ActivityManagerService.java revision b7289330e1ae201691dc5b2aa2b6b3a65795e4cb
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.google.android.collect.Lists;
20import com.google.android.collect.Maps;
21import com.android.internal.R;
22import com.android.internal.annotations.GuardedBy;
23import com.android.internal.app.AssistUtils;
24import com.android.internal.app.DumpHeapActivity;
25import com.android.internal.app.IAppOpsCallback;
26import com.android.internal.app.IAppOpsService;
27import com.android.internal.app.IVoiceInteractor;
28import com.android.internal.app.ProcessMap;
29import com.android.internal.app.ProcessStats;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.os.BackgroundThread;
32import com.android.internal.os.BatteryStatsImpl;
33import com.android.internal.os.IResultReceiver;
34import com.android.internal.os.ProcessCpuTracker;
35import com.android.internal.os.TransferPipe;
36import com.android.internal.os.Zygote;
37import com.android.internal.os.InstallerConnection.InstallerException;
38import com.android.internal.util.ArrayUtils;
39import com.android.internal.util.FastPrintWriter;
40import com.android.internal.util.FastXmlSerializer;
41import com.android.internal.util.MemInfoReader;
42import com.android.internal.util.Preconditions;
43import com.android.server.AppOpsService;
44import com.android.server.AttributeCache;
45import com.android.server.DeviceIdleController;
46import com.android.server.IntentResolver;
47import com.android.server.LocalServices;
48import com.android.server.ServiceThread;
49import com.android.server.SystemService;
50import com.android.server.SystemServiceManager;
51import com.android.server.Watchdog;
52import com.android.server.am.ActivityStack.ActivityState;
53import com.android.server.firewall.IntentFirewall;
54import com.android.server.pm.Installer;
55import com.android.server.statusbar.StatusBarManagerInternal;
56import com.android.server.vr.VrManagerInternal;
57import com.android.server.wm.AppTransition;
58import com.android.server.wm.WindowManagerService;
59
60import org.xmlpull.v1.XmlPullParser;
61import org.xmlpull.v1.XmlPullParserException;
62import org.xmlpull.v1.XmlSerializer;
63
64import android.Manifest;
65import android.app.Activity;
66import android.app.ActivityManager;
67import android.app.ActivityManager.RunningTaskInfo;
68import android.app.ActivityManager.StackId;
69import android.app.ActivityManager.StackInfo;
70import android.app.ActivityManager.TaskThumbnailInfo;
71import android.app.ActivityManagerInternal;
72import android.app.ActivityManagerInternal.SleepToken;
73import android.app.ActivityManagerNative;
74import android.app.ActivityOptions;
75import android.app.ActivityThread;
76import android.app.AlertDialog;
77import android.app.AppGlobals;
78import android.app.AppOpsManager;
79import android.app.ApplicationErrorReport;
80import android.app.ApplicationThreadNative;
81import android.app.BroadcastOptions;
82import android.app.Dialog;
83import android.app.IActivityContainer;
84import android.app.IActivityContainerCallback;
85import android.app.IActivityController;
86import android.app.IAppTask;
87import android.app.IApplicationThread;
88import android.app.IInstrumentationWatcher;
89import android.app.INotificationManager;
90import android.app.IProcessObserver;
91import android.app.IServiceConnection;
92import android.app.IStopUserCallback;
93import android.app.ITaskStackListener;
94import android.app.IUiAutomationConnection;
95import android.app.IUidObserver;
96import android.app.IUserSwitchObserver;
97import android.app.Instrumentation;
98import android.app.Notification;
99import android.app.NotificationManager;
100import android.app.PendingIntent;
101import android.app.ProfilerInfo;
102import android.app.admin.DevicePolicyManager;
103import android.app.assist.AssistContent;
104import android.app.assist.AssistStructure;
105import android.app.backup.IBackupManager;
106import android.app.usage.UsageEvents;
107import android.app.usage.UsageStatsManagerInternal;
108import android.appwidget.AppWidgetManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.PackageManager.NameNotFoundException;
133import android.content.pm.PackageManagerInternal;
134import android.content.pm.ParceledListSlice;
135import android.content.pm.PathPermission;
136import android.content.pm.PermissionInfo;
137import android.content.pm.ProviderInfo;
138import android.content.pm.ResolveInfo;
139import android.content.pm.ServiceInfo;
140import android.content.pm.UserInfo;
141import android.content.res.CompatibilityInfo;
142import android.content.res.Configuration;
143import android.content.res.Resources;
144import android.database.ContentObserver;
145import android.graphics.Bitmap;
146import android.graphics.Point;
147import android.graphics.Rect;
148import android.location.LocationManager;
149import android.net.Proxy;
150import android.net.ProxyInfo;
151import android.net.Uri;
152import android.os.BatteryStats;
153import android.os.Binder;
154import android.os.Build;
155import android.os.Bundle;
156import android.os.Debug;
157import android.os.DropBoxManager;
158import android.os.Environment;
159import android.os.FactoryTest;
160import android.os.FileObserver;
161import android.os.FileUtils;
162import android.os.Handler;
163import android.os.IBinder;
164import android.os.IPermissionController;
165import android.os.IProcessInfoService;
166import android.os.Looper;
167import android.os.Message;
168import android.os.Parcel;
169import android.os.ParcelFileDescriptor;
170import android.os.PersistableBundle;
171import android.os.PowerManager;
172import android.os.PowerManagerInternal;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.ResultReceiver;
177import android.os.ServiceManager;
178import android.os.StrictMode;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.Trace;
182import android.os.TransactionTooLargeException;
183import android.os.UpdateLock;
184import android.os.UserHandle;
185import android.os.UserManager;
186import android.os.WorkSource;
187import android.os.storage.IMountService;
188import android.os.storage.MountServiceInternal;
189import android.os.storage.StorageManager;
190import android.provider.Settings;
191import android.service.voice.IVoiceInteractionSession;
192import android.service.voice.VoiceInteractionManagerInternal;
193import android.service.voice.VoiceInteractionSession;
194import android.text.format.DateUtils;
195import android.text.format.Time;
196import android.util.ArrayMap;
197import android.util.ArraySet;
198import android.util.AtomicFile;
199import android.util.DebugUtils;
200import android.util.EventLog;
201import android.util.LocaleList;
202import android.util.Log;
203import android.util.Pair;
204import android.util.PrintWriterPrinter;
205import android.util.Slog;
206import android.util.SparseArray;
207import android.util.TimeUtils;
208import android.util.Xml;
209import android.view.Display;
210import android.view.Gravity;
211import android.view.LayoutInflater;
212import android.view.View;
213import android.view.WindowManager;
214
215import java.io.BufferedInputStream;
216import java.io.BufferedOutputStream;
217import java.io.DataInputStream;
218import java.io.DataOutputStream;
219import java.io.File;
220import java.io.FileDescriptor;
221import java.io.FileInputStream;
222import java.io.FileNotFoundException;
223import java.io.FileOutputStream;
224import java.io.IOException;
225import java.io.InputStreamReader;
226import java.io.PrintWriter;
227import java.io.StringWriter;
228import java.lang.ref.WeakReference;
229import java.nio.charset.StandardCharsets;
230import java.util.ArrayList;
231import java.util.Arrays;
232import java.util.Collections;
233import java.util.Comparator;
234import java.util.HashMap;
235import java.util.HashSet;
236import java.util.Iterator;
237import java.util.List;
238import java.util.Locale;
239import java.util.Map;
240import java.util.Set;
241import java.util.concurrent.atomic.AtomicBoolean;
242import java.util.concurrent.atomic.AtomicLong;
243
244import dalvik.system.VMRuntime;
245
246import libcore.io.IoUtils;
247import libcore.util.EmptyArray;
248
249import static android.Manifest.permission.INTERACT_ACROSS_USERS;
250import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
251import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
252import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
253import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
254import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
255import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
256import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
257import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
258import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
259import static android.app.ActivityManager.StackId.HOME_STACK_ID;
260import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
261import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
262import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
263import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
264import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
265import static android.content.pm.PackageManager.GET_PROVIDERS;
266import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
267import static android.content.pm.PackageManager.MATCH_ENCRYPTION_UNAWARE;
268import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
269import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
270import static android.content.pm.PackageManager.PERMISSION_GRANTED;
271import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
272import static android.provider.Settings.Global.DEBUG_APP;
273import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
274import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
275import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
276import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
277import static android.provider.Settings.System.FONT_SCALE;
278import static com.android.internal.util.XmlUtils.readBooleanAttribute;
279import static com.android.internal.util.XmlUtils.readIntAttribute;
280import static com.android.internal.util.XmlUtils.readLongAttribute;
281import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
282import static com.android.internal.util.XmlUtils.writeIntAttribute;
283import static com.android.internal.util.XmlUtils.writeLongAttribute;
284import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
285import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
315import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
316import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
317import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
339import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
340import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
341import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
342import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
343import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
344import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
345import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
346import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
347import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
348import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
349import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
350import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
351import static org.xmlpull.v1.XmlPullParser.START_TAG;
352
353public final class ActivityManagerService extends ActivityManagerNative
354        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
355
356    // File that stores last updated system version and called preboot receivers
357    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
358
359    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
360    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
361    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
362    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
363    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
364    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
365    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
366    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
367    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
368    private static final String TAG_LRU = TAG + POSTFIX_LRU;
369    private static final String TAG_MU = TAG + POSTFIX_MU;
370    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
371    private static final String TAG_POWER = TAG + POSTFIX_POWER;
372    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
373    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
374    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
375    private static final String TAG_PSS = TAG + POSTFIX_PSS;
376    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
377    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
378    private static final String TAG_STACK = TAG + POSTFIX_STACK;
379    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
380    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
381    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
382    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
383    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
384
385    /** Control over CPU and battery monitoring */
386    // write battery stats every 30 minutes.
387    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
388    static final boolean MONITOR_CPU_USAGE = true;
389    // don't sample cpu less than every 5 seconds.
390    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
391    // wait possibly forever for next cpu sample.
392    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
393    static final boolean MONITOR_THREAD_CPU_USAGE = false;
394
395    // The flags that are set for all calls we make to the package manager.
396    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
397
398    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
399
400    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
401
402    // Amount of time after a call to stopAppSwitches() during which we will
403    // prevent further untrusted switches from happening.
404    static final long APP_SWITCH_DELAY_TIME = 5*1000;
405
406    // How long we wait for a launched process to attach to the activity manager
407    // before we decide it's never going to come up for real.
408    static final int PROC_START_TIMEOUT = 10*1000;
409    // How long we wait for an attached process to publish its content providers
410    // before we decide it must be hung.
411    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
412
413    // How long we will retain processes hosting content providers in the "last activity"
414    // state before allowing them to drop down to the regular cached LRU list.  This is
415    // to avoid thrashing of provider processes under low memory situations.
416    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
417
418    // How long we wait for a launched process to attach to the activity manager
419    // before we decide it's never going to come up for real, when the process was
420    // started with a wrapper for instrumentation (such as Valgrind) because it
421    // could take much longer than usual.
422    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
423
424    // How long to wait after going idle before forcing apps to GC.
425    static final int GC_TIMEOUT = 5*1000;
426
427    // The minimum amount of time between successive GC requests for a process.
428    static final int GC_MIN_INTERVAL = 60*1000;
429
430    // The minimum amount of time between successive PSS requests for a process.
431    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
432
433    // The minimum amount of time between successive PSS requests for a process
434    // when the request is due to the memory state being lowered.
435    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
436
437    // The rate at which we check for apps using excessive power -- 15 mins.
438    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
439
440    // The minimum sample duration we will allow before deciding we have
441    // enough data on wake locks to start killing things.
442    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
443
444    // The minimum sample duration we will allow before deciding we have
445    // enough data on CPU usage to start killing things.
446    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
447
448    // How long we allow a receiver to run before giving up on it.
449    static final int BROADCAST_FG_TIMEOUT = 10*1000;
450    static final int BROADCAST_BG_TIMEOUT = 60*1000;
451
452    // How long we wait until we timeout on key dispatching.
453    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
454
455    // How long we wait until we timeout on key dispatching during instrumentation.
456    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
457
458    // This is the amount of time an app needs to be running a foreground service before
459    // we will consider it to be doing interaction for usage stats.
460    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
461
462    // Maximum amount of time we will allow to elapse before re-reporting usage stats
463    // interaction with foreground processes.
464    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
465
466    // This is the amount of time we allow an app to settle after it goes into the background,
467    // before we start restricting what it can do.
468    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
469
470    // How long to wait in getAssistContextExtras for the activity and foreground services
471    // to respond with the result.
472    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
473
474    // How long top wait when going through the modern assist (which doesn't need to block
475    // on getting this result before starting to launch its UI).
476    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
477
478    // Maximum number of persisted Uri grants a package is allowed
479    static final int MAX_PERSISTED_URI_GRANTS = 128;
480
481    static final int MY_PID = Process.myPid();
482
483    static final String[] EMPTY_STRING_ARRAY = new String[0];
484
485    // How many bytes to write into the dropbox log before truncating
486    static final int DROPBOX_MAX_SIZE = 256 * 1024;
487
488    // Access modes for handleIncomingUser.
489    static final int ALLOW_NON_FULL = 0;
490    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
491    static final int ALLOW_FULL_ONLY = 2;
492
493    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
494
495    // Delay in notifying task stack change listeners (in millis)
496    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
497
498    // Necessary ApplicationInfo flags to mark an app as persistent
499    private static final int PERSISTENT_MASK =
500            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
501
502
503    // Delay to disable app launch boost
504    static final int APP_BOOST_MESSAGE_DELAY = 3000;
505    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
506    static final int APP_BOOST_TIMEOUT = 2500;
507
508    // Used to indicate that a task is removed it should also be removed from recents.
509    private static final boolean REMOVE_FROM_RECENTS = true;
510    // Used to indicate that an app transition should be animated.
511    static final boolean ANIMATE = true;
512
513    // Determines whether to take full screen screenshots
514    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
515
516    private static native int nativeMigrateToBoost();
517    private static native int nativeMigrateFromBoost();
518    private boolean mIsBoosted = false;
519    private long mBoostStartTime = 0;
520
521    /** All system services */
522    SystemServiceManager mSystemServiceManager;
523
524    private Installer mInstaller;
525
526    /** Run all ActivityStacks through this */
527    final ActivityStackSupervisor mStackSupervisor;
528
529    final ActivityStarter mActivityStarter;
530
531    /** Task stack change listeners. */
532    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
533            new RemoteCallbackList<ITaskStackListener>();
534
535    public IntentFirewall mIntentFirewall;
536
537    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
538    // default actuion automatically.  Important for devices without direct input
539    // devices.
540    private boolean mShowDialogs = true;
541    private boolean mInVrMode = false;
542
543    BroadcastQueue mFgBroadcastQueue;
544    BroadcastQueue mBgBroadcastQueue;
545    // Convenient for easy iteration over the queues. Foreground is first
546    // so that dispatch of foreground broadcasts gets precedence.
547    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
548
549    BroadcastQueue broadcastQueueForIntent(Intent intent) {
550        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
551        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
552                "Broadcast intent " + intent + " on "
553                + (isFg ? "foreground" : "background") + " queue");
554        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
555    }
556
557    /**
558     * Activity we have told the window manager to have key focus.
559     */
560    ActivityRecord mFocusedActivity = null;
561
562    /**
563     * User id of the last activity mFocusedActivity was set to.
564     */
565    private int mLastFocusedUserId;
566
567    /**
568     * If non-null, we are tracking the time the user spends in the currently focused app.
569     */
570    private AppTimeTracker mCurAppTimeTracker;
571
572    /**
573     * List of intents that were used to start the most recent tasks.
574     */
575    final RecentTasks mRecentTasks;
576
577    /**
578     * For addAppTask: cached of the last activity component that was added.
579     */
580    ComponentName mLastAddedTaskComponent;
581
582    /**
583     * For addAppTask: cached of the last activity uid that was added.
584     */
585    int mLastAddedTaskUid;
586
587    /**
588     * For addAppTask: cached of the last ActivityInfo that was added.
589     */
590    ActivityInfo mLastAddedTaskActivity;
591
592    /**
593     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
594     */
595    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
596
597    /**
598     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
599     */
600    String mDeviceOwnerName;
601
602    final UserController mUserController;
603
604    final AppErrors mAppErrors;
605
606    boolean mDoingSetFocusedActivity;
607
608    public boolean canShowErrorDialogs() {
609        return mShowDialogs && !mSleeping && !mShuttingDown;
610    }
611
612    public class PendingAssistExtras extends Binder implements Runnable {
613        public final ActivityRecord activity;
614        public final Bundle extras;
615        public final Intent intent;
616        public final String hint;
617        public final IResultReceiver receiver;
618        public final int userHandle;
619        public boolean haveResult = false;
620        public Bundle result = null;
621        public AssistStructure structure = null;
622        public AssistContent content = null;
623        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
624                String _hint, IResultReceiver _receiver, int _userHandle) {
625            activity = _activity;
626            extras = _extras;
627            intent = _intent;
628            hint = _hint;
629            receiver = _receiver;
630            userHandle = _userHandle;
631        }
632        @Override
633        public void run() {
634            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
635            synchronized (this) {
636                haveResult = true;
637                notifyAll();
638            }
639            pendingAssistExtrasTimedOut(this);
640        }
641    }
642
643    final ArrayList<PendingAssistExtras> mPendingAssistExtras
644            = new ArrayList<PendingAssistExtras>();
645
646    /**
647     * Process management.
648     */
649    final ProcessList mProcessList = new ProcessList();
650
651    /**
652     * All of the applications we currently have running organized by name.
653     * The keys are strings of the application package name (as
654     * returned by the package manager), and the keys are ApplicationRecord
655     * objects.
656     */
657    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
658
659    /**
660     * Tracking long-term execution of processes to look for abuse and other
661     * bad app behavior.
662     */
663    final ProcessStatsService mProcessStats;
664
665    /**
666     * The currently running isolated processes.
667     */
668    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
669
670    /**
671     * Counter for assigning isolated process uids, to avoid frequently reusing the
672     * same ones.
673     */
674    int mNextIsolatedProcessUid = 0;
675
676    /**
677     * The currently running heavy-weight process, if any.
678     */
679    ProcessRecord mHeavyWeightProcess = null;
680
681    /**
682     * All of the processes we currently have running organized by pid.
683     * The keys are the pid running the application.
684     *
685     * <p>NOTE: This object is protected by its own lock, NOT the global
686     * activity manager lock!
687     */
688    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
689
690    /**
691     * All of the processes that have been forced to be foreground.  The key
692     * is the pid of the caller who requested it (we hold a death
693     * link on it).
694     */
695    abstract class ForegroundToken implements IBinder.DeathRecipient {
696        int pid;
697        IBinder token;
698    }
699    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
700
701    /**
702     * List of records for processes that someone had tried to start before the
703     * system was ready.  We don't start them at that point, but ensure they
704     * are started by the time booting is complete.
705     */
706    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
707
708    /**
709     * List of persistent applications that are in the process
710     * of being started.
711     */
712    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
713
714    /**
715     * Processes that are being forcibly torn down.
716     */
717    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
718
719    /**
720     * List of running applications, sorted by recent usage.
721     * The first entry in the list is the least recently used.
722     */
723    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
724
725    /**
726     * Where in mLruProcesses that the processes hosting activities start.
727     */
728    int mLruProcessActivityStart = 0;
729
730    /**
731     * Where in mLruProcesses that the processes hosting services start.
732     * This is after (lower index) than mLruProcessesActivityStart.
733     */
734    int mLruProcessServiceStart = 0;
735
736    /**
737     * List of processes that should gc as soon as things are idle.
738     */
739    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
740
741    /**
742     * Processes we want to collect PSS data from.
743     */
744    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
745
746    private boolean mBinderTransactionTrackingEnabled = false;
747
748    /**
749     * Last time we requested PSS data of all processes.
750     */
751    long mLastFullPssTime = SystemClock.uptimeMillis();
752
753    /**
754     * If set, the next time we collect PSS data we should do a full collection
755     * with data from native processes and the kernel.
756     */
757    boolean mFullPssPending = false;
758
759    /**
760     * This is the process holding what we currently consider to be
761     * the "home" activity.
762     */
763    ProcessRecord mHomeProcess;
764
765    /**
766     * This is the process holding the activity the user last visited that
767     * is in a different process from the one they are currently in.
768     */
769    ProcessRecord mPreviousProcess;
770
771    /**
772     * The time at which the previous process was last visible.
773     */
774    long mPreviousProcessVisibleTime;
775
776    /**
777     * Track all uids that have actively running processes.
778     */
779    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
780
781    /**
782     * This is for verifying the UID report flow.
783     */
784    static final boolean VALIDATE_UID_STATES = true;
785    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
786
787    /**
788     * Packages that the user has asked to have run in screen size
789     * compatibility mode instead of filling the screen.
790     */
791    final CompatModePackages mCompatModePackages;
792
793    /**
794     * Set of IntentSenderRecord objects that are currently active.
795     */
796    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
797            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
798
799    /**
800     * Fingerprints (hashCode()) of stack traces that we've
801     * already logged DropBox entries for.  Guarded by itself.  If
802     * something (rogue user app) forces this over
803     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
804     */
805    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
806    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
807
808    /**
809     * Strict Mode background batched logging state.
810     *
811     * The string buffer is guarded by itself, and its lock is also
812     * used to determine if another batched write is already
813     * in-flight.
814     */
815    private final StringBuilder mStrictModeBuffer = new StringBuilder();
816
817    /**
818     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
819     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
820     */
821    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
822
823    /**
824     * Resolver for broadcast intents to registered receivers.
825     * Holds BroadcastFilter (subclass of IntentFilter).
826     */
827    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
828            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
829        @Override
830        protected boolean allowFilterResult(
831                BroadcastFilter filter, List<BroadcastFilter> dest) {
832            IBinder target = filter.receiverList.receiver.asBinder();
833            for (int i = dest.size() - 1; i >= 0; i--) {
834                if (dest.get(i).receiverList.receiver.asBinder() == target) {
835                    return false;
836                }
837            }
838            return true;
839        }
840
841        @Override
842        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
843            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
844                    || userId == filter.owningUserId) {
845                return super.newResult(filter, match, userId);
846            }
847            return null;
848        }
849
850        @Override
851        protected BroadcastFilter[] newArray(int size) {
852            return new BroadcastFilter[size];
853        }
854
855        @Override
856        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
857            return packageName.equals(filter.packageName);
858        }
859    };
860
861    /**
862     * State of all active sticky broadcasts per user.  Keys are the action of the
863     * sticky Intent, values are an ArrayList of all broadcasted intents with
864     * that action (which should usually be one).  The SparseArray is keyed
865     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
866     * for stickies that are sent to all users.
867     */
868    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
869            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
870
871    final ActiveServices mServices;
872
873    final static class Association {
874        final int mSourceUid;
875        final String mSourceProcess;
876        final int mTargetUid;
877        final ComponentName mTargetComponent;
878        final String mTargetProcess;
879
880        int mCount;
881        long mTime;
882
883        int mNesting;
884        long mStartTime;
885
886        Association(int sourceUid, String sourceProcess, int targetUid,
887                ComponentName targetComponent, String targetProcess) {
888            mSourceUid = sourceUid;
889            mSourceProcess = sourceProcess;
890            mTargetUid = targetUid;
891            mTargetComponent = targetComponent;
892            mTargetProcess = targetProcess;
893        }
894    }
895
896    /**
897     * When service association tracking is enabled, this is all of the associations we
898     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
899     * -> association data.
900     */
901    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
902            mAssociations = new SparseArray<>();
903    boolean mTrackingAssociations;
904
905    /**
906     * Backup/restore process management
907     */
908    String mBackupAppName = null;
909    BackupRecord mBackupTarget = null;
910
911    final ProviderMap mProviderMap;
912
913    /**
914     * List of content providers who have clients waiting for them.  The
915     * application is currently being launched and the provider will be
916     * removed from this list once it is published.
917     */
918    final ArrayList<ContentProviderRecord> mLaunchingProviders
919            = new ArrayList<ContentProviderRecord>();
920
921    /**
922     * File storing persisted {@link #mGrantedUriPermissions}.
923     */
924    private final AtomicFile mGrantFile;
925
926    /** XML constants used in {@link #mGrantFile} */
927    private static final String TAG_URI_GRANTS = "uri-grants";
928    private static final String TAG_URI_GRANT = "uri-grant";
929    private static final String ATTR_USER_HANDLE = "userHandle";
930    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
931    private static final String ATTR_TARGET_USER_ID = "targetUserId";
932    private static final String ATTR_SOURCE_PKG = "sourcePkg";
933    private static final String ATTR_TARGET_PKG = "targetPkg";
934    private static final String ATTR_URI = "uri";
935    private static final String ATTR_MODE_FLAGS = "modeFlags";
936    private static final String ATTR_CREATED_TIME = "createdTime";
937    private static final String ATTR_PREFIX = "prefix";
938
939    /**
940     * Global set of specific {@link Uri} permissions that have been granted.
941     * This optimized lookup structure maps from {@link UriPermission#targetUid}
942     * to {@link UriPermission#uri} to {@link UriPermission}.
943     */
944    @GuardedBy("this")
945    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
946            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
947
948    public static class GrantUri {
949        public final int sourceUserId;
950        public final Uri uri;
951        public boolean prefix;
952
953        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
954            this.sourceUserId = sourceUserId;
955            this.uri = uri;
956            this.prefix = prefix;
957        }
958
959        @Override
960        public int hashCode() {
961            int hashCode = 1;
962            hashCode = 31 * hashCode + sourceUserId;
963            hashCode = 31 * hashCode + uri.hashCode();
964            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
965            return hashCode;
966        }
967
968        @Override
969        public boolean equals(Object o) {
970            if (o instanceof GrantUri) {
971                GrantUri other = (GrantUri) o;
972                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
973                        && prefix == other.prefix;
974            }
975            return false;
976        }
977
978        @Override
979        public String toString() {
980            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
981            if (prefix) result += " [prefix]";
982            return result;
983        }
984
985        public String toSafeString() {
986            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
987            if (prefix) result += " [prefix]";
988            return result;
989        }
990
991        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
992            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
993                    ContentProvider.getUriWithoutUserId(uri), false);
994        }
995    }
996
997    CoreSettingsObserver mCoreSettingsObserver;
998
999    FontScaleSettingObserver mFontScaleSettingObserver;
1000
1001    private final class FontScaleSettingObserver extends ContentObserver {
1002        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1003
1004        public FontScaleSettingObserver() {
1005            super(mHandler);
1006            ContentResolver resolver = mContext.getContentResolver();
1007            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1008        }
1009
1010        @Override
1011        public void onChange(boolean selfChange, Uri uri) {
1012            if (mFontScaleUri.equals(uri)) {
1013                updateFontScaleIfNeeded();
1014            }
1015        }
1016    }
1017
1018    /**
1019     * Thread-local storage used to carry caller permissions over through
1020     * indirect content-provider access.
1021     */
1022    private class Identity {
1023        public final IBinder token;
1024        public final int pid;
1025        public final int uid;
1026
1027        Identity(IBinder _token, int _pid, int _uid) {
1028            token = _token;
1029            pid = _pid;
1030            uid = _uid;
1031        }
1032    }
1033
1034    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1035
1036    /**
1037     * All information we have collected about the runtime performance of
1038     * any user id that can impact battery performance.
1039     */
1040    final BatteryStatsService mBatteryStatsService;
1041
1042    /**
1043     * Information about component usage
1044     */
1045    UsageStatsManagerInternal mUsageStatsService;
1046
1047    /**
1048     * Access to DeviceIdleController service.
1049     */
1050    DeviceIdleController.LocalService mLocalDeviceIdleController;
1051
1052    /**
1053     * Information about and control over application operations
1054     */
1055    final AppOpsService mAppOpsService;
1056
1057    /**
1058     * Current configuration information.  HistoryRecord objects are given
1059     * a reference to this object to indicate which configuration they are
1060     * currently running in, so this object must be kept immutable.
1061     */
1062    Configuration mConfiguration = new Configuration();
1063
1064    /**
1065     * Current sequencing integer of the configuration, for skipping old
1066     * configurations.
1067     */
1068    int mConfigurationSeq = 0;
1069
1070    boolean mSuppressResizeConfigChanges = false;
1071
1072    /**
1073     * Hardware-reported OpenGLES version.
1074     */
1075    final int GL_ES_VERSION;
1076
1077    /**
1078     * List of initialization arguments to pass to all processes when binding applications to them.
1079     * For example, references to the commonly used services.
1080     */
1081    HashMap<String, IBinder> mAppBindArgs;
1082
1083    /**
1084     * Temporary to avoid allocations.  Protected by main lock.
1085     */
1086    final StringBuilder mStringBuilder = new StringBuilder(256);
1087
1088    /**
1089     * Used to control how we initialize the service.
1090     */
1091    ComponentName mTopComponent;
1092    String mTopAction = Intent.ACTION_MAIN;
1093    String mTopData;
1094    boolean mProcessesReady = false;
1095    boolean mSystemReady = false;
1096    boolean mBooting = false;
1097    boolean mCallFinishBooting = false;
1098    boolean mBootAnimationComplete = false;
1099    boolean mWaitingUpdate = false;
1100    boolean mDidUpdate = false;
1101    boolean mOnBattery = false;
1102    boolean mLaunchWarningShown = false;
1103
1104    Context mContext;
1105
1106    int mFactoryTest;
1107
1108    boolean mCheckedForSetup;
1109
1110    /**
1111     * The time at which we will allow normal application switches again,
1112     * after a call to {@link #stopAppSwitches()}.
1113     */
1114    long mAppSwitchesAllowedTime;
1115
1116    /**
1117     * This is set to true after the first switch after mAppSwitchesAllowedTime
1118     * is set; any switches after that will clear the time.
1119     */
1120    boolean mDidAppSwitch;
1121
1122    /**
1123     * Last time (in realtime) at which we checked for power usage.
1124     */
1125    long mLastPowerCheckRealtime;
1126
1127    /**
1128     * Last time (in uptime) at which we checked for power usage.
1129     */
1130    long mLastPowerCheckUptime;
1131
1132    /**
1133     * Set while we are wanting to sleep, to prevent any
1134     * activities from being started/resumed.
1135     */
1136    private boolean mSleeping = false;
1137
1138    /**
1139     * The process state used for processes that are running the top activities.
1140     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1141     */
1142    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1143
1144    /**
1145     * Set while we are running a voice interaction.  This overrides
1146     * sleeping while it is active.
1147     */
1148    private IVoiceInteractionSession mRunningVoice;
1149
1150    /**
1151     * For some direct access we need to power manager.
1152     */
1153    PowerManagerInternal mLocalPowerManager;
1154
1155    /**
1156     * We want to hold a wake lock while running a voice interaction session, since
1157     * this may happen with the screen off and we need to keep the CPU running to
1158     * be able to continue to interact with the user.
1159     */
1160    PowerManager.WakeLock mVoiceWakeLock;
1161
1162    /**
1163     * State of external calls telling us if the device is awake or asleep.
1164     */
1165    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1166
1167    /**
1168     * A list of tokens that cause the top activity to be put to sleep.
1169     * They are used by components that may hide and block interaction with underlying
1170     * activities.
1171     */
1172    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1173
1174    static final int LOCK_SCREEN_HIDDEN = 0;
1175    static final int LOCK_SCREEN_LEAVING = 1;
1176    static final int LOCK_SCREEN_SHOWN = 2;
1177    /**
1178     * State of external call telling us if the lock screen is shown.
1179     */
1180    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1181
1182    /**
1183     * Set if we are shutting down the system, similar to sleeping.
1184     */
1185    boolean mShuttingDown = false;
1186
1187    /**
1188     * Current sequence id for oom_adj computation traversal.
1189     */
1190    int mAdjSeq = 0;
1191
1192    /**
1193     * Current sequence id for process LRU updating.
1194     */
1195    int mLruSeq = 0;
1196
1197    /**
1198     * Keep track of the non-cached/empty process we last found, to help
1199     * determine how to distribute cached/empty processes next time.
1200     */
1201    int mNumNonCachedProcs = 0;
1202
1203    /**
1204     * Keep track of the number of cached hidden procs, to balance oom adj
1205     * distribution between those and empty procs.
1206     */
1207    int mNumCachedHiddenProcs = 0;
1208
1209    /**
1210     * Keep track of the number of service processes we last found, to
1211     * determine on the next iteration which should be B services.
1212     */
1213    int mNumServiceProcs = 0;
1214    int mNewNumAServiceProcs = 0;
1215    int mNewNumServiceProcs = 0;
1216
1217    /**
1218     * Allow the current computed overall memory level of the system to go down?
1219     * This is set to false when we are killing processes for reasons other than
1220     * memory management, so that the now smaller process list will not be taken as
1221     * an indication that memory is tighter.
1222     */
1223    boolean mAllowLowerMemLevel = false;
1224
1225    /**
1226     * The last computed memory level, for holding when we are in a state that
1227     * processes are going away for other reasons.
1228     */
1229    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1230
1231    /**
1232     * The last total number of process we have, to determine if changes actually look
1233     * like a shrinking number of process due to lower RAM.
1234     */
1235    int mLastNumProcesses;
1236
1237    /**
1238     * The uptime of the last time we performed idle maintenance.
1239     */
1240    long mLastIdleTime = SystemClock.uptimeMillis();
1241
1242    /**
1243     * Total time spent with RAM that has been added in the past since the last idle time.
1244     */
1245    long mLowRamTimeSinceLastIdle = 0;
1246
1247    /**
1248     * If RAM is currently low, when that horrible situation started.
1249     */
1250    long mLowRamStartTime = 0;
1251
1252    /**
1253     * For reporting to battery stats the current top application.
1254     */
1255    private String mCurResumedPackage = null;
1256    private int mCurResumedUid = -1;
1257
1258    /**
1259     * For reporting to battery stats the apps currently running foreground
1260     * service.  The ProcessMap is package/uid tuples; each of these contain
1261     * an array of the currently foreground processes.
1262     */
1263    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1264            = new ProcessMap<ArrayList<ProcessRecord>>();
1265
1266    /**
1267     * This is set if we had to do a delayed dexopt of an app before launching
1268     * it, to increase the ANR timeouts in that case.
1269     */
1270    boolean mDidDexOpt;
1271
1272    /**
1273     * Set if the systemServer made a call to enterSafeMode.
1274     */
1275    boolean mSafeMode;
1276
1277    /**
1278     * If true, we are running under a test environment so will sample PSS from processes
1279     * much more rapidly to try to collect better data when the tests are rapidly
1280     * running through apps.
1281     */
1282    boolean mTestPssMode = false;
1283
1284    String mDebugApp = null;
1285    boolean mWaitForDebugger = false;
1286    boolean mDebugTransient = false;
1287    String mOrigDebugApp = null;
1288    boolean mOrigWaitForDebugger = false;
1289    boolean mAlwaysFinishActivities = false;
1290    boolean mForceResizableActivities;
1291    boolean mSupportsFreeformWindowManagement;
1292    boolean mSupportsPictureInPicture;
1293    Rect mDefaultPinnedStackBounds;
1294    IActivityController mController = null;
1295    String mProfileApp = null;
1296    ProcessRecord mProfileProc = null;
1297    String mProfileFile;
1298    ParcelFileDescriptor mProfileFd;
1299    int mSamplingInterval = 0;
1300    boolean mAutoStopProfiler = false;
1301    int mProfileType = 0;
1302    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1303    String mMemWatchDumpProcName;
1304    String mMemWatchDumpFile;
1305    int mMemWatchDumpPid;
1306    int mMemWatchDumpUid;
1307    String mTrackAllocationApp = null;
1308    String mNativeDebuggingApp = null;
1309
1310    final long[] mTmpLong = new long[2];
1311
1312    static final class ProcessChangeItem {
1313        static final int CHANGE_ACTIVITIES = 1<<0;
1314        static final int CHANGE_PROCESS_STATE = 1<<1;
1315        int changes;
1316        int uid;
1317        int pid;
1318        int processState;
1319        boolean foregroundActivities;
1320    }
1321
1322    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1323    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1324
1325    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1326    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1327
1328    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1329    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1330
1331    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1332    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1333
1334    /**
1335     * Runtime CPU use collection thread.  This object's lock is used to
1336     * perform synchronization with the thread (notifying it to run).
1337     */
1338    final Thread mProcessCpuThread;
1339
1340    /**
1341     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1342     * Must acquire this object's lock when accessing it.
1343     * NOTE: this lock will be held while doing long operations (trawling
1344     * through all processes in /proc), so it should never be acquired by
1345     * any critical paths such as when holding the main activity manager lock.
1346     */
1347    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1348            MONITOR_THREAD_CPU_USAGE);
1349    final AtomicLong mLastCpuTime = new AtomicLong(0);
1350    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1351
1352    long mLastWriteTime = 0;
1353
1354    /**
1355     * Used to retain an update lock when the foreground activity is in
1356     * immersive mode.
1357     */
1358    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1359
1360    /**
1361     * Set to true after the system has finished booting.
1362     */
1363    boolean mBooted = false;
1364
1365    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1366    int mProcessLimitOverride = -1;
1367
1368    WindowManagerService mWindowManager;
1369
1370    final ActivityThread mSystemThread;
1371
1372    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1373        final ProcessRecord mApp;
1374        final int mPid;
1375        final IApplicationThread mAppThread;
1376
1377        AppDeathRecipient(ProcessRecord app, int pid,
1378                IApplicationThread thread) {
1379            if (DEBUG_ALL) Slog.v(
1380                TAG, "New death recipient " + this
1381                + " for thread " + thread.asBinder());
1382            mApp = app;
1383            mPid = pid;
1384            mAppThread = thread;
1385        }
1386
1387        @Override
1388        public void binderDied() {
1389            if (DEBUG_ALL) Slog.v(
1390                TAG, "Death received in " + this
1391                + " for thread " + mAppThread.asBinder());
1392            synchronized(ActivityManagerService.this) {
1393                appDiedLocked(mApp, mPid, mAppThread, true);
1394            }
1395        }
1396    }
1397
1398    static final int SHOW_ERROR_UI_MSG = 1;
1399    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1400    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1401    static final int UPDATE_CONFIGURATION_MSG = 4;
1402    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1403    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1404    static final int SERVICE_TIMEOUT_MSG = 12;
1405    static final int UPDATE_TIME_ZONE = 13;
1406    static final int SHOW_UID_ERROR_UI_MSG = 14;
1407    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1408    static final int PROC_START_TIMEOUT_MSG = 20;
1409    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1410    static final int KILL_APPLICATION_MSG = 22;
1411    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1412    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1413    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1414    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1415    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1416    static final int CLEAR_DNS_CACHE_MSG = 28;
1417    static final int UPDATE_HTTP_PROXY_MSG = 29;
1418    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1419    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1420    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1421    static final int REPORT_MEM_USAGE_MSG = 33;
1422    static final int REPORT_USER_SWITCH_MSG = 34;
1423    static final int CONTINUE_USER_SWITCH_MSG = 35;
1424    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1425    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1426    static final int PERSIST_URI_GRANTS_MSG = 38;
1427    static final int REQUEST_ALL_PSS_MSG = 39;
1428    static final int START_PROFILES_MSG = 40;
1429    static final int UPDATE_TIME = 41;
1430    static final int SYSTEM_USER_START_MSG = 42;
1431    static final int SYSTEM_USER_CURRENT_MSG = 43;
1432    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1433    static final int FINISH_BOOTING_MSG = 45;
1434    static final int START_USER_SWITCH_UI_MSG = 46;
1435    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1436    static final int DISMISS_DIALOG_UI_MSG = 48;
1437    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1438    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1439    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1440    static final int DELETE_DUMPHEAP_MSG = 52;
1441    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1442    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1443    static final int REPORT_TIME_TRACKER_MSG = 55;
1444    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1445    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1446    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1447    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1448    static final int IDLE_UIDS_MSG = 60;
1449    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1450    static final int LOG_STACK_STATE = 62;
1451    static final int VR_MODE_CHANGE_MSG = 63;
1452    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1453    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1454
1455    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1456    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1457    static final int FIRST_COMPAT_MODE_MSG = 300;
1458    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1459
1460    CompatModeDialog mCompatModeDialog;
1461    long mLastMemUsageReportTime = 0;
1462
1463    /**
1464     * Flag whether the current user is a "monkey", i.e. whether
1465     * the UI is driven by a UI automation tool.
1466     */
1467    private boolean mUserIsMonkey;
1468
1469    /** Flag whether the device has a Recents UI */
1470    boolean mHasRecents;
1471
1472    /** The dimensions of the thumbnails in the Recents UI. */
1473    int mThumbnailWidth;
1474    int mThumbnailHeight;
1475
1476    final ServiceThread mHandlerThread;
1477    final MainHandler mHandler;
1478    final UiHandler mUiHandler;
1479    final ProcessStartLogger mProcessStartLogger;
1480
1481    PackageManagerInternal mPackageManagerInt;
1482
1483    final class UiHandler extends Handler {
1484        public UiHandler() {
1485            super(com.android.server.UiThread.get().getLooper(), null, true);
1486        }
1487
1488        @Override
1489        public void handleMessage(Message msg) {
1490            switch (msg.what) {
1491            case SHOW_ERROR_UI_MSG: {
1492                mAppErrors.handleShowAppErrorUi(msg);
1493                ensureBootCompleted();
1494            } break;
1495            case SHOW_NOT_RESPONDING_UI_MSG: {
1496                mAppErrors.handleShowAnrUi(msg);
1497                ensureBootCompleted();
1498            } break;
1499            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1500                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1501                synchronized (ActivityManagerService.this) {
1502                    ProcessRecord proc = (ProcessRecord) data.get("app");
1503                    if (proc == null) {
1504                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1505                        break;
1506                    }
1507                    if (proc.crashDialog != null) {
1508                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1509                        return;
1510                    }
1511                    AppErrorResult res = (AppErrorResult) data.get("result");
1512                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1513                        Dialog d = new StrictModeViolationDialog(mContext,
1514                                ActivityManagerService.this, res, proc);
1515                        d.show();
1516                        proc.crashDialog = d;
1517                    } else {
1518                        // The device is asleep, so just pretend that the user
1519                        // saw a crash dialog and hit "force quit".
1520                        res.set(0);
1521                    }
1522                }
1523                ensureBootCompleted();
1524            } break;
1525            case SHOW_FACTORY_ERROR_UI_MSG: {
1526                Dialog d = new FactoryErrorDialog(
1527                    mContext, msg.getData().getCharSequence("msg"));
1528                d.show();
1529                ensureBootCompleted();
1530            } break;
1531            case WAIT_FOR_DEBUGGER_UI_MSG: {
1532                synchronized (ActivityManagerService.this) {
1533                    ProcessRecord app = (ProcessRecord)msg.obj;
1534                    if (msg.arg1 != 0) {
1535                        if (!app.waitedForDebugger) {
1536                            Dialog d = new AppWaitingForDebuggerDialog(
1537                                    ActivityManagerService.this,
1538                                    mContext, app);
1539                            app.waitDialog = d;
1540                            app.waitedForDebugger = true;
1541                            d.show();
1542                        }
1543                    } else {
1544                        if (app.waitDialog != null) {
1545                            app.waitDialog.dismiss();
1546                            app.waitDialog = null;
1547                        }
1548                    }
1549                }
1550            } break;
1551            case SHOW_UID_ERROR_UI_MSG: {
1552                if (mShowDialogs) {
1553                    AlertDialog d = new BaseErrorDialog(mContext);
1554                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1555                    d.setCancelable(false);
1556                    d.setTitle(mContext.getText(R.string.android_system_label));
1557                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1558                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1559                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1560                    d.show();
1561                }
1562            } break;
1563            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1564                if (mShowDialogs) {
1565                    AlertDialog d = new BaseErrorDialog(mContext);
1566                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1567                    d.setCancelable(false);
1568                    d.setTitle(mContext.getText(R.string.android_system_label));
1569                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1570                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1571                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1572                    d.show();
1573                }
1574            } break;
1575            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1576                synchronized (ActivityManagerService.this) {
1577                    ActivityRecord ar = (ActivityRecord) msg.obj;
1578                    if (mCompatModeDialog != null) {
1579                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1580                                ar.info.applicationInfo.packageName)) {
1581                            return;
1582                        }
1583                        mCompatModeDialog.dismiss();
1584                        mCompatModeDialog = null;
1585                    }
1586                    if (ar != null && false) {
1587                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1588                                ar.packageName)) {
1589                            int mode = mCompatModePackages.computeCompatModeLocked(
1590                                    ar.info.applicationInfo);
1591                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1592                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1593                                mCompatModeDialog = new CompatModeDialog(
1594                                        ActivityManagerService.this, mContext,
1595                                        ar.info.applicationInfo);
1596                                mCompatModeDialog.show();
1597                            }
1598                        }
1599                    }
1600                }
1601                break;
1602            }
1603            case START_USER_SWITCH_UI_MSG: {
1604                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1605                break;
1606            }
1607            case DISMISS_DIALOG_UI_MSG: {
1608                final Dialog d = (Dialog) msg.obj;
1609                d.dismiss();
1610                break;
1611            }
1612            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1613                dispatchProcessesChanged();
1614                break;
1615            }
1616            case DISPATCH_PROCESS_DIED_UI_MSG: {
1617                final int pid = msg.arg1;
1618                final int uid = msg.arg2;
1619                dispatchProcessDied(pid, uid);
1620                break;
1621            }
1622            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1623                dispatchUidsChanged();
1624            } break;
1625            }
1626        }
1627    }
1628
1629    final class MainHandler extends Handler {
1630        public MainHandler(Looper looper) {
1631            super(looper, null, true);
1632        }
1633
1634        @Override
1635        public void handleMessage(Message msg) {
1636            switch (msg.what) {
1637            case UPDATE_CONFIGURATION_MSG: {
1638                final ContentResolver resolver = mContext.getContentResolver();
1639                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1640                        msg.arg1);
1641            } break;
1642            case GC_BACKGROUND_PROCESSES_MSG: {
1643                synchronized (ActivityManagerService.this) {
1644                    performAppGcsIfAppropriateLocked();
1645                }
1646            } break;
1647            case SERVICE_TIMEOUT_MSG: {
1648                if (mDidDexOpt) {
1649                    mDidDexOpt = false;
1650                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1651                    nmsg.obj = msg.obj;
1652                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1653                    return;
1654                }
1655                mServices.serviceTimeout((ProcessRecord)msg.obj);
1656            } break;
1657            case UPDATE_TIME_ZONE: {
1658                synchronized (ActivityManagerService.this) {
1659                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1660                        ProcessRecord r = mLruProcesses.get(i);
1661                        if (r.thread != null) {
1662                            try {
1663                                r.thread.updateTimeZone();
1664                            } catch (RemoteException ex) {
1665                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1666                            }
1667                        }
1668                    }
1669                }
1670            } break;
1671            case CLEAR_DNS_CACHE_MSG: {
1672                synchronized (ActivityManagerService.this) {
1673                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1674                        ProcessRecord r = mLruProcesses.get(i);
1675                        if (r.thread != null) {
1676                            try {
1677                                r.thread.clearDnsCache();
1678                            } catch (RemoteException ex) {
1679                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1680                            }
1681                        }
1682                    }
1683                }
1684            } break;
1685            case UPDATE_HTTP_PROXY_MSG: {
1686                ProxyInfo proxy = (ProxyInfo)msg.obj;
1687                String host = "";
1688                String port = "";
1689                String exclList = "";
1690                Uri pacFileUrl = Uri.EMPTY;
1691                if (proxy != null) {
1692                    host = proxy.getHost();
1693                    port = Integer.toString(proxy.getPort());
1694                    exclList = proxy.getExclusionListAsString();
1695                    pacFileUrl = proxy.getPacFileUrl();
1696                }
1697                synchronized (ActivityManagerService.this) {
1698                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1699                        ProcessRecord r = mLruProcesses.get(i);
1700                        if (r.thread != null) {
1701                            try {
1702                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1703                            } catch (RemoteException ex) {
1704                                Slog.w(TAG, "Failed to update http proxy for: " +
1705                                        r.info.processName);
1706                            }
1707                        }
1708                    }
1709                }
1710            } break;
1711            case PROC_START_TIMEOUT_MSG: {
1712                if (mDidDexOpt) {
1713                    mDidDexOpt = false;
1714                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1715                    nmsg.obj = msg.obj;
1716                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1717                    return;
1718                }
1719                ProcessRecord app = (ProcessRecord)msg.obj;
1720                synchronized (ActivityManagerService.this) {
1721                    processStartTimedOutLocked(app);
1722                }
1723            } break;
1724            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1725                ProcessRecord app = (ProcessRecord)msg.obj;
1726                synchronized (ActivityManagerService.this) {
1727                    processContentProviderPublishTimedOutLocked(app);
1728                }
1729            } break;
1730            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1731                synchronized (ActivityManagerService.this) {
1732                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1733                }
1734            } break;
1735            case KILL_APPLICATION_MSG: {
1736                synchronized (ActivityManagerService.this) {
1737                    int appid = msg.arg1;
1738                    boolean restart = (msg.arg2 == 1);
1739                    Bundle bundle = (Bundle)msg.obj;
1740                    String pkg = bundle.getString("pkg");
1741                    String reason = bundle.getString("reason");
1742                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1743                            false, UserHandle.USER_ALL, reason);
1744                }
1745            } break;
1746            case FINALIZE_PENDING_INTENT_MSG: {
1747                ((PendingIntentRecord)msg.obj).completeFinalize();
1748            } break;
1749            case POST_HEAVY_NOTIFICATION_MSG: {
1750                INotificationManager inm = NotificationManager.getService();
1751                if (inm == null) {
1752                    return;
1753                }
1754
1755                ActivityRecord root = (ActivityRecord)msg.obj;
1756                ProcessRecord process = root.app;
1757                if (process == null) {
1758                    return;
1759                }
1760
1761                try {
1762                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1763                    String text = mContext.getString(R.string.heavy_weight_notification,
1764                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1765                    Notification notification = new Notification.Builder(context)
1766                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1767                            .setWhen(0)
1768                            .setOngoing(true)
1769                            .setTicker(text)
1770                            .setColor(mContext.getColor(
1771                                    com.android.internal.R.color.system_notification_accent_color))
1772                            .setContentTitle(text)
1773                            .setContentText(
1774                                    mContext.getText(R.string.heavy_weight_notification_detail))
1775                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1776                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1777                                    new UserHandle(root.userId)))
1778                            .build();
1779                    try {
1780                        int[] outId = new int[1];
1781                        inm.enqueueNotificationWithTag("android", "android", null,
1782                                R.string.heavy_weight_notification,
1783                                notification, outId, root.userId);
1784                    } catch (RuntimeException e) {
1785                        Slog.w(ActivityManagerService.TAG,
1786                                "Error showing notification for heavy-weight app", e);
1787                    } catch (RemoteException e) {
1788                    }
1789                } catch (NameNotFoundException e) {
1790                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1791                }
1792            } break;
1793            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1794                INotificationManager inm = NotificationManager.getService();
1795                if (inm == null) {
1796                    return;
1797                }
1798                try {
1799                    inm.cancelNotificationWithTag("android", null,
1800                            R.string.heavy_weight_notification,  msg.arg1);
1801                } catch (RuntimeException e) {
1802                    Slog.w(ActivityManagerService.TAG,
1803                            "Error canceling notification for service", e);
1804                } catch (RemoteException e) {
1805                }
1806            } break;
1807            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1808                synchronized (ActivityManagerService.this) {
1809                    checkExcessivePowerUsageLocked(true);
1810                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1811                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1812                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1813                }
1814            } break;
1815            case REPORT_MEM_USAGE_MSG: {
1816                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1817                Thread thread = new Thread() {
1818                    @Override public void run() {
1819                        reportMemUsage(memInfos);
1820                    }
1821                };
1822                thread.start();
1823                break;
1824            }
1825            case REPORT_USER_SWITCH_MSG: {
1826                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1827                break;
1828            }
1829            case CONTINUE_USER_SWITCH_MSG: {
1830                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1831                break;
1832            }
1833            case USER_SWITCH_TIMEOUT_MSG: {
1834                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1835                break;
1836            }
1837            case IMMERSIVE_MODE_LOCK_MSG: {
1838                final boolean nextState = (msg.arg1 != 0);
1839                if (mUpdateLock.isHeld() != nextState) {
1840                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1841                            "Applying new update lock state '" + nextState
1842                            + "' for " + (ActivityRecord)msg.obj);
1843                    if (nextState) {
1844                        mUpdateLock.acquire();
1845                    } else {
1846                        mUpdateLock.release();
1847                    }
1848                }
1849                break;
1850            }
1851            case PERSIST_URI_GRANTS_MSG: {
1852                writeGrantedUriPermissions();
1853                break;
1854            }
1855            case REQUEST_ALL_PSS_MSG: {
1856                synchronized (ActivityManagerService.this) {
1857                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1858                }
1859                break;
1860            }
1861            case START_PROFILES_MSG: {
1862                synchronized (ActivityManagerService.this) {
1863                    mUserController.startProfilesLocked();
1864                }
1865                break;
1866            }
1867            case UPDATE_TIME: {
1868                synchronized (ActivityManagerService.this) {
1869                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1870                        ProcessRecord r = mLruProcesses.get(i);
1871                        if (r.thread != null) {
1872                            try {
1873                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1874                            } catch (RemoteException ex) {
1875                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1876                            }
1877                        }
1878                    }
1879                }
1880                break;
1881            }
1882            case SYSTEM_USER_START_MSG: {
1883                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1884                        Integer.toString(msg.arg1), msg.arg1);
1885                mSystemServiceManager.startUser(msg.arg1);
1886                break;
1887            }
1888            case SYSTEM_USER_UNLOCK_MSG: {
1889                final int userId = msg.arg1;
1890                mSystemServiceManager.unlockUser(userId);
1891                mRecentTasks.cleanupLocked(userId);
1892                installEncryptionUnawareProviders(userId);
1893                break;
1894            }
1895            case SYSTEM_USER_CURRENT_MSG: {
1896                mBatteryStatsService.noteEvent(
1897                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1898                        Integer.toString(msg.arg2), msg.arg2);
1899                mBatteryStatsService.noteEvent(
1900                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1901                        Integer.toString(msg.arg1), msg.arg1);
1902                mSystemServiceManager.switchUser(msg.arg1);
1903                break;
1904            }
1905            case ENTER_ANIMATION_COMPLETE_MSG: {
1906                synchronized (ActivityManagerService.this) {
1907                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1908                    if (r != null && r.app != null && r.app.thread != null) {
1909                        try {
1910                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1911                        } catch (RemoteException e) {
1912                        }
1913                    }
1914                }
1915                break;
1916            }
1917            case FINISH_BOOTING_MSG: {
1918                if (msg.arg1 != 0) {
1919                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1920                    finishBooting();
1921                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1922                }
1923                if (msg.arg2 != 0) {
1924                    enableScreenAfterBoot();
1925                }
1926                break;
1927            }
1928            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1929                try {
1930                    Locale l = (Locale) msg.obj;
1931                    IBinder service = ServiceManager.getService("mount");
1932                    IMountService mountService = IMountService.Stub.asInterface(service);
1933                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1934                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1935                } catch (RemoteException e) {
1936                    Log.e(TAG, "Error storing locale for decryption UI", e);
1937                }
1938                break;
1939            }
1940            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1941                synchronized (ActivityManagerService.this) {
1942                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1943                        try {
1944                            // Make a one-way callback to the listener
1945                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1946                        } catch (RemoteException e){
1947                            // Handled by the RemoteCallbackList
1948                        }
1949                    }
1950                    mTaskStackListeners.finishBroadcast();
1951                }
1952                break;
1953            }
1954            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
1955                synchronized (ActivityManagerService.this) {
1956                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1957                        try {
1958                            // Make a one-way callback to the listener
1959                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
1960                        } catch (RemoteException e){
1961                            // Handled by the RemoteCallbackList
1962                        }
1963                    }
1964                    mTaskStackListeners.finishBroadcast();
1965                }
1966                break;
1967            }
1968            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
1969                synchronized (ActivityManagerService.this) {
1970                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1971                        try {
1972                            // Make a one-way callback to the listener
1973                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
1974                        } catch (RemoteException e){
1975                            // Handled by the RemoteCallbackList
1976                        }
1977                    }
1978                    mTaskStackListeners.finishBroadcast();
1979                }
1980                break;
1981            }
1982            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1983                final int uid = msg.arg1;
1984                final byte[] firstPacket = (byte[]) msg.obj;
1985
1986                synchronized (mPidsSelfLocked) {
1987                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1988                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1989                        if (p.uid == uid) {
1990                            try {
1991                                p.thread.notifyCleartextNetwork(firstPacket);
1992                            } catch (RemoteException ignored) {
1993                            }
1994                        }
1995                    }
1996                }
1997                break;
1998            }
1999            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2000                final String procName;
2001                final int uid;
2002                final long memLimit;
2003                final String reportPackage;
2004                synchronized (ActivityManagerService.this) {
2005                    procName = mMemWatchDumpProcName;
2006                    uid = mMemWatchDumpUid;
2007                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2008                    if (val == null) {
2009                        val = mMemWatchProcesses.get(procName, 0);
2010                    }
2011                    if (val != null) {
2012                        memLimit = val.first;
2013                        reportPackage = val.second;
2014                    } else {
2015                        memLimit = 0;
2016                        reportPackage = null;
2017                    }
2018                }
2019                if (procName == null) {
2020                    return;
2021                }
2022
2023                if (DEBUG_PSS) Slog.d(TAG_PSS,
2024                        "Showing dump heap notification from " + procName + "/" + uid);
2025
2026                INotificationManager inm = NotificationManager.getService();
2027                if (inm == null) {
2028                    return;
2029                }
2030
2031                String text = mContext.getString(R.string.dump_heap_notification, procName);
2032
2033
2034                Intent deleteIntent = new Intent();
2035                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2036                Intent intent = new Intent();
2037                intent.setClassName("android", DumpHeapActivity.class.getName());
2038                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2039                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2040                if (reportPackage != null) {
2041                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2042                }
2043                int userId = UserHandle.getUserId(uid);
2044                Notification notification = new Notification.Builder(mContext)
2045                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2046                        .setWhen(0)
2047                        .setOngoing(true)
2048                        .setAutoCancel(true)
2049                        .setTicker(text)
2050                        .setColor(mContext.getColor(
2051                                com.android.internal.R.color.system_notification_accent_color))
2052                        .setContentTitle(text)
2053                        .setContentText(
2054                                mContext.getText(R.string.dump_heap_notification_detail))
2055                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2056                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2057                                new UserHandle(userId)))
2058                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2059                                deleteIntent, 0, UserHandle.SYSTEM))
2060                        .build();
2061
2062                try {
2063                    int[] outId = new int[1];
2064                    inm.enqueueNotificationWithTag("android", "android", null,
2065                            R.string.dump_heap_notification,
2066                            notification, outId, userId);
2067                } catch (RuntimeException e) {
2068                    Slog.w(ActivityManagerService.TAG,
2069                            "Error showing notification for dump heap", e);
2070                } catch (RemoteException e) {
2071                }
2072            } break;
2073            case DELETE_DUMPHEAP_MSG: {
2074                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2075                        DumpHeapActivity.JAVA_URI,
2076                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2077                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2078                        UserHandle.myUserId());
2079                synchronized (ActivityManagerService.this) {
2080                    mMemWatchDumpFile = null;
2081                    mMemWatchDumpProcName = null;
2082                    mMemWatchDumpPid = -1;
2083                    mMemWatchDumpUid = -1;
2084                }
2085            } break;
2086            case FOREGROUND_PROFILE_CHANGED_MSG: {
2087                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2088            } break;
2089            case REPORT_TIME_TRACKER_MSG: {
2090                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2091                tracker.deliverResult(mContext);
2092            } break;
2093            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2094                mUserController.dispatchUserSwitchComplete(msg.arg1);
2095            } break;
2096            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2097                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2098                try {
2099                    connection.shutdown();
2100                } catch (RemoteException e) {
2101                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2102                }
2103                // Only a UiAutomation can set this flag and now that
2104                // it is finished we make sure it is reset to its default.
2105                mUserIsMonkey = false;
2106            } break;
2107            case APP_BOOST_DEACTIVATE_MSG: {
2108                synchronized(ActivityManagerService.this) {
2109                    if (mIsBoosted) {
2110                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2111                            nativeMigrateFromBoost();
2112                            mIsBoosted = false;
2113                            mBoostStartTime = 0;
2114                        } else {
2115                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2116                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2117                        }
2118                    }
2119                }
2120            } break;
2121            case IDLE_UIDS_MSG: {
2122                idleUids();
2123            } break;
2124            case LOG_STACK_STATE: {
2125                synchronized (ActivityManagerService.this) {
2126                    mStackSupervisor.logStackState();
2127                }
2128            } break;
2129            case VR_MODE_CHANGE_MSG: {
2130                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2131                final boolean vrMode = msg.arg1 != 0;
2132                vrService.setVrMode(vrMode);
2133
2134                if (mInVrMode != vrMode) {
2135                    synchronized (ActivityManagerService.this) {
2136                        mInVrMode = vrMode;
2137                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2138                    }
2139                }
2140            } break;
2141            }
2142        }
2143    };
2144
2145    static final int COLLECT_PSS_BG_MSG = 1;
2146
2147    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2148        @Override
2149        public void handleMessage(Message msg) {
2150            switch (msg.what) {
2151            case COLLECT_PSS_BG_MSG: {
2152                long start = SystemClock.uptimeMillis();
2153                MemInfoReader memInfo = null;
2154                synchronized (ActivityManagerService.this) {
2155                    if (mFullPssPending) {
2156                        mFullPssPending = false;
2157                        memInfo = new MemInfoReader();
2158                    }
2159                }
2160                if (memInfo != null) {
2161                    updateCpuStatsNow();
2162                    long nativeTotalPss = 0;
2163                    synchronized (mProcessCpuTracker) {
2164                        final int N = mProcessCpuTracker.countStats();
2165                        for (int j=0; j<N; j++) {
2166                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2167                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2168                                // This is definitely an application process; skip it.
2169                                continue;
2170                            }
2171                            synchronized (mPidsSelfLocked) {
2172                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2173                                    // This is one of our own processes; skip it.
2174                                    continue;
2175                                }
2176                            }
2177                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2178                        }
2179                    }
2180                    memInfo.readMemInfo();
2181                    synchronized (ActivityManagerService.this) {
2182                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2183                                + (SystemClock.uptimeMillis()-start) + "ms");
2184                        final long cachedKb = memInfo.getCachedSizeKb();
2185                        final long freeKb = memInfo.getFreeSizeKb();
2186                        final long zramKb = memInfo.getZramTotalSizeKb();
2187                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2188                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2189                                kernelKb*1024, nativeTotalPss*1024);
2190                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2191                                nativeTotalPss);
2192                    }
2193                }
2194
2195                int num = 0;
2196                long[] tmp = new long[2];
2197                do {
2198                    ProcessRecord proc;
2199                    int procState;
2200                    int pid;
2201                    long lastPssTime;
2202                    synchronized (ActivityManagerService.this) {
2203                        if (mPendingPssProcesses.size() <= 0) {
2204                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2205                                    "Collected PSS of " + num + " processes in "
2206                                    + (SystemClock.uptimeMillis() - start) + "ms");
2207                            mPendingPssProcesses.clear();
2208                            return;
2209                        }
2210                        proc = mPendingPssProcesses.remove(0);
2211                        procState = proc.pssProcState;
2212                        lastPssTime = proc.lastPssTime;
2213                        if (proc.thread != null && procState == proc.setProcState
2214                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2215                                        < SystemClock.uptimeMillis()) {
2216                            pid = proc.pid;
2217                        } else {
2218                            proc = null;
2219                            pid = 0;
2220                        }
2221                    }
2222                    if (proc != null) {
2223                        long pss = Debug.getPss(pid, tmp, null);
2224                        synchronized (ActivityManagerService.this) {
2225                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2226                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2227                                num++;
2228                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2229                                        SystemClock.uptimeMillis());
2230                            }
2231                        }
2232                    }
2233                } while (true);
2234            }
2235            }
2236        }
2237    };
2238
2239    public void setSystemProcess() {
2240        try {
2241            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2242            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2243            ServiceManager.addService("meminfo", new MemBinder(this));
2244            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2245            ServiceManager.addService("dbinfo", new DbBinder(this));
2246            if (MONITOR_CPU_USAGE) {
2247                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2248            }
2249            ServiceManager.addService("permission", new PermissionController(this));
2250            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2251
2252            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2253                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2254            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2255
2256            synchronized (this) {
2257                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2258                app.persistent = true;
2259                app.pid = MY_PID;
2260                app.maxAdj = ProcessList.SYSTEM_ADJ;
2261                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2262                synchronized (mPidsSelfLocked) {
2263                    mPidsSelfLocked.put(app.pid, app);
2264                }
2265                updateLruProcessLocked(app, false, null);
2266                updateOomAdjLocked();
2267            }
2268        } catch (PackageManager.NameNotFoundException e) {
2269            throw new RuntimeException(
2270                    "Unable to find android system package", e);
2271        }
2272    }
2273
2274    public void setWindowManager(WindowManagerService wm) {
2275        mWindowManager = wm;
2276        mStackSupervisor.setWindowManager(wm);
2277        mActivityStarter.setWindowManager(wm);
2278    }
2279
2280    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2281        mUsageStatsService = usageStatsManager;
2282    }
2283
2284    public void startObservingNativeCrashes() {
2285        final NativeCrashListener ncl = new NativeCrashListener(this);
2286        ncl.start();
2287    }
2288
2289    public IAppOpsService getAppOpsService() {
2290        return mAppOpsService;
2291    }
2292
2293    static class MemBinder extends Binder {
2294        ActivityManagerService mActivityManagerService;
2295        MemBinder(ActivityManagerService activityManagerService) {
2296            mActivityManagerService = activityManagerService;
2297        }
2298
2299        @Override
2300        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2301            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2302                    != PackageManager.PERMISSION_GRANTED) {
2303                pw.println("Permission Denial: can't dump meminfo from from pid="
2304                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2305                        + " without permission " + android.Manifest.permission.DUMP);
2306                return;
2307            }
2308
2309            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2310        }
2311    }
2312
2313    static class GraphicsBinder extends Binder {
2314        ActivityManagerService mActivityManagerService;
2315        GraphicsBinder(ActivityManagerService activityManagerService) {
2316            mActivityManagerService = activityManagerService;
2317        }
2318
2319        @Override
2320        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2321            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2322                    != PackageManager.PERMISSION_GRANTED) {
2323                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2324                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2325                        + " without permission " + android.Manifest.permission.DUMP);
2326                return;
2327            }
2328
2329            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2330        }
2331    }
2332
2333    static class DbBinder extends Binder {
2334        ActivityManagerService mActivityManagerService;
2335        DbBinder(ActivityManagerService activityManagerService) {
2336            mActivityManagerService = activityManagerService;
2337        }
2338
2339        @Override
2340        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2341            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2342                    != PackageManager.PERMISSION_GRANTED) {
2343                pw.println("Permission Denial: can't dump dbinfo from from pid="
2344                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2345                        + " without permission " + android.Manifest.permission.DUMP);
2346                return;
2347            }
2348
2349            mActivityManagerService.dumpDbInfo(fd, pw, args);
2350        }
2351    }
2352
2353    static class CpuBinder extends Binder {
2354        ActivityManagerService mActivityManagerService;
2355        CpuBinder(ActivityManagerService activityManagerService) {
2356            mActivityManagerService = activityManagerService;
2357        }
2358
2359        @Override
2360        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2361            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2362                    != PackageManager.PERMISSION_GRANTED) {
2363                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2364                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2365                        + " without permission " + android.Manifest.permission.DUMP);
2366                return;
2367            }
2368
2369            synchronized (mActivityManagerService.mProcessCpuTracker) {
2370                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2371                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2372                        SystemClock.uptimeMillis()));
2373            }
2374        }
2375    }
2376
2377    public static final class Lifecycle extends SystemService {
2378        private final ActivityManagerService mService;
2379
2380        public Lifecycle(Context context) {
2381            super(context);
2382            mService = new ActivityManagerService(context);
2383        }
2384
2385        @Override
2386        public void onStart() {
2387            mService.start();
2388        }
2389
2390        public ActivityManagerService getService() {
2391            return mService;
2392        }
2393    }
2394
2395    // Note: This method is invoked on the main thread but may need to attach various
2396    // handlers to other threads.  So take care to be explicit about the looper.
2397    public ActivityManagerService(Context systemContext) {
2398        mContext = systemContext;
2399        mFactoryTest = FactoryTest.getMode();
2400        mSystemThread = ActivityThread.currentActivityThread();
2401
2402        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2403
2404        mHandlerThread = new ServiceThread(TAG,
2405                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2406        mHandlerThread.start();
2407        mHandler = new MainHandler(mHandlerThread.getLooper());
2408        mUiHandler = new UiHandler();
2409
2410        mProcessStartLogger = new ProcessStartLogger();
2411
2412        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2413                "foreground", BROADCAST_FG_TIMEOUT, false);
2414        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2415                "background", BROADCAST_BG_TIMEOUT, true);
2416        mBroadcastQueues[0] = mFgBroadcastQueue;
2417        mBroadcastQueues[1] = mBgBroadcastQueue;
2418
2419        mServices = new ActiveServices(this);
2420        mProviderMap = new ProviderMap(this);
2421        mAppErrors = new AppErrors(mContext, this);
2422
2423        // TODO: Move creation of battery stats service outside of activity manager service.
2424        File dataDir = Environment.getDataDirectory();
2425        File systemDir = new File(dataDir, "system");
2426        systemDir.mkdirs();
2427        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2428        mBatteryStatsService.getActiveStatistics().readLocked();
2429        mBatteryStatsService.scheduleWriteToDisk();
2430        mOnBattery = DEBUG_POWER ? true
2431                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2432        mBatteryStatsService.getActiveStatistics().setCallback(this);
2433
2434        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2435
2436        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2437        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2438                new IAppOpsCallback.Stub() {
2439                    @Override public void opChanged(int op, int uid, String packageName) {
2440                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2441                            if (mAppOpsService.checkOperation(op, uid, packageName)
2442                                    != AppOpsManager.MODE_ALLOWED) {
2443                                runInBackgroundDisabled(uid);
2444                            }
2445                        }
2446                    }
2447                });
2448
2449        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2450
2451        mUserController = new UserController(this);
2452
2453        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2454            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2455
2456        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2457
2458        mConfiguration.setToDefaults();
2459        mConfiguration.setLocales(LocaleList.getDefault());
2460
2461        mConfigurationSeq = mConfiguration.seq = 1;
2462        mProcessCpuTracker.init();
2463
2464        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2465        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2466        mStackSupervisor = new ActivityStackSupervisor(this);
2467        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2468        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2469
2470
2471        mProcessCpuThread = new Thread("CpuTracker") {
2472            @Override
2473            public void run() {
2474                while (true) {
2475                    try {
2476                        try {
2477                            synchronized(this) {
2478                                final long now = SystemClock.uptimeMillis();
2479                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2480                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2481                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2482                                //        + ", write delay=" + nextWriteDelay);
2483                                if (nextWriteDelay < nextCpuDelay) {
2484                                    nextCpuDelay = nextWriteDelay;
2485                                }
2486                                if (nextCpuDelay > 0) {
2487                                    mProcessCpuMutexFree.set(true);
2488                                    this.wait(nextCpuDelay);
2489                                }
2490                            }
2491                        } catch (InterruptedException e) {
2492                        }
2493                        updateCpuStatsNow();
2494                    } catch (Exception e) {
2495                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2496                    }
2497                }
2498            }
2499        };
2500
2501        Watchdog.getInstance().addMonitor(this);
2502        Watchdog.getInstance().addThread(mHandler);
2503    }
2504
2505    public void setSystemServiceManager(SystemServiceManager mgr) {
2506        mSystemServiceManager = mgr;
2507    }
2508
2509    public void setInstaller(Installer installer) {
2510        mInstaller = installer;
2511    }
2512
2513    private void start() {
2514        Process.removeAllProcessGroups();
2515        mProcessCpuThread.start();
2516
2517        mBatteryStatsService.publish(mContext);
2518        mAppOpsService.publish(mContext);
2519        Slog.d("AppOps", "AppOpsService published");
2520        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2521    }
2522
2523    void onUserStoppedLocked(int userId) {
2524        mRecentTasks.unloadUserRecentsLocked(userId);
2525    }
2526
2527    public void initPowerManagement() {
2528        mStackSupervisor.initPowerManagement();
2529        mBatteryStatsService.initPowerManagement();
2530        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2531        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2532        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2533        mVoiceWakeLock.setReferenceCounted(false);
2534    }
2535
2536    @Override
2537    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2538            throws RemoteException {
2539        if (code == SYSPROPS_TRANSACTION) {
2540            // We need to tell all apps about the system property change.
2541            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2542            synchronized(this) {
2543                final int NP = mProcessNames.getMap().size();
2544                for (int ip=0; ip<NP; ip++) {
2545                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2546                    final int NA = apps.size();
2547                    for (int ia=0; ia<NA; ia++) {
2548                        ProcessRecord app = apps.valueAt(ia);
2549                        if (app.thread != null) {
2550                            procs.add(app.thread.asBinder());
2551                        }
2552                    }
2553                }
2554            }
2555
2556            int N = procs.size();
2557            for (int i=0; i<N; i++) {
2558                Parcel data2 = Parcel.obtain();
2559                try {
2560                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2561                } catch (RemoteException e) {
2562                }
2563                data2.recycle();
2564            }
2565        }
2566        try {
2567            return super.onTransact(code, data, reply, flags);
2568        } catch (RuntimeException e) {
2569            // The activity manager only throws security exceptions, so let's
2570            // log all others.
2571            if (!(e instanceof SecurityException)) {
2572                Slog.wtf(TAG, "Activity Manager Crash", e);
2573            }
2574            throw e;
2575        }
2576    }
2577
2578    void updateCpuStats() {
2579        final long now = SystemClock.uptimeMillis();
2580        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2581            return;
2582        }
2583        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2584            synchronized (mProcessCpuThread) {
2585                mProcessCpuThread.notify();
2586            }
2587        }
2588    }
2589
2590    void updateCpuStatsNow() {
2591        synchronized (mProcessCpuTracker) {
2592            mProcessCpuMutexFree.set(false);
2593            final long now = SystemClock.uptimeMillis();
2594            boolean haveNewCpuStats = false;
2595
2596            if (MONITOR_CPU_USAGE &&
2597                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2598                mLastCpuTime.set(now);
2599                mProcessCpuTracker.update();
2600                if (mProcessCpuTracker.hasGoodLastStats()) {
2601                    haveNewCpuStats = true;
2602                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2603                    //Slog.i(TAG, "Total CPU usage: "
2604                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2605
2606                    // Slog the cpu usage if the property is set.
2607                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2608                        int user = mProcessCpuTracker.getLastUserTime();
2609                        int system = mProcessCpuTracker.getLastSystemTime();
2610                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2611                        int irq = mProcessCpuTracker.getLastIrqTime();
2612                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2613                        int idle = mProcessCpuTracker.getLastIdleTime();
2614
2615                        int total = user + system + iowait + irq + softIrq + idle;
2616                        if (total == 0) total = 1;
2617
2618                        EventLog.writeEvent(EventLogTags.CPU,
2619                                ((user+system+iowait+irq+softIrq) * 100) / total,
2620                                (user * 100) / total,
2621                                (system * 100) / total,
2622                                (iowait * 100) / total,
2623                                (irq * 100) / total,
2624                                (softIrq * 100) / total);
2625                    }
2626                }
2627            }
2628
2629            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2630            synchronized(bstats) {
2631                synchronized(mPidsSelfLocked) {
2632                    if (haveNewCpuStats) {
2633                        if (bstats.startAddingCpuLocked()) {
2634                            int totalUTime = 0;
2635                            int totalSTime = 0;
2636                            final int N = mProcessCpuTracker.countStats();
2637                            for (int i=0; i<N; i++) {
2638                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2639                                if (!st.working) {
2640                                    continue;
2641                                }
2642                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2643                                totalUTime += st.rel_utime;
2644                                totalSTime += st.rel_stime;
2645                                if (pr != null) {
2646                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2647                                    if (ps == null || !ps.isActive()) {
2648                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2649                                                pr.info.uid, pr.processName);
2650                                    }
2651                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2652                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2653                                } else {
2654                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2655                                    if (ps == null || !ps.isActive()) {
2656                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2657                                                bstats.mapUid(st.uid), st.name);
2658                                    }
2659                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2660                                }
2661                            }
2662                            final int userTime = mProcessCpuTracker.getLastUserTime();
2663                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2664                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2665                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2666                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2667                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2668                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2669                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2670                        }
2671                    }
2672                }
2673
2674                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2675                    mLastWriteTime = now;
2676                    mBatteryStatsService.scheduleWriteToDisk();
2677                }
2678            }
2679        }
2680    }
2681
2682    @Override
2683    public void batteryNeedsCpuUpdate() {
2684        updateCpuStatsNow();
2685    }
2686
2687    @Override
2688    public void batteryPowerChanged(boolean onBattery) {
2689        // When plugging in, update the CPU stats first before changing
2690        // the plug state.
2691        updateCpuStatsNow();
2692        synchronized (this) {
2693            synchronized(mPidsSelfLocked) {
2694                mOnBattery = DEBUG_POWER ? true : onBattery;
2695            }
2696        }
2697    }
2698
2699    @Override
2700    public void batterySendBroadcast(Intent intent) {
2701        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2702                AppOpsManager.OP_NONE, null, false, false,
2703                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2704    }
2705
2706    /**
2707     * Initialize the application bind args. These are passed to each
2708     * process when the bindApplication() IPC is sent to the process. They're
2709     * lazily setup to make sure the services are running when they're asked for.
2710     */
2711    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2712        if (mAppBindArgs == null) {
2713            mAppBindArgs = new HashMap<>();
2714
2715            // Isolated processes won't get this optimization, so that we don't
2716            // violate the rules about which services they have access to.
2717            if (!isolated) {
2718                // Setup the application init args
2719                mAppBindArgs.put("package", ServiceManager.getService("package"));
2720                mAppBindArgs.put("window", ServiceManager.getService("window"));
2721                mAppBindArgs.put(Context.ALARM_SERVICE,
2722                        ServiceManager.getService(Context.ALARM_SERVICE));
2723            }
2724        }
2725        return mAppBindArgs;
2726    }
2727
2728    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2729        if (r == null || mFocusedActivity == r) {
2730            return false;
2731        }
2732
2733        if (!r.isFocusable()) {
2734            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2735            return false;
2736        }
2737
2738        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2739
2740        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2741        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2742                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2743        mDoingSetFocusedActivity = true;
2744
2745        final ActivityRecord last = mFocusedActivity;
2746        mFocusedActivity = r;
2747        if (r.task.isApplicationTask()) {
2748            if (mCurAppTimeTracker != r.appTimeTracker) {
2749                // We are switching app tracking.  Complete the current one.
2750                if (mCurAppTimeTracker != null) {
2751                    mCurAppTimeTracker.stop();
2752                    mHandler.obtainMessage(
2753                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2754                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2755                    mCurAppTimeTracker = null;
2756                }
2757                if (r.appTimeTracker != null) {
2758                    mCurAppTimeTracker = r.appTimeTracker;
2759                    startTimeTrackingFocusedActivityLocked();
2760                }
2761            } else {
2762                startTimeTrackingFocusedActivityLocked();
2763            }
2764        } else {
2765            r.appTimeTracker = null;
2766        }
2767        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2768        // TODO: Probably not, because we don't want to resume voice on switching
2769        // back to this activity
2770        if (r.task.voiceInteractor != null) {
2771            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2772        } else {
2773            finishRunningVoiceLocked();
2774            IVoiceInteractionSession session;
2775            if (last != null && ((session = last.task.voiceSession) != null
2776                    || (session = last.voiceSession) != null)) {
2777                // We had been in a voice interaction session, but now focused has
2778                // move to something different.  Just finish the session, we can't
2779                // return to it and retain the proper state and synchronization with
2780                // the voice interaction service.
2781                finishVoiceTask(session);
2782            }
2783        }
2784        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2785            mWindowManager.setFocusedApp(r.appToken, true);
2786        }
2787        applyUpdateLockStateLocked(r);
2788        applyUpdateVrModeLocked(r);
2789        if (mFocusedActivity.userId != mLastFocusedUserId) {
2790            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2791            mHandler.obtainMessage(
2792                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2793            mLastFocusedUserId = mFocusedActivity.userId;
2794        }
2795
2796        // Log a warning if the focused app is changed during the process. This could
2797        // indicate a problem of the focus setting logic!
2798        if (mFocusedActivity != r) Slog.w(TAG,
2799                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2800        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2801
2802        EventLogTags.writeAmFocusedActivity(
2803                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2804                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2805                reason);
2806        return true;
2807    }
2808
2809    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2810        if (mFocusedActivity != goingAway) {
2811            return;
2812        }
2813
2814        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2815        if (focusedStack != null) {
2816            final ActivityRecord top = focusedStack.topActivity();
2817            if (top != null && top.userId != mLastFocusedUserId) {
2818                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2819                mHandler.sendMessage(
2820                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2821                mLastFocusedUserId = top.userId;
2822            }
2823        }
2824
2825        // Try to move focus to another activity if possible.
2826        if (setFocusedActivityLocked(
2827                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2828            return;
2829        }
2830
2831        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2832                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2833        mFocusedActivity = null;
2834        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2835    }
2836
2837    @Override
2838    public void setFocusedStack(int stackId) {
2839        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2840        synchronized (ActivityManagerService.this) {
2841            ActivityStack stack = mStackSupervisor.getStack(stackId);
2842            if (stack != null) {
2843                ActivityRecord r = stack.topRunningActivityLocked();
2844                if (r != null) {
2845                    setFocusedActivityLocked(r, "setFocusedStack");
2846                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2847                }
2848            }
2849        }
2850    }
2851
2852    @Override
2853    public void setFocusedTask(int taskId) {
2854        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2855        long callingId = Binder.clearCallingIdentity();
2856        try {
2857            synchronized (ActivityManagerService.this) {
2858                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2859                if (task != null) {
2860                    final ActivityRecord r = task.topRunningActivityLocked();
2861                    if (setFocusedActivityLocked(r, "setFocusedTask")) {
2862                        mStackSupervisor.resumeFocusedStackTopActivityLocked();
2863                    }
2864                }
2865            }
2866        } finally {
2867            Binder.restoreCallingIdentity(callingId);
2868        }
2869    }
2870
2871    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2872    @Override
2873    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2874        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2875        synchronized (this) {
2876            if (listener != null) {
2877                mTaskStackListeners.register(listener);
2878            }
2879        }
2880    }
2881
2882    @Override
2883    public void notifyActivityDrawn(IBinder token) {
2884        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2885        synchronized (this) {
2886            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2887            if (r != null) {
2888                r.task.stack.notifyActivityDrawnLocked(r);
2889            }
2890        }
2891    }
2892
2893    final void applyUpdateLockStateLocked(ActivityRecord r) {
2894        // Modifications to the UpdateLock state are done on our handler, outside
2895        // the activity manager's locks.  The new state is determined based on the
2896        // state *now* of the relevant activity record.  The object is passed to
2897        // the handler solely for logging detail, not to be consulted/modified.
2898        final boolean nextState = r != null && r.immersive;
2899        mHandler.sendMessage(
2900                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2901    }
2902
2903    final void applyUpdateVrModeLocked(ActivityRecord r) {
2904        mHandler.sendMessage(
2905                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, (r.isVrActivity) ? 1 : 0, 0));
2906    }
2907
2908    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2909        Message msg = Message.obtain();
2910        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2911        msg.obj = r.task.askedCompatMode ? null : r;
2912        mUiHandler.sendMessage(msg);
2913    }
2914
2915    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2916            String what, Object obj, ProcessRecord srcApp) {
2917        app.lastActivityTime = now;
2918
2919        if (app.activities.size() > 0) {
2920            // Don't want to touch dependent processes that are hosting activities.
2921            return index;
2922        }
2923
2924        int lrui = mLruProcesses.lastIndexOf(app);
2925        if (lrui < 0) {
2926            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2927                    + what + " " + obj + " from " + srcApp);
2928            return index;
2929        }
2930
2931        if (lrui >= index) {
2932            // Don't want to cause this to move dependent processes *back* in the
2933            // list as if they were less frequently used.
2934            return index;
2935        }
2936
2937        if (lrui >= mLruProcessActivityStart) {
2938            // Don't want to touch dependent processes that are hosting activities.
2939            return index;
2940        }
2941
2942        mLruProcesses.remove(lrui);
2943        if (index > 0) {
2944            index--;
2945        }
2946        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2947                + " in LRU list: " + app);
2948        mLruProcesses.add(index, app);
2949        return index;
2950    }
2951
2952    static void killProcessGroup(int uid, int pid) {
2953        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2954        Process.killProcessGroup(uid, pid);
2955        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2956    }
2957
2958    final void removeLruProcessLocked(ProcessRecord app) {
2959        int lrui = mLruProcesses.lastIndexOf(app);
2960        if (lrui >= 0) {
2961            if (!app.killed) {
2962                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2963                Process.killProcessQuiet(app.pid);
2964                killProcessGroup(app.info.uid, app.pid);
2965            }
2966            if (lrui <= mLruProcessActivityStart) {
2967                mLruProcessActivityStart--;
2968            }
2969            if (lrui <= mLruProcessServiceStart) {
2970                mLruProcessServiceStart--;
2971            }
2972            mLruProcesses.remove(lrui);
2973        }
2974    }
2975
2976    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2977            ProcessRecord client) {
2978        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2979                || app.treatLikeActivity;
2980        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2981        if (!activityChange && hasActivity) {
2982            // The process has activities, so we are only allowing activity-based adjustments
2983            // to move it.  It should be kept in the front of the list with other
2984            // processes that have activities, and we don't want those to change their
2985            // order except due to activity operations.
2986            return;
2987        }
2988
2989        mLruSeq++;
2990        final long now = SystemClock.uptimeMillis();
2991        app.lastActivityTime = now;
2992
2993        // First a quick reject: if the app is already at the position we will
2994        // put it, then there is nothing to do.
2995        if (hasActivity) {
2996            final int N = mLruProcesses.size();
2997            if (N > 0 && mLruProcesses.get(N-1) == app) {
2998                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2999                return;
3000            }
3001        } else {
3002            if (mLruProcessServiceStart > 0
3003                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3004                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3005                return;
3006            }
3007        }
3008
3009        int lrui = mLruProcesses.lastIndexOf(app);
3010
3011        if (app.persistent && lrui >= 0) {
3012            // We don't care about the position of persistent processes, as long as
3013            // they are in the list.
3014            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3015            return;
3016        }
3017
3018        /* In progress: compute new position first, so we can avoid doing work
3019           if the process is not actually going to move.  Not yet working.
3020        int addIndex;
3021        int nextIndex;
3022        boolean inActivity = false, inService = false;
3023        if (hasActivity) {
3024            // Process has activities, put it at the very tipsy-top.
3025            addIndex = mLruProcesses.size();
3026            nextIndex = mLruProcessServiceStart;
3027            inActivity = true;
3028        } else if (hasService) {
3029            // Process has services, put it at the top of the service list.
3030            addIndex = mLruProcessActivityStart;
3031            nextIndex = mLruProcessServiceStart;
3032            inActivity = true;
3033            inService = true;
3034        } else  {
3035            // Process not otherwise of interest, it goes to the top of the non-service area.
3036            addIndex = mLruProcessServiceStart;
3037            if (client != null) {
3038                int clientIndex = mLruProcesses.lastIndexOf(client);
3039                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3040                        + app);
3041                if (clientIndex >= 0 && addIndex > clientIndex) {
3042                    addIndex = clientIndex;
3043                }
3044            }
3045            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3046        }
3047
3048        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3049                + mLruProcessActivityStart + "): " + app);
3050        */
3051
3052        if (lrui >= 0) {
3053            if (lrui < mLruProcessActivityStart) {
3054                mLruProcessActivityStart--;
3055            }
3056            if (lrui < mLruProcessServiceStart) {
3057                mLruProcessServiceStart--;
3058            }
3059            /*
3060            if (addIndex > lrui) {
3061                addIndex--;
3062            }
3063            if (nextIndex > lrui) {
3064                nextIndex--;
3065            }
3066            */
3067            mLruProcesses.remove(lrui);
3068        }
3069
3070        /*
3071        mLruProcesses.add(addIndex, app);
3072        if (inActivity) {
3073            mLruProcessActivityStart++;
3074        }
3075        if (inService) {
3076            mLruProcessActivityStart++;
3077        }
3078        */
3079
3080        int nextIndex;
3081        if (hasActivity) {
3082            final int N = mLruProcesses.size();
3083            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3084                // Process doesn't have activities, but has clients with
3085                // activities...  move it up, but one below the top (the top
3086                // should always have a real activity).
3087                if (DEBUG_LRU) Slog.d(TAG_LRU,
3088                        "Adding to second-top of LRU activity list: " + app);
3089                mLruProcesses.add(N - 1, app);
3090                // To keep it from spamming the LRU list (by making a bunch of clients),
3091                // we will push down any other entries owned by the app.
3092                final int uid = app.info.uid;
3093                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3094                    ProcessRecord subProc = mLruProcesses.get(i);
3095                    if (subProc.info.uid == uid) {
3096                        // We want to push this one down the list.  If the process after
3097                        // it is for the same uid, however, don't do so, because we don't
3098                        // want them internally to be re-ordered.
3099                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3100                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3101                                    "Pushing uid " + uid + " swapping at " + i + ": "
3102                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3103                            ProcessRecord tmp = mLruProcesses.get(i);
3104                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3105                            mLruProcesses.set(i - 1, tmp);
3106                            i--;
3107                        }
3108                    } else {
3109                        // A gap, we can stop here.
3110                        break;
3111                    }
3112                }
3113            } else {
3114                // Process has activities, put it at the very tipsy-top.
3115                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3116                mLruProcesses.add(app);
3117            }
3118            nextIndex = mLruProcessServiceStart;
3119        } else if (hasService) {
3120            // Process has services, put it at the top of the service list.
3121            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3122            mLruProcesses.add(mLruProcessActivityStart, app);
3123            nextIndex = mLruProcessServiceStart;
3124            mLruProcessActivityStart++;
3125        } else  {
3126            // Process not otherwise of interest, it goes to the top of the non-service area.
3127            int index = mLruProcessServiceStart;
3128            if (client != null) {
3129                // If there is a client, don't allow the process to be moved up higher
3130                // in the list than that client.
3131                int clientIndex = mLruProcesses.lastIndexOf(client);
3132                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3133                        + " when updating " + app);
3134                if (clientIndex <= lrui) {
3135                    // Don't allow the client index restriction to push it down farther in the
3136                    // list than it already is.
3137                    clientIndex = lrui;
3138                }
3139                if (clientIndex >= 0 && index > clientIndex) {
3140                    index = clientIndex;
3141                }
3142            }
3143            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3144            mLruProcesses.add(index, app);
3145            nextIndex = index-1;
3146            mLruProcessActivityStart++;
3147            mLruProcessServiceStart++;
3148        }
3149
3150        // If the app is currently using a content provider or service,
3151        // bump those processes as well.
3152        for (int j=app.connections.size()-1; j>=0; j--) {
3153            ConnectionRecord cr = app.connections.valueAt(j);
3154            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3155                    && cr.binding.service.app != null
3156                    && cr.binding.service.app.lruSeq != mLruSeq
3157                    && !cr.binding.service.app.persistent) {
3158                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3159                        "service connection", cr, app);
3160            }
3161        }
3162        for (int j=app.conProviders.size()-1; j>=0; j--) {
3163            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3164            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3165                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3166                        "provider reference", cpr, app);
3167            }
3168        }
3169    }
3170
3171    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3172        if (uid == Process.SYSTEM_UID) {
3173            // The system gets to run in any process.  If there are multiple
3174            // processes with the same uid, just pick the first (this
3175            // should never happen).
3176            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3177            if (procs == null) return null;
3178            final int procCount = procs.size();
3179            for (int i = 0; i < procCount; i++) {
3180                final int procUid = procs.keyAt(i);
3181                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3182                    // Don't use an app process or different user process for system component.
3183                    continue;
3184                }
3185                return procs.valueAt(i);
3186            }
3187        }
3188        ProcessRecord proc = mProcessNames.get(processName, uid);
3189        if (false && proc != null && !keepIfLarge
3190                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3191                && proc.lastCachedPss >= 4000) {
3192            // Turn this condition on to cause killing to happen regularly, for testing.
3193            if (proc.baseProcessTracker != null) {
3194                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3195            }
3196            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3197        } else if (proc != null && !keepIfLarge
3198                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3199                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3200            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3201            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3202                if (proc.baseProcessTracker != null) {
3203                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3204                }
3205                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3206            }
3207        }
3208        return proc;
3209    }
3210
3211    void notifyPackageUse(String packageName) {
3212        IPackageManager pm = AppGlobals.getPackageManager();
3213        try {
3214            pm.notifyPackageUse(packageName);
3215        } catch (RemoteException e) {
3216        }
3217    }
3218
3219    boolean isNextTransitionForward() {
3220        int transit = mWindowManager.getPendingAppTransition();
3221        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3222                || transit == AppTransition.TRANSIT_TASK_OPEN
3223                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3224    }
3225
3226    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3227            String processName, String abiOverride, int uid, Runnable crashHandler) {
3228        synchronized(this) {
3229            ApplicationInfo info = new ApplicationInfo();
3230            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3231            // For isolated processes, the former contains the parent's uid and the latter the
3232            // actual uid of the isolated process.
3233            // In the special case introduced by this method (which is, starting an isolated
3234            // process directly from the SystemServer without an actual parent app process) the
3235            // closest thing to a parent's uid is SYSTEM_UID.
3236            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3237            // the |isolated| logic in the ProcessRecord constructor.
3238            info.uid = Process.SYSTEM_UID;
3239            info.processName = processName;
3240            info.className = entryPoint;
3241            info.packageName = "android";
3242            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3243                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3244                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3245                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3246                    crashHandler);
3247            return proc != null ? proc.pid : 0;
3248        }
3249    }
3250
3251    final ProcessRecord startProcessLocked(String processName,
3252            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3253            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3254            boolean isolated, boolean keepIfLarge) {
3255        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3256                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3257                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3258                null /* crashHandler */);
3259    }
3260
3261    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3262            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3263            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3264            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3265        long startTime = SystemClock.elapsedRealtime();
3266        ProcessRecord app;
3267        if (!isolated) {
3268            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3269            checkTime(startTime, "startProcess: after getProcessRecord");
3270
3271            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3272                // If we are in the background, then check to see if this process
3273                // is bad.  If so, we will just silently fail.
3274                if (mAppErrors.isBadProcessLocked(info)) {
3275                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3276                            + "/" + info.processName);
3277                    return null;
3278                }
3279            } else {
3280                // When the user is explicitly starting a process, then clear its
3281                // crash count so that we won't make it bad until they see at
3282                // least one crash dialog again, and make the process good again
3283                // if it had been bad.
3284                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3285                        + "/" + info.processName);
3286                mAppErrors.resetProcessCrashTimeLocked(info);
3287                if (mAppErrors.isBadProcessLocked(info)) {
3288                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3289                            UserHandle.getUserId(info.uid), info.uid,
3290                            info.processName);
3291                    mAppErrors.clearBadProcessLocked(info);
3292                    if (app != null) {
3293                        app.bad = false;
3294                    }
3295                }
3296            }
3297        } else {
3298            // If this is an isolated process, it can't re-use an existing process.
3299            app = null;
3300        }
3301
3302        // app launch boost for big.little configurations
3303        // use cpusets to migrate freshly launched tasks to big cores
3304        synchronized(ActivityManagerService.this) {
3305            nativeMigrateToBoost();
3306            mIsBoosted = true;
3307            mBoostStartTime = SystemClock.uptimeMillis();
3308            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3309            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3310        }
3311
3312        // We don't have to do anything more if:
3313        // (1) There is an existing application record; and
3314        // (2) The caller doesn't think it is dead, OR there is no thread
3315        //     object attached to it so we know it couldn't have crashed; and
3316        // (3) There is a pid assigned to it, so it is either starting or
3317        //     already running.
3318        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3319                + " app=" + app + " knownToBeDead=" + knownToBeDead
3320                + " thread=" + (app != null ? app.thread : null)
3321                + " pid=" + (app != null ? app.pid : -1));
3322        if (app != null && app.pid > 0) {
3323            if (!knownToBeDead || app.thread == null) {
3324                // We already have the app running, or are waiting for it to
3325                // come up (we have a pid but not yet its thread), so keep it.
3326                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3327                // If this is a new package in the process, add the package to the list
3328                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3329                checkTime(startTime, "startProcess: done, added package to proc");
3330                return app;
3331            }
3332
3333            // An application record is attached to a previous process,
3334            // clean it up now.
3335            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3336            checkTime(startTime, "startProcess: bad proc running, killing");
3337            killProcessGroup(app.info.uid, app.pid);
3338            handleAppDiedLocked(app, true, true);
3339            checkTime(startTime, "startProcess: done killing old proc");
3340        }
3341
3342        String hostingNameStr = hostingName != null
3343                ? hostingName.flattenToShortString() : null;
3344
3345        if (app == null) {
3346            checkTime(startTime, "startProcess: creating new process record");
3347            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3348            if (app == null) {
3349                Slog.w(TAG, "Failed making new process record for "
3350                        + processName + "/" + info.uid + " isolated=" + isolated);
3351                return null;
3352            }
3353            app.crashHandler = crashHandler;
3354            checkTime(startTime, "startProcess: done creating new process record");
3355        } else {
3356            // If this is a new package in the process, add the package to the list
3357            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3358            checkTime(startTime, "startProcess: added package to existing proc");
3359        }
3360
3361        // If the system is not ready yet, then hold off on starting this
3362        // process until it is.
3363        if (!mProcessesReady
3364                && !isAllowedWhileBooting(info)
3365                && !allowWhileBooting) {
3366            if (!mProcessesOnHold.contains(app)) {
3367                mProcessesOnHold.add(app);
3368            }
3369            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3370                    "System not ready, putting on hold: " + app);
3371            checkTime(startTime, "startProcess: returning with proc on hold");
3372            return app;
3373        }
3374
3375        checkTime(startTime, "startProcess: stepping in to startProcess");
3376        startProcessLocked(
3377                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3378        checkTime(startTime, "startProcess: done starting proc!");
3379        return (app.pid != 0) ? app : null;
3380    }
3381
3382    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3383        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3384    }
3385
3386    private final void startProcessLocked(ProcessRecord app,
3387            String hostingType, String hostingNameStr) {
3388        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3389                null /* entryPoint */, null /* entryPointArgs */);
3390    }
3391
3392    private final void startProcessLocked(ProcessRecord app, String hostingType,
3393            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3394        long startTime = SystemClock.elapsedRealtime();
3395        if (app.pid > 0 && app.pid != MY_PID) {
3396            checkTime(startTime, "startProcess: removing from pids map");
3397            synchronized (mPidsSelfLocked) {
3398                mPidsSelfLocked.remove(app.pid);
3399                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3400            }
3401            checkTime(startTime, "startProcess: done removing from pids map");
3402            app.setPid(0);
3403        }
3404
3405        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3406                "startProcessLocked removing on hold: " + app);
3407        mProcessesOnHold.remove(app);
3408
3409        checkTime(startTime, "startProcess: starting to update cpu stats");
3410        updateCpuStats();
3411        checkTime(startTime, "startProcess: done updating cpu stats");
3412
3413        try {
3414            try {
3415                final int userId = UserHandle.getUserId(app.uid);
3416                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3417            } catch (RemoteException e) {
3418                throw e.rethrowAsRuntimeException();
3419            }
3420
3421            int uid = app.uid;
3422            int[] gids = null;
3423            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3424            if (!app.isolated) {
3425                int[] permGids = null;
3426                try {
3427                    checkTime(startTime, "startProcess: getting gids from package manager");
3428                    final IPackageManager pm = AppGlobals.getPackageManager();
3429                    permGids = pm.getPackageGids(app.info.packageName,
3430                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3431                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3432                            MountServiceInternal.class);
3433                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3434                            app.info.packageName);
3435                } catch (RemoteException e) {
3436                    throw e.rethrowAsRuntimeException();
3437                }
3438
3439                /*
3440                 * Add shared application and profile GIDs so applications can share some
3441                 * resources like shared libraries and access user-wide resources
3442                 */
3443                if (ArrayUtils.isEmpty(permGids)) {
3444                    gids = new int[2];
3445                } else {
3446                    gids = new int[permGids.length + 2];
3447                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3448                }
3449                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3450                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3451            }
3452            checkTime(startTime, "startProcess: building args");
3453            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3454                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3455                        && mTopComponent != null
3456                        && app.processName.equals(mTopComponent.getPackageName())) {
3457                    uid = 0;
3458                }
3459                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3460                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3461                    uid = 0;
3462                }
3463            }
3464            int debugFlags = 0;
3465            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3466                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3467                // Also turn on CheckJNI for debuggable apps. It's quite
3468                // awkward to turn on otherwise.
3469                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3470            }
3471            // Run the app in safe mode if its manifest requests so or the
3472            // system is booted in safe mode.
3473            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3474                mSafeMode == true) {
3475                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3476            }
3477            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3478                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3479            }
3480            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3481            if ("true".equals(genDebugInfoProperty)) {
3482                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3483            }
3484            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3485                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3486            }
3487            if ("1".equals(SystemProperties.get("debug.assert"))) {
3488                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3489            }
3490            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3491                // Enable all debug flags required by the native debugger.
3492                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3493                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3494                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3495                mNativeDebuggingApp = null;
3496            }
3497
3498            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3499            if (requiredAbi == null) {
3500                requiredAbi = Build.SUPPORTED_ABIS[0];
3501            }
3502
3503            String instructionSet = null;
3504            if (app.info.primaryCpuAbi != null) {
3505                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3506            }
3507
3508            app.gids = gids;
3509            app.requiredAbi = requiredAbi;
3510            app.instructionSet = instructionSet;
3511
3512            // Start the process.  It will either succeed and return a result containing
3513            // the PID of the new process, or else throw a RuntimeException.
3514            boolean isActivityProcess = (entryPoint == null);
3515            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3516            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3517                    app.processName);
3518            checkTime(startTime, "startProcess: asking zygote to start proc");
3519            Process.ProcessStartResult startResult = Process.start(entryPoint,
3520                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3521                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3522                    app.info.dataDir, entryPointArgs);
3523            checkTime(startTime, "startProcess: returned from zygote!");
3524            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3525
3526            if (app.isolated) {
3527                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3528            }
3529            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3530            checkTime(startTime, "startProcess: done updating battery stats");
3531
3532            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3533                    UserHandle.getUserId(uid), startResult.pid, uid,
3534                    app.processName, hostingType,
3535                    hostingNameStr != null ? hostingNameStr : "");
3536
3537            mProcessStartLogger.logIfNeededLocked(app, startResult);
3538
3539            if (app.persistent) {
3540                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3541            }
3542
3543            if (DEBUG_PROCESSES) {
3544                checkTime(startTime, "startProcess: building log message");
3545                StringBuilder buf = mStringBuilder;
3546                buf.setLength(0);
3547                buf.append("Start proc ");
3548                buf.append(startResult.pid);
3549                buf.append(':');
3550                buf.append(app.processName);
3551                buf.append('/');
3552                UserHandle.formatUid(buf, uid);
3553                if (!isActivityProcess) {
3554                    buf.append(" [");
3555                    buf.append(entryPoint);
3556                    buf.append("]");
3557                }
3558                buf.append(" for ");
3559                buf.append(hostingType);
3560                if (hostingNameStr != null) {
3561                    buf.append(" ");
3562                    buf.append(hostingNameStr);
3563                }
3564                Slog.i(TAG, buf.toString());
3565            }
3566            app.setPid(startResult.pid);
3567            app.usingWrapper = startResult.usingWrapper;
3568            app.removed = false;
3569            app.killed = false;
3570            app.killedByAm = false;
3571            checkTime(startTime, "startProcess: starting to update pids map");
3572            synchronized (mPidsSelfLocked) {
3573                this.mPidsSelfLocked.put(startResult.pid, app);
3574                if (isActivityProcess) {
3575                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3576                    msg.obj = app;
3577                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3578                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3579                }
3580            }
3581            checkTime(startTime, "startProcess: done updating pids map");
3582        } catch (RuntimeException e) {
3583            // XXX do better error recovery.
3584            app.setPid(0);
3585            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3586            if (app.isolated) {
3587                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3588            }
3589            Slog.e(TAG, "Failure starting process " + app.processName, e);
3590        }
3591    }
3592
3593    void updateUsageStats(ActivityRecord component, boolean resumed) {
3594        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3595                "updateUsageStats: comp=" + component + "res=" + resumed);
3596        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3597        if (resumed) {
3598            if (mUsageStatsService != null) {
3599                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3600                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3601            }
3602            synchronized (stats) {
3603                stats.noteActivityResumedLocked(component.app.uid);
3604            }
3605        } else {
3606            if (mUsageStatsService != null) {
3607                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3608                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3609            }
3610            synchronized (stats) {
3611                stats.noteActivityPausedLocked(component.app.uid);
3612            }
3613        }
3614    }
3615
3616    Intent getHomeIntent() {
3617        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3618        intent.setComponent(mTopComponent);
3619        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3620        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3621            intent.addCategory(Intent.CATEGORY_HOME);
3622        }
3623        return intent;
3624    }
3625
3626    boolean startHomeActivityLocked(int userId, String reason) {
3627        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3628                && mTopAction == null) {
3629            // We are running in factory test mode, but unable to find
3630            // the factory test app, so just sit around displaying the
3631            // error message and don't try to start anything.
3632            return false;
3633        }
3634        Intent intent = getHomeIntent();
3635        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3636        if (aInfo != null) {
3637            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3638            // Don't do this if the home app is currently being
3639            // instrumented.
3640            aInfo = new ActivityInfo(aInfo);
3641            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3642            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3643                    aInfo.applicationInfo.uid, true);
3644            if (app == null || app.instrumentationClass == null) {
3645                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3646                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3647            }
3648        }
3649
3650        return true;
3651    }
3652
3653    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3654        ActivityInfo ai = null;
3655        ComponentName comp = intent.getComponent();
3656        try {
3657            if (comp != null) {
3658                // Factory test.
3659                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3660            } else {
3661                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3662                        intent,
3663                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3664                        flags, userId);
3665
3666                if (info != null) {
3667                    ai = info.activityInfo;
3668                }
3669            }
3670        } catch (RemoteException e) {
3671            // ignore
3672        }
3673
3674        return ai;
3675    }
3676
3677    /**
3678     * Starts the "new version setup screen" if appropriate.
3679     */
3680    void startSetupActivityLocked() {
3681        // Only do this once per boot.
3682        if (mCheckedForSetup) {
3683            return;
3684        }
3685
3686        // We will show this screen if the current one is a different
3687        // version than the last one shown, and we are not running in
3688        // low-level factory test mode.
3689        final ContentResolver resolver = mContext.getContentResolver();
3690        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3691                Settings.Global.getInt(resolver,
3692                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3693            mCheckedForSetup = true;
3694
3695            // See if we should be showing the platform update setup UI.
3696            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3697            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3698                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3699            if (!ris.isEmpty()) {
3700                final ResolveInfo ri = ris.get(0);
3701                String vers = ri.activityInfo.metaData != null
3702                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3703                        : null;
3704                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3705                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3706                            Intent.METADATA_SETUP_VERSION);
3707                }
3708                String lastVers = Settings.Secure.getString(
3709                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3710                if (vers != null && !vers.equals(lastVers)) {
3711                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3712                    intent.setComponent(new ComponentName(
3713                            ri.activityInfo.packageName, ri.activityInfo.name));
3714                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3715                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3716                            null, 0, 0, 0, null, false, false, null, null, null);
3717                }
3718            }
3719        }
3720    }
3721
3722    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3723        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3724    }
3725
3726    void enforceNotIsolatedCaller(String caller) {
3727        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3728            throw new SecurityException("Isolated process not allowed to call " + caller);
3729        }
3730    }
3731
3732    void enforceShellRestriction(String restriction, int userHandle) {
3733        if (Binder.getCallingUid() == Process.SHELL_UID) {
3734            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3735                throw new SecurityException("Shell does not have permission to access user "
3736                        + userHandle);
3737            }
3738        }
3739    }
3740
3741    @Override
3742    public int getFrontActivityScreenCompatMode() {
3743        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3744        synchronized (this) {
3745            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3746        }
3747    }
3748
3749    @Override
3750    public void setFrontActivityScreenCompatMode(int mode) {
3751        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3752                "setFrontActivityScreenCompatMode");
3753        synchronized (this) {
3754            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3755        }
3756    }
3757
3758    @Override
3759    public int getPackageScreenCompatMode(String packageName) {
3760        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3761        synchronized (this) {
3762            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3763        }
3764    }
3765
3766    @Override
3767    public void setPackageScreenCompatMode(String packageName, int mode) {
3768        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3769                "setPackageScreenCompatMode");
3770        synchronized (this) {
3771            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3772        }
3773    }
3774
3775    @Override
3776    public boolean getPackageAskScreenCompat(String packageName) {
3777        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3778        synchronized (this) {
3779            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3780        }
3781    }
3782
3783    @Override
3784    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3785        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3786                "setPackageAskScreenCompat");
3787        synchronized (this) {
3788            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3789        }
3790    }
3791
3792    private boolean hasUsageStatsPermission(String callingPackage) {
3793        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3794                Binder.getCallingUid(), callingPackage);
3795        if (mode == AppOpsManager.MODE_DEFAULT) {
3796            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3797                    == PackageManager.PERMISSION_GRANTED;
3798        }
3799        return mode == AppOpsManager.MODE_ALLOWED;
3800    }
3801
3802    @Override
3803    public int getPackageProcessState(String packageName, String callingPackage) {
3804        if (!hasUsageStatsPermission(callingPackage)) {
3805            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3806                    "getPackageProcessState");
3807        }
3808
3809        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3810        synchronized (this) {
3811            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3812                final ProcessRecord proc = mLruProcesses.get(i);
3813                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3814                        || procState > proc.setProcState) {
3815                    boolean found = false;
3816                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3817                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3818                            procState = proc.setProcState;
3819                            found = true;
3820                        }
3821                    }
3822                    if (proc.pkgDeps != null && !found) {
3823                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3824                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3825                                procState = proc.setProcState;
3826                                break;
3827                            }
3828                        }
3829                    }
3830                }
3831            }
3832        }
3833        return procState;
3834    }
3835
3836    @Override
3837    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3838        synchronized (this) {
3839            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3840            if (app == null) {
3841                return false;
3842            }
3843            if (app.trimMemoryLevel < level && app.thread != null &&
3844                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3845                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3846                try {
3847                    app.thread.scheduleTrimMemory(level);
3848                    app.trimMemoryLevel = level;
3849                    return true;
3850                } catch (RemoteException e) {
3851                    // Fallthrough to failure case.
3852                }
3853            }
3854        }
3855        return false;
3856    }
3857
3858    private void dispatchProcessesChanged() {
3859        int N;
3860        synchronized (this) {
3861            N = mPendingProcessChanges.size();
3862            if (mActiveProcessChanges.length < N) {
3863                mActiveProcessChanges = new ProcessChangeItem[N];
3864            }
3865            mPendingProcessChanges.toArray(mActiveProcessChanges);
3866            mPendingProcessChanges.clear();
3867            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3868                    "*** Delivering " + N + " process changes");
3869        }
3870
3871        int i = mProcessObservers.beginBroadcast();
3872        while (i > 0) {
3873            i--;
3874            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3875            if (observer != null) {
3876                try {
3877                    for (int j=0; j<N; j++) {
3878                        ProcessChangeItem item = mActiveProcessChanges[j];
3879                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3880                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3881                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3882                                    + item.uid + ": " + item.foregroundActivities);
3883                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3884                                    item.foregroundActivities);
3885                        }
3886                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3887                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3888                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3889                                    + ": " + item.processState);
3890                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3891                        }
3892                    }
3893                } catch (RemoteException e) {
3894                }
3895            }
3896        }
3897        mProcessObservers.finishBroadcast();
3898
3899        synchronized (this) {
3900            for (int j=0; j<N; j++) {
3901                mAvailProcessChanges.add(mActiveProcessChanges[j]);
3902            }
3903        }
3904    }
3905
3906    private void dispatchProcessDied(int pid, int uid) {
3907        int i = mProcessObservers.beginBroadcast();
3908        while (i > 0) {
3909            i--;
3910            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3911            if (observer != null) {
3912                try {
3913                    observer.onProcessDied(pid, uid);
3914                } catch (RemoteException e) {
3915                }
3916            }
3917        }
3918        mProcessObservers.finishBroadcast();
3919    }
3920
3921    private void dispatchUidsChanged() {
3922        int N;
3923        synchronized (this) {
3924            N = mPendingUidChanges.size();
3925            if (mActiveUidChanges.length < N) {
3926                mActiveUidChanges = new UidRecord.ChangeItem[N];
3927            }
3928            for (int i=0; i<N; i++) {
3929                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3930                mActiveUidChanges[i] = change;
3931                if (change.uidRecord != null) {
3932                    change.uidRecord.pendingChange = null;
3933                    change.uidRecord = null;
3934                }
3935            }
3936            mPendingUidChanges.clear();
3937            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3938                    "*** Delivering " + N + " uid changes");
3939        }
3940
3941        if (mLocalPowerManager != null) {
3942            for (int j=0; j<N; j++) {
3943                UidRecord.ChangeItem item = mActiveUidChanges[j];
3944                if (item.change == UidRecord.CHANGE_GONE
3945                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
3946                    mLocalPowerManager.uidGone(item.uid);
3947                } else {
3948                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3949                }
3950            }
3951        }
3952
3953        int i = mUidObservers.beginBroadcast();
3954        while (i > 0) {
3955            i--;
3956            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3957            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3958            if (observer != null) {
3959                try {
3960                    for (int j=0; j<N; j++) {
3961                        UidRecord.ChangeItem item = mActiveUidChanges[j];
3962                        final int change = item.change;
3963                        UidRecord validateUid = null;
3964                        if (VALIDATE_UID_STATES && i == 0) {
3965                            validateUid = mValidateUids.get(item.uid);
3966                            if (validateUid == null && change != UidRecord.CHANGE_GONE
3967                                    && change != UidRecord.CHANGE_GONE_IDLE) {
3968                                validateUid = new UidRecord(item.uid);
3969                                mValidateUids.put(item.uid, validateUid);
3970                            }
3971                        }
3972                        if (change == UidRecord.CHANGE_IDLE
3973                                || change == UidRecord.CHANGE_GONE_IDLE) {
3974                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
3975                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3976                                        "UID idle uid=" + item.uid);
3977                                observer.onUidIdle(item.uid);
3978                            }
3979                            if (VALIDATE_UID_STATES && i == 0) {
3980                                if (validateUid != null) {
3981                                    validateUid.idle = true;
3982                                }
3983                            }
3984                        } else if (change == UidRecord.CHANGE_ACTIVE) {
3985                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
3986                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3987                                        "UID active uid=" + item.uid);
3988                                observer.onUidActive(item.uid);
3989                            }
3990                            if (VALIDATE_UID_STATES && i == 0) {
3991                                validateUid.idle = false;
3992                            }
3993                        }
3994                        if (change == UidRecord.CHANGE_GONE
3995                                || change == UidRecord.CHANGE_GONE_IDLE) {
3996                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
3997                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3998                                        "UID gone uid=" + item.uid);
3999                                observer.onUidGone(item.uid);
4000                            }
4001                            if (VALIDATE_UID_STATES && i == 0) {
4002                                if (validateUid != null) {
4003                                    mValidateUids.remove(item.uid);
4004                                }
4005                            }
4006                        } else {
4007                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4008                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4009                                        "UID CHANGED uid=" + item.uid
4010                                                + ": " + item.processState);
4011                                observer.onUidStateChanged(item.uid, item.processState);
4012                            }
4013                            if (VALIDATE_UID_STATES && i == 0) {
4014                                validateUid.curProcState = validateUid.setProcState
4015                                        = item.processState;
4016                            }
4017                        }
4018                    }
4019                } catch (RemoteException e) {
4020                }
4021            }
4022        }
4023        mUidObservers.finishBroadcast();
4024
4025        synchronized (this) {
4026            for (int j=0; j<N; j++) {
4027                mAvailUidChanges.add(mActiveUidChanges[j]);
4028            }
4029        }
4030    }
4031
4032    @Override
4033    public final int startActivity(IApplicationThread caller, String callingPackage,
4034            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4035            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4036        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4037                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4038                UserHandle.getCallingUserId());
4039    }
4040
4041    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4042        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4043        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4044                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4045                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4046
4047        // TODO: Switch to user app stacks here.
4048        String mimeType = intent.getType();
4049        final Uri data = intent.getData();
4050        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4051            mimeType = getProviderMimeType(data, userId);
4052        }
4053        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4054
4055        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4056        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4057                null, 0, 0, null, null, null, null, false, userId, container, null);
4058    }
4059
4060    @Override
4061    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4062            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4063            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4064        enforceNotIsolatedCaller("startActivity");
4065        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4066                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4067        // TODO: Switch to user app stacks here.
4068        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4069                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4070                profilerInfo, null, null, bOptions, false, userId, null, null);
4071    }
4072
4073    @Override
4074    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4075            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4076            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4077            int userId) {
4078
4079        // This is very dangerous -- it allows you to perform a start activity (including
4080        // permission grants) as any app that may launch one of your own activities.  So
4081        // we will only allow this to be done from activities that are part of the core framework,
4082        // and then only when they are running as the system.
4083        final ActivityRecord sourceRecord;
4084        final int targetUid;
4085        final String targetPackage;
4086        synchronized (this) {
4087            if (resultTo == null) {
4088                throw new SecurityException("Must be called from an activity");
4089            }
4090            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4091            if (sourceRecord == null) {
4092                throw new SecurityException("Called with bad activity token: " + resultTo);
4093            }
4094            if (!sourceRecord.info.packageName.equals("android")) {
4095                throw new SecurityException(
4096                        "Must be called from an activity that is declared in the android package");
4097            }
4098            if (sourceRecord.app == null) {
4099                throw new SecurityException("Called without a process attached to activity");
4100            }
4101            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4102                // This is still okay, as long as this activity is running under the
4103                // uid of the original calling activity.
4104                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4105                    throw new SecurityException(
4106                            "Calling activity in uid " + sourceRecord.app.uid
4107                                    + " must be system uid or original calling uid "
4108                                    + sourceRecord.launchedFromUid);
4109                }
4110            }
4111            if (ignoreTargetSecurity) {
4112                if (intent.getComponent() == null) {
4113                    throw new SecurityException(
4114                            "Component must be specified with ignoreTargetSecurity");
4115                }
4116                if (intent.getSelector() != null) {
4117                    throw new SecurityException(
4118                            "Selector not allowed with ignoreTargetSecurity");
4119                }
4120            }
4121            targetUid = sourceRecord.launchedFromUid;
4122            targetPackage = sourceRecord.launchedFromPackage;
4123        }
4124
4125        if (userId == UserHandle.USER_NULL) {
4126            userId = UserHandle.getUserId(sourceRecord.app.uid);
4127        }
4128
4129        // TODO: Switch to user app stacks here.
4130        try {
4131            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4132                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4133                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4134            return ret;
4135        } catch (SecurityException e) {
4136            // XXX need to figure out how to propagate to original app.
4137            // A SecurityException here is generally actually a fault of the original
4138            // calling activity (such as a fairly granting permissions), so propagate it
4139            // back to them.
4140            /*
4141            StringBuilder msg = new StringBuilder();
4142            msg.append("While launching");
4143            msg.append(intent.toString());
4144            msg.append(": ");
4145            msg.append(e.getMessage());
4146            */
4147            throw e;
4148        }
4149    }
4150
4151    @Override
4152    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4153            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4154            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4155        enforceNotIsolatedCaller("startActivityAndWait");
4156        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4157                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4158        WaitResult res = new WaitResult();
4159        // TODO: Switch to user app stacks here.
4160        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4161                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4162                bOptions, false, userId, null, null);
4163        return res;
4164    }
4165
4166    @Override
4167    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4168            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4169            int startFlags, Configuration config, Bundle bOptions, int userId) {
4170        enforceNotIsolatedCaller("startActivityWithConfig");
4171        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4172                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4173        // TODO: Switch to user app stacks here.
4174        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4175                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4176                null, null, config, bOptions, false, userId, null, null);
4177        return ret;
4178    }
4179
4180    @Override
4181    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4182            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4183            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4184            throws TransactionTooLargeException {
4185        enforceNotIsolatedCaller("startActivityIntentSender");
4186        // Refuse possible leaked file descriptors
4187        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4188            throw new IllegalArgumentException("File descriptors passed in Intent");
4189        }
4190
4191        IIntentSender sender = intent.getTarget();
4192        if (!(sender instanceof PendingIntentRecord)) {
4193            throw new IllegalArgumentException("Bad PendingIntent object");
4194        }
4195
4196        PendingIntentRecord pir = (PendingIntentRecord)sender;
4197
4198        synchronized (this) {
4199            // If this is coming from the currently resumed activity, it is
4200            // effectively saying that app switches are allowed at this point.
4201            final ActivityStack stack = getFocusedStack();
4202            if (stack.mResumedActivity != null &&
4203                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4204                mAppSwitchesAllowedTime = 0;
4205            }
4206        }
4207        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4208                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4209        return ret;
4210    }
4211
4212    @Override
4213    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4214            Intent intent, String resolvedType, IVoiceInteractionSession session,
4215            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4216            Bundle bOptions, int userId) {
4217        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4218                != PackageManager.PERMISSION_GRANTED) {
4219            String msg = "Permission Denial: startVoiceActivity() from pid="
4220                    + Binder.getCallingPid()
4221                    + ", uid=" + Binder.getCallingUid()
4222                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4223            Slog.w(TAG, msg);
4224            throw new SecurityException(msg);
4225        }
4226        if (session == null || interactor == null) {
4227            throw new NullPointerException("null session or interactor");
4228        }
4229        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4230                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4231        // TODO: Switch to user app stacks here.
4232        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4233                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4234                null, bOptions, false, userId, null, null);
4235    }
4236
4237    @Override
4238    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4239            throws RemoteException {
4240        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4241        synchronized (this) {
4242            ActivityRecord activity = getFocusedStack().topActivity();
4243            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4244                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4245            }
4246            if (mRunningVoice != null || activity.task.voiceSession != null
4247                    || activity.voiceSession != null) {
4248                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4249                return;
4250            }
4251            if (activity.pendingVoiceInteractionStart) {
4252                Slog.w(TAG, "Pending start of voice interaction already.");
4253                return;
4254            }
4255            activity.pendingVoiceInteractionStart = true;
4256        }
4257        LocalServices.getService(VoiceInteractionManagerInternal.class)
4258                .startLocalVoiceInteraction(callingActivity, options);
4259    }
4260
4261    @Override
4262    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4263        LocalServices.getService(VoiceInteractionManagerInternal.class)
4264                .stopLocalVoiceInteraction(callingActivity);
4265    }
4266
4267    @Override
4268    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4269        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4270                .supportsLocalVoiceInteraction();
4271    }
4272
4273    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4274            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4275        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4276        if (activityToCallback == null) return;
4277        activityToCallback.setVoiceSessionLocked(voiceSession);
4278
4279        // Inform the activity
4280        try {
4281            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4282                    voiceInteractor);
4283            long token = Binder.clearCallingIdentity();
4284            try {
4285                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4286            } finally {
4287                Binder.restoreCallingIdentity(token);
4288            }
4289            // TODO: VI Should we cache the activity so that it's easier to find later
4290            // rather than scan through all the stacks and activities?
4291        } catch (RemoteException re) {
4292            activityToCallback.clearVoiceSessionLocked();
4293            // TODO: VI Should this terminate the voice session?
4294        }
4295    }
4296
4297    @Override
4298    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4299        synchronized (this) {
4300            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4301                if (keepAwake) {
4302                    mVoiceWakeLock.acquire();
4303                } else {
4304                    mVoiceWakeLock.release();
4305                }
4306            }
4307        }
4308    }
4309
4310    @Override
4311    public boolean startNextMatchingActivity(IBinder callingActivity,
4312            Intent intent, Bundle bOptions) {
4313        // Refuse possible leaked file descriptors
4314        if (intent != null && intent.hasFileDescriptors() == true) {
4315            throw new IllegalArgumentException("File descriptors passed in Intent");
4316        }
4317        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4318
4319        synchronized (this) {
4320            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4321            if (r == null) {
4322                ActivityOptions.abort(options);
4323                return false;
4324            }
4325            if (r.app == null || r.app.thread == null) {
4326                // The caller is not running...  d'oh!
4327                ActivityOptions.abort(options);
4328                return false;
4329            }
4330            intent = new Intent(intent);
4331            // The caller is not allowed to change the data.
4332            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4333            // And we are resetting to find the next component...
4334            intent.setComponent(null);
4335
4336            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4337
4338            ActivityInfo aInfo = null;
4339            try {
4340                List<ResolveInfo> resolves =
4341                    AppGlobals.getPackageManager().queryIntentActivities(
4342                            intent, r.resolvedType,
4343                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4344                            UserHandle.getCallingUserId());
4345
4346                // Look for the original activity in the list...
4347                final int N = resolves != null ? resolves.size() : 0;
4348                for (int i=0; i<N; i++) {
4349                    ResolveInfo rInfo = resolves.get(i);
4350                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4351                            && rInfo.activityInfo.name.equals(r.info.name)) {
4352                        // We found the current one...  the next matching is
4353                        // after it.
4354                        i++;
4355                        if (i<N) {
4356                            aInfo = resolves.get(i).activityInfo;
4357                        }
4358                        if (debug) {
4359                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4360                                    + "/" + r.info.name);
4361                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4362                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4363                        }
4364                        break;
4365                    }
4366                }
4367            } catch (RemoteException e) {
4368            }
4369
4370            if (aInfo == null) {
4371                // Nobody who is next!
4372                ActivityOptions.abort(options);
4373                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4374                return false;
4375            }
4376
4377            intent.setComponent(new ComponentName(
4378                    aInfo.applicationInfo.packageName, aInfo.name));
4379            intent.setFlags(intent.getFlags()&~(
4380                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4381                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4382                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4383                    Intent.FLAG_ACTIVITY_NEW_TASK));
4384
4385            // Okay now we need to start the new activity, replacing the
4386            // currently running activity.  This is a little tricky because
4387            // we want to start the new one as if the current one is finished,
4388            // but not finish the current one first so that there is no flicker.
4389            // And thus...
4390            final boolean wasFinishing = r.finishing;
4391            r.finishing = true;
4392
4393            // Propagate reply information over to the new activity.
4394            final ActivityRecord resultTo = r.resultTo;
4395            final String resultWho = r.resultWho;
4396            final int requestCode = r.requestCode;
4397            r.resultTo = null;
4398            if (resultTo != null) {
4399                resultTo.removeResultsLocked(r, resultWho, requestCode);
4400            }
4401
4402            final long origId = Binder.clearCallingIdentity();
4403            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4404                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4405                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4406                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4407                    false, false, null, null, null);
4408            Binder.restoreCallingIdentity(origId);
4409
4410            r.finishing = wasFinishing;
4411            if (res != ActivityManager.START_SUCCESS) {
4412                return false;
4413            }
4414            return true;
4415        }
4416    }
4417
4418    @Override
4419    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4420        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4421            String msg = "Permission Denial: startActivityFromRecents called without " +
4422                    START_TASKS_FROM_RECENTS;
4423            Slog.w(TAG, msg);
4424            throw new SecurityException(msg);
4425        }
4426        final long origId = Binder.clearCallingIdentity();
4427        try {
4428            return startActivityFromRecentsInner(taskId, bOptions);
4429        } finally {
4430            Binder.restoreCallingIdentity(origId);
4431        }
4432    }
4433
4434    final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4435        final TaskRecord task;
4436        final int callingUid;
4437        final String callingPackage;
4438        final Intent intent;
4439        final int userId;
4440        synchronized (this) {
4441            final ActivityOptions activityOptions = (bOptions != null)
4442                    ? new ActivityOptions(bOptions) : null;
4443            final int launchStackId = (activityOptions != null)
4444                    ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4445
4446            if (launchStackId == HOME_STACK_ID) {
4447                throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4448                        + taskId + " can't be launch in the home stack.");
4449            }
4450            task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4451            if (task == null) {
4452                throw new IllegalArgumentException(
4453                        "startActivityFromRecentsInner: Task " + taskId + " not found.");
4454            }
4455
4456            if (launchStackId != INVALID_STACK_ID) {
4457                if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
4458                    mWindowManager.setDockedStackCreateState(
4459                            activityOptions.getDockCreateMode(), null /* initialBounds */);
4460                }
4461                if (task.stack.mStackId != launchStackId) {
4462                    mStackSupervisor.moveTaskToStackLocked(
4463                            taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4464                            ANIMATE);
4465                }
4466            }
4467
4468            // If the user must confirm credentials (e.g. when first launching a work app and the
4469            // Work Challenge is present) let startActivityInPackage handle the intercepting.
4470            if (!mUserController.shouldConfirmCredentials(task.userId)
4471                    && task.getRootActivity() != null) {
4472                moveTaskToFrontLocked(task.taskId, 0, bOptions);
4473                return ActivityManager.START_TASK_TO_FRONT;
4474            }
4475            callingUid = task.mCallingUid;
4476            callingPackage = task.mCallingPackage;
4477            intent = task.intent;
4478            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4479            userId = task.userId;
4480        }
4481        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4482                bOptions, userId, null, task);
4483    }
4484
4485    final int startActivityInPackage(int uid, String callingPackage,
4486            Intent intent, String resolvedType, IBinder resultTo,
4487            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4488            IActivityContainer container, TaskRecord inTask) {
4489
4490        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4491                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4492
4493        // TODO: Switch to user app stacks here.
4494        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4495                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4496                null, null, null, bOptions, false, userId, container, inTask);
4497        return ret;
4498    }
4499
4500    @Override
4501    public final int startActivities(IApplicationThread caller, String callingPackage,
4502            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4503            int userId) {
4504        enforceNotIsolatedCaller("startActivities");
4505        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4506                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4507        // TODO: Switch to user app stacks here.
4508        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4509                resolvedTypes, resultTo, bOptions, userId);
4510        return ret;
4511    }
4512
4513    final int startActivitiesInPackage(int uid, String callingPackage,
4514            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4515            Bundle bOptions, int userId) {
4516
4517        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4518                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4519        // TODO: Switch to user app stacks here.
4520        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4521                resultTo, bOptions, userId);
4522        return ret;
4523    }
4524
4525    @Override
4526    public void reportActivityFullyDrawn(IBinder token) {
4527        synchronized (this) {
4528            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4529            if (r == null) {
4530                return;
4531            }
4532            r.reportFullyDrawnLocked();
4533        }
4534    }
4535
4536    @Override
4537    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4538        synchronized (this) {
4539            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4540            if (r == null) {
4541                return;
4542            }
4543            TaskRecord task = r.task;
4544            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4545                // Fixed screen orientation isn't supported when activities aren't in full screen
4546                // mode.
4547                return;
4548            }
4549            final long origId = Binder.clearCallingIdentity();
4550            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4551            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4552                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4553            if (config != null) {
4554                r.frozenBeforeDestroy = true;
4555                if (!updateConfigurationLocked(config, r, false)) {
4556                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4557                }
4558            }
4559            Binder.restoreCallingIdentity(origId);
4560        }
4561    }
4562
4563    @Override
4564    public int getRequestedOrientation(IBinder token) {
4565        synchronized (this) {
4566            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4567            if (r == null) {
4568                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4569            }
4570            return mWindowManager.getAppOrientation(r.appToken);
4571        }
4572    }
4573
4574    /**
4575     * This is the internal entry point for handling Activity.finish().
4576     *
4577     * @param token The Binder token referencing the Activity we want to finish.
4578     * @param resultCode Result code, if any, from this Activity.
4579     * @param resultData Result data (Intent), if any, from this Activity.
4580     * @param finishTask Whether to finish the task associated with this Activity.
4581     *
4582     * @return Returns true if the activity successfully finished, or false if it is still running.
4583     */
4584    @Override
4585    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4586            int finishTask) {
4587        // Refuse possible leaked file descriptors
4588        if (resultData != null && resultData.hasFileDescriptors() == true) {
4589            throw new IllegalArgumentException("File descriptors passed in Intent");
4590        }
4591
4592        synchronized(this) {
4593            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4594            if (r == null) {
4595                return true;
4596            }
4597            // Keep track of the root activity of the task before we finish it
4598            TaskRecord tr = r.task;
4599            ActivityRecord rootR = tr.getRootActivity();
4600            if (rootR == null) {
4601                Slog.w(TAG, "Finishing task with all activities already finished");
4602            }
4603            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4604            // finish.
4605            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4606                    mStackSupervisor.isLastLockedTask(tr)) {
4607                Slog.i(TAG, "Not finishing task in lock task mode");
4608                mStackSupervisor.showLockTaskToast();
4609                return false;
4610            }
4611            if (mController != null) {
4612                // Find the first activity that is not finishing.
4613                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4614                if (next != null) {
4615                    // ask watcher if this is allowed
4616                    boolean resumeOK = true;
4617                    try {
4618                        resumeOK = mController.activityResuming(next.packageName);
4619                    } catch (RemoteException e) {
4620                        mController = null;
4621                        Watchdog.getInstance().setActivityController(null);
4622                    }
4623
4624                    if (!resumeOK) {
4625                        Slog.i(TAG, "Not finishing activity because controller resumed");
4626                        return false;
4627                    }
4628                }
4629            }
4630            final long origId = Binder.clearCallingIdentity();
4631            try {
4632                boolean res;
4633                final boolean finishWithRootActivity =
4634                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4635                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4636                        || (finishWithRootActivity && r == rootR)) {
4637                    // If requested, remove the task that is associated to this activity only if it
4638                    // was the root activity in the task. The result code and data is ignored
4639                    // because we don't support returning them across task boundaries. Also, to
4640                    // keep backwards compatibility we remove the task from recents when finishing
4641                    // task with root activity.
4642                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4643                    if (!res) {
4644                        Slog.i(TAG, "Removing task failed to finish activity");
4645                    }
4646                } else {
4647                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4648                            resultData, "app-request", true);
4649                    if (!res) {
4650                        Slog.i(TAG, "Failed to finish by app-request");
4651                    }
4652                }
4653                return res;
4654            } finally {
4655                Binder.restoreCallingIdentity(origId);
4656            }
4657        }
4658    }
4659
4660    @Override
4661    public final void finishHeavyWeightApp() {
4662        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4663                != PackageManager.PERMISSION_GRANTED) {
4664            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4665                    + Binder.getCallingPid()
4666                    + ", uid=" + Binder.getCallingUid()
4667                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4668            Slog.w(TAG, msg);
4669            throw new SecurityException(msg);
4670        }
4671
4672        synchronized(this) {
4673            if (mHeavyWeightProcess == null) {
4674                return;
4675            }
4676
4677            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4678            for (int i = 0; i < activities.size(); i++) {
4679                ActivityRecord r = activities.get(i);
4680                if (!r.finishing && r.isInStackLocked()) {
4681                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4682                            null, "finish-heavy", true);
4683                }
4684            }
4685
4686            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4687                    mHeavyWeightProcess.userId, 0));
4688            mHeavyWeightProcess = null;
4689        }
4690    }
4691
4692    @Override
4693    public void crashApplication(int uid, int initialPid, String packageName,
4694            String message) {
4695        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4696                != PackageManager.PERMISSION_GRANTED) {
4697            String msg = "Permission Denial: crashApplication() from pid="
4698                    + Binder.getCallingPid()
4699                    + ", uid=" + Binder.getCallingUid()
4700                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4701            Slog.w(TAG, msg);
4702            throw new SecurityException(msg);
4703        }
4704
4705        synchronized(this) {
4706            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4707        }
4708    }
4709
4710    @Override
4711    public final void finishSubActivity(IBinder token, String resultWho,
4712            int requestCode) {
4713        synchronized(this) {
4714            final long origId = Binder.clearCallingIdentity();
4715            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4716            if (r != null) {
4717                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4718            }
4719            Binder.restoreCallingIdentity(origId);
4720        }
4721    }
4722
4723    @Override
4724    public boolean finishActivityAffinity(IBinder token) {
4725        synchronized(this) {
4726            final long origId = Binder.clearCallingIdentity();
4727            try {
4728                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4729                if (r == null) {
4730                    return false;
4731                }
4732
4733                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4734                // can finish.
4735                final TaskRecord task = r.task;
4736                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4737                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4738                    mStackSupervisor.showLockTaskToast();
4739                    return false;
4740                }
4741                return task.stack.finishActivityAffinityLocked(r);
4742            } finally {
4743                Binder.restoreCallingIdentity(origId);
4744            }
4745        }
4746    }
4747
4748    @Override
4749    public void finishVoiceTask(IVoiceInteractionSession session) {
4750        synchronized (this) {
4751            final long origId = Binder.clearCallingIdentity();
4752            try {
4753                // TODO: VI Consider treating local voice interactions and voice tasks
4754                // differently here
4755                mStackSupervisor.finishVoiceTask(session);
4756            } finally {
4757                Binder.restoreCallingIdentity(origId);
4758            }
4759        }
4760
4761    }
4762
4763    @Override
4764    public boolean releaseActivityInstance(IBinder token) {
4765        synchronized(this) {
4766            final long origId = Binder.clearCallingIdentity();
4767            try {
4768                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4769                if (r == null) {
4770                    return false;
4771                }
4772                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4773            } finally {
4774                Binder.restoreCallingIdentity(origId);
4775            }
4776        }
4777    }
4778
4779    @Override
4780    public void releaseSomeActivities(IApplicationThread appInt) {
4781        synchronized(this) {
4782            final long origId = Binder.clearCallingIdentity();
4783            try {
4784                ProcessRecord app = getRecordForAppLocked(appInt);
4785                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4786            } finally {
4787                Binder.restoreCallingIdentity(origId);
4788            }
4789        }
4790    }
4791
4792    @Override
4793    public boolean willActivityBeVisible(IBinder token) {
4794        synchronized(this) {
4795            ActivityStack stack = ActivityRecord.getStackLocked(token);
4796            if (stack != null) {
4797                return stack.willActivityBeVisibleLocked(token);
4798            }
4799            return false;
4800        }
4801    }
4802
4803    @Override
4804    public void overridePendingTransition(IBinder token, String packageName,
4805            int enterAnim, int exitAnim) {
4806        synchronized(this) {
4807            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4808            if (self == null) {
4809                return;
4810            }
4811
4812            final long origId = Binder.clearCallingIdentity();
4813
4814            if (self.state == ActivityState.RESUMED
4815                    || self.state == ActivityState.PAUSING) {
4816                mWindowManager.overridePendingAppTransition(packageName,
4817                        enterAnim, exitAnim, null);
4818            }
4819
4820            Binder.restoreCallingIdentity(origId);
4821        }
4822    }
4823
4824    /**
4825     * Main function for removing an existing process from the activity manager
4826     * as a result of that process going away.  Clears out all connections
4827     * to the process.
4828     */
4829    private final void handleAppDiedLocked(ProcessRecord app,
4830            boolean restarting, boolean allowRestart) {
4831        int pid = app.pid;
4832        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4833        if (!kept && !restarting) {
4834            removeLruProcessLocked(app);
4835            if (pid > 0) {
4836                ProcessList.remove(pid);
4837            }
4838        }
4839
4840        if (mProfileProc == app) {
4841            clearProfilerLocked();
4842        }
4843
4844        // Remove this application's activities from active lists.
4845        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4846
4847        app.activities.clear();
4848
4849        if (app.instrumentationClass != null) {
4850            Slog.w(TAG, "Crash of app " + app.processName
4851                  + " running instrumentation " + app.instrumentationClass);
4852            Bundle info = new Bundle();
4853            info.putString("shortMsg", "Process crashed.");
4854            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4855        }
4856
4857        if (!restarting && hasVisibleActivities
4858                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4859            // If there was nothing to resume, and we are not already restarting this process, but
4860            // there is a visible activity that is hosted by the process...  then make sure all
4861            // visible activities are running, taking care of restarting this process.
4862            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4863        }
4864    }
4865
4866    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4867        IBinder threadBinder = thread.asBinder();
4868        // Find the application record.
4869        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4870            ProcessRecord rec = mLruProcesses.get(i);
4871            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4872                return i;
4873            }
4874        }
4875        return -1;
4876    }
4877
4878    final ProcessRecord getRecordForAppLocked(
4879            IApplicationThread thread) {
4880        if (thread == null) {
4881            return null;
4882        }
4883
4884        int appIndex = getLRURecordIndexForAppLocked(thread);
4885        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4886    }
4887
4888    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4889        // If there are no longer any background processes running,
4890        // and the app that died was not running instrumentation,
4891        // then tell everyone we are now low on memory.
4892        boolean haveBg = false;
4893        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4894            ProcessRecord rec = mLruProcesses.get(i);
4895            if (rec.thread != null
4896                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4897                haveBg = true;
4898                break;
4899            }
4900        }
4901
4902        if (!haveBg) {
4903            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4904            if (doReport) {
4905                long now = SystemClock.uptimeMillis();
4906                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4907                    doReport = false;
4908                } else {
4909                    mLastMemUsageReportTime = now;
4910                }
4911            }
4912            final ArrayList<ProcessMemInfo> memInfos
4913                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4914            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4915            long now = SystemClock.uptimeMillis();
4916            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4917                ProcessRecord rec = mLruProcesses.get(i);
4918                if (rec == dyingProc || rec.thread == null) {
4919                    continue;
4920                }
4921                if (doReport) {
4922                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4923                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4924                }
4925                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4926                    // The low memory report is overriding any current
4927                    // state for a GC request.  Make sure to do
4928                    // heavy/important/visible/foreground processes first.
4929                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4930                        rec.lastRequestedGc = 0;
4931                    } else {
4932                        rec.lastRequestedGc = rec.lastLowMemory;
4933                    }
4934                    rec.reportLowMemory = true;
4935                    rec.lastLowMemory = now;
4936                    mProcessesToGc.remove(rec);
4937                    addProcessToGcListLocked(rec);
4938                }
4939            }
4940            if (doReport) {
4941                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4942                mHandler.sendMessage(msg);
4943            }
4944            scheduleAppGcsLocked();
4945        }
4946    }
4947
4948    final void appDiedLocked(ProcessRecord app) {
4949       appDiedLocked(app, app.pid, app.thread, false);
4950    }
4951
4952    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4953            boolean fromBinderDied) {
4954        // First check if this ProcessRecord is actually active for the pid.
4955        synchronized (mPidsSelfLocked) {
4956            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4957            if (curProc != app) {
4958                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4959                return;
4960            }
4961        }
4962
4963        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4964        synchronized (stats) {
4965            stats.noteProcessDiedLocked(app.info.uid, pid);
4966        }
4967
4968        if (!app.killed) {
4969            if (!fromBinderDied) {
4970                Process.killProcessQuiet(pid);
4971            }
4972            killProcessGroup(app.info.uid, pid);
4973            app.killed = true;
4974        }
4975
4976        // Clean up already done if the process has been re-started.
4977        if (app.pid == pid && app.thread != null &&
4978                app.thread.asBinder() == thread.asBinder()) {
4979            boolean doLowMem = app.instrumentationClass == null;
4980            boolean doOomAdj = doLowMem;
4981            if (!app.killedByAm) {
4982                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4983                        + ") has died");
4984                mAllowLowerMemLevel = true;
4985            } else {
4986                // Note that we always want to do oom adj to update our state with the
4987                // new number of procs.
4988                mAllowLowerMemLevel = false;
4989                doLowMem = false;
4990            }
4991            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4992            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4993                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4994            handleAppDiedLocked(app, false, true);
4995
4996            if (doOomAdj) {
4997                updateOomAdjLocked();
4998            }
4999            if (doLowMem) {
5000                doLowMemReportIfNeededLocked(app);
5001            }
5002        } else if (app.pid != pid) {
5003            // A new process has already been started.
5004            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5005                    + ") has died and restarted (pid " + app.pid + ").");
5006            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5007        } else if (DEBUG_PROCESSES) {
5008            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5009                    + thread.asBinder());
5010        }
5011    }
5012
5013    /**
5014     * If a stack trace dump file is configured, dump process stack traces.
5015     * @param clearTraces causes the dump file to be erased prior to the new
5016     *    traces being written, if true; when false, the new traces will be
5017     *    appended to any existing file content.
5018     * @param firstPids of dalvik VM processes to dump stack traces for first
5019     * @param lastPids of dalvik VM processes to dump stack traces for last
5020     * @param nativeProcs optional list of native process names to dump stack crawls
5021     * @return file containing stack traces, or null if no dump file is configured
5022     */
5023    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5024            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5025        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5026        if (tracesPath == null || tracesPath.length() == 0) {
5027            return null;
5028        }
5029
5030        File tracesFile = new File(tracesPath);
5031        try {
5032            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5033            tracesFile.createNewFile();
5034            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5035        } catch (IOException e) {
5036            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5037            return null;
5038        }
5039
5040        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5041        return tracesFile;
5042    }
5043
5044    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5045            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5046        // Use a FileObserver to detect when traces finish writing.
5047        // The order of traces is considered important to maintain for legibility.
5048        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5049            @Override
5050            public synchronized void onEvent(int event, String path) { notify(); }
5051        };
5052
5053        try {
5054            observer.startWatching();
5055
5056            // First collect all of the stacks of the most important pids.
5057            if (firstPids != null) {
5058                try {
5059                    int num = firstPids.size();
5060                    for (int i = 0; i < num; i++) {
5061                        synchronized (observer) {
5062                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5063                            observer.wait(200);  // Wait for write-close, give up after 200msec
5064                        }
5065                    }
5066                } catch (InterruptedException e) {
5067                    Slog.wtf(TAG, e);
5068                }
5069            }
5070
5071            // Next collect the stacks of the native pids
5072            if (nativeProcs != null) {
5073                int[] pids = Process.getPidsForCommands(nativeProcs);
5074                if (pids != null) {
5075                    for (int pid : pids) {
5076                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5077                    }
5078                }
5079            }
5080
5081            // Lastly, measure CPU usage.
5082            if (processCpuTracker != null) {
5083                processCpuTracker.init();
5084                System.gc();
5085                processCpuTracker.update();
5086                try {
5087                    synchronized (processCpuTracker) {
5088                        processCpuTracker.wait(500); // measure over 1/2 second.
5089                    }
5090                } catch (InterruptedException e) {
5091                }
5092                processCpuTracker.update();
5093
5094                // We'll take the stack crawls of just the top apps using CPU.
5095                final int N = processCpuTracker.countWorkingStats();
5096                int numProcs = 0;
5097                for (int i=0; i<N && numProcs<5; i++) {
5098                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5099                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5100                        numProcs++;
5101                        try {
5102                            synchronized (observer) {
5103                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5104                                observer.wait(200);  // Wait for write-close, give up after 200msec
5105                            }
5106                        } catch (InterruptedException e) {
5107                            Slog.wtf(TAG, e);
5108                        }
5109
5110                    }
5111                }
5112            }
5113        } finally {
5114            observer.stopWatching();
5115        }
5116    }
5117
5118    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5119        if (true || IS_USER_BUILD) {
5120            return;
5121        }
5122        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5123        if (tracesPath == null || tracesPath.length() == 0) {
5124            return;
5125        }
5126
5127        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5128        StrictMode.allowThreadDiskWrites();
5129        try {
5130            final File tracesFile = new File(tracesPath);
5131            final File tracesDir = tracesFile.getParentFile();
5132            final File tracesTmp = new File(tracesDir, "__tmp__");
5133            try {
5134                if (tracesFile.exists()) {
5135                    tracesTmp.delete();
5136                    tracesFile.renameTo(tracesTmp);
5137                }
5138                StringBuilder sb = new StringBuilder();
5139                Time tobj = new Time();
5140                tobj.set(System.currentTimeMillis());
5141                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5142                sb.append(": ");
5143                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5144                sb.append(" since ");
5145                sb.append(msg);
5146                FileOutputStream fos = new FileOutputStream(tracesFile);
5147                fos.write(sb.toString().getBytes());
5148                if (app == null) {
5149                    fos.write("\n*** No application process!".getBytes());
5150                }
5151                fos.close();
5152                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5153            } catch (IOException e) {
5154                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5155                return;
5156            }
5157
5158            if (app != null) {
5159                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5160                firstPids.add(app.pid);
5161                dumpStackTraces(tracesPath, firstPids, null, null, null);
5162            }
5163
5164            File lastTracesFile = null;
5165            File curTracesFile = null;
5166            for (int i=9; i>=0; i--) {
5167                String name = String.format(Locale.US, "slow%02d.txt", i);
5168                curTracesFile = new File(tracesDir, name);
5169                if (curTracesFile.exists()) {
5170                    if (lastTracesFile != null) {
5171                        curTracesFile.renameTo(lastTracesFile);
5172                    } else {
5173                        curTracesFile.delete();
5174                    }
5175                }
5176                lastTracesFile = curTracesFile;
5177            }
5178            tracesFile.renameTo(curTracesFile);
5179            if (tracesTmp.exists()) {
5180                tracesTmp.renameTo(tracesFile);
5181            }
5182        } finally {
5183            StrictMode.setThreadPolicy(oldPolicy);
5184        }
5185    }
5186
5187    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5188        if (!mLaunchWarningShown) {
5189            mLaunchWarningShown = true;
5190            mUiHandler.post(new Runnable() {
5191                @Override
5192                public void run() {
5193                    synchronized (ActivityManagerService.this) {
5194                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5195                        d.show();
5196                        mUiHandler.postDelayed(new Runnable() {
5197                            @Override
5198                            public void run() {
5199                                synchronized (ActivityManagerService.this) {
5200                                    d.dismiss();
5201                                    mLaunchWarningShown = false;
5202                                }
5203                            }
5204                        }, 4000);
5205                    }
5206                }
5207            });
5208        }
5209    }
5210
5211    @Override
5212    public boolean clearApplicationUserData(final String packageName,
5213            final IPackageDataObserver observer, int userId) {
5214        enforceNotIsolatedCaller("clearApplicationUserData");
5215        if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5216            throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5217        }
5218        int uid = Binder.getCallingUid();
5219        int pid = Binder.getCallingPid();
5220        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5221                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5222        long callingId = Binder.clearCallingIdentity();
5223        try {
5224            IPackageManager pm = AppGlobals.getPackageManager();
5225            int pkgUid = -1;
5226            synchronized(this) {
5227                try {
5228                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5229                } catch (RemoteException e) {
5230                }
5231                if (pkgUid == -1) {
5232                    Slog.w(TAG, "Invalid packageName: " + packageName);
5233                    if (observer != null) {
5234                        try {
5235                            observer.onRemoveCompleted(packageName, false);
5236                        } catch (RemoteException e) {
5237                            Slog.i(TAG, "Observer no longer exists.");
5238                        }
5239                    }
5240                    return false;
5241                }
5242                if (uid == pkgUid || checkComponentPermission(
5243                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5244                        pid, uid, -1, true)
5245                        == PackageManager.PERMISSION_GRANTED) {
5246                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5247                } else {
5248                    throw new SecurityException("PID " + pid + " does not have permission "
5249                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5250                                    + " of package " + packageName);
5251                }
5252
5253                // Remove all tasks match the cleared application package and user
5254                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5255                    final TaskRecord tr = mRecentTasks.get(i);
5256                    final String taskPackageName =
5257                            tr.getBaseIntent().getComponent().getPackageName();
5258                    if (tr.userId != userId) continue;
5259                    if (!taskPackageName.equals(packageName)) continue;
5260                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5261                }
5262            }
5263
5264            try {
5265                // Clear application user data
5266                pm.clearApplicationUserData(packageName, observer, userId);
5267
5268                synchronized(this) {
5269                    // Remove all permissions granted from/to this package
5270                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5271                }
5272
5273                // Remove all zen rules created by this package; revoke it's zen access.
5274                INotificationManager inm = NotificationManager.getService();
5275                inm.removeAutomaticZenRules(packageName);
5276                inm.setNotificationPolicyAccessGranted(packageName, false);
5277
5278                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5279                        Uri.fromParts("package", packageName, null));
5280                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5281                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5282                        null, null, 0, null, null, null, null, false, false, userId);
5283            } catch (RemoteException e) {
5284            }
5285        } finally {
5286            Binder.restoreCallingIdentity(callingId);
5287        }
5288        return true;
5289    }
5290
5291    @Override
5292    public void killBackgroundProcesses(final String packageName, int userId) {
5293        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5294                != PackageManager.PERMISSION_GRANTED &&
5295                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5296                        != PackageManager.PERMISSION_GRANTED) {
5297            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5298                    + Binder.getCallingPid()
5299                    + ", uid=" + Binder.getCallingUid()
5300                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5301            Slog.w(TAG, msg);
5302            throw new SecurityException(msg);
5303        }
5304
5305        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5306                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5307        long callingId = Binder.clearCallingIdentity();
5308        try {
5309            IPackageManager pm = AppGlobals.getPackageManager();
5310            synchronized(this) {
5311                int appId = -1;
5312                try {
5313                    appId = UserHandle.getAppId(
5314                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5315                } catch (RemoteException e) {
5316                }
5317                if (appId == -1) {
5318                    Slog.w(TAG, "Invalid packageName: " + packageName);
5319                    return;
5320                }
5321                killPackageProcessesLocked(packageName, appId, userId,
5322                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5323            }
5324        } finally {
5325            Binder.restoreCallingIdentity(callingId);
5326        }
5327    }
5328
5329    @Override
5330    public void killAllBackgroundProcesses() {
5331        killAllBackgroundProcesses(-1);
5332    }
5333
5334    /**
5335     * Kills all background processes with targetSdkVersion below the specified
5336     * target SDK version.
5337     *
5338     * @param targetSdkVersion the target SDK version below which to kill
5339     *                         processes, or {@code -1} to kill all processes
5340     */
5341    private void killAllBackgroundProcesses(int targetSdkVersion) {
5342        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5343                != PackageManager.PERMISSION_GRANTED) {
5344            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5345                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5346                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5347            Slog.w(TAG, msg);
5348            throw new SecurityException(msg);
5349        }
5350
5351        final long callingId = Binder.clearCallingIdentity();
5352        try {
5353            synchronized (this) {
5354                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5355                final int NP = mProcessNames.getMap().size();
5356                for (int ip = 0; ip < NP; ip++) {
5357                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5358                    final int NA = apps.size();
5359                    for (int ia = 0; ia < NA; ia++) {
5360                        final ProcessRecord app = apps.valueAt(ia);
5361                        if (app.persistent) {
5362                            // We don't kill persistent processes.
5363                            continue;
5364                        }
5365                        if (targetSdkVersion > 0
5366                                && app.info.targetSdkVersion >= targetSdkVersion) {
5367                            continue;
5368                        }
5369                        if (app.removed) {
5370                            procs.add(app);
5371                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5372                            app.removed = true;
5373                            procs.add(app);
5374                        }
5375                    }
5376                }
5377
5378                final int N = procs.size();
5379                for (int i = 0; i < N; i++) {
5380                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5381                }
5382
5383                mAllowLowerMemLevel = true;
5384
5385                updateOomAdjLocked();
5386                doLowMemReportIfNeededLocked(null);
5387            }
5388        } finally {
5389            Binder.restoreCallingIdentity(callingId);
5390        }
5391    }
5392
5393    @Override
5394    public void forceStopPackage(final String packageName, int userId) {
5395        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5396                != PackageManager.PERMISSION_GRANTED) {
5397            String msg = "Permission Denial: forceStopPackage() from pid="
5398                    + Binder.getCallingPid()
5399                    + ", uid=" + Binder.getCallingUid()
5400                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5401            Slog.w(TAG, msg);
5402            throw new SecurityException(msg);
5403        }
5404        final int callingPid = Binder.getCallingPid();
5405        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5406                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5407        long callingId = Binder.clearCallingIdentity();
5408        try {
5409            IPackageManager pm = AppGlobals.getPackageManager();
5410            synchronized(this) {
5411                int[] users = userId == UserHandle.USER_ALL
5412                        ? mUserController.getUsers() : new int[] { userId };
5413                for (int user : users) {
5414                    int pkgUid = -1;
5415                    try {
5416                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5417                                user);
5418                    } catch (RemoteException e) {
5419                    }
5420                    if (pkgUid == -1) {
5421                        Slog.w(TAG, "Invalid packageName: " + packageName);
5422                        continue;
5423                    }
5424                    try {
5425                        pm.setPackageStoppedState(packageName, true, user);
5426                    } catch (RemoteException e) {
5427                    } catch (IllegalArgumentException e) {
5428                        Slog.w(TAG, "Failed trying to unstop package "
5429                                + packageName + ": " + e);
5430                    }
5431                    if (mUserController.isUserRunningLocked(user, 0)) {
5432                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5433                    }
5434                }
5435            }
5436        } finally {
5437            Binder.restoreCallingIdentity(callingId);
5438        }
5439    }
5440
5441    @Override
5442    public void addPackageDependency(String packageName) {
5443        synchronized (this) {
5444            int callingPid = Binder.getCallingPid();
5445            if (callingPid == Process.myPid()) {
5446                //  Yeah, um, no.
5447                return;
5448            }
5449            ProcessRecord proc;
5450            synchronized (mPidsSelfLocked) {
5451                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5452            }
5453            if (proc != null) {
5454                if (proc.pkgDeps == null) {
5455                    proc.pkgDeps = new ArraySet<String>(1);
5456                }
5457                proc.pkgDeps.add(packageName);
5458            }
5459        }
5460    }
5461
5462    /*
5463     * The pkg name and app id have to be specified.
5464     */
5465    @Override
5466    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5467        if (pkg == null) {
5468            return;
5469        }
5470        // Make sure the uid is valid.
5471        if (appid < 0) {
5472            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5473            return;
5474        }
5475        int callerUid = Binder.getCallingUid();
5476        // Only the system server can kill an application
5477        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5478            // Post an aysnc message to kill the application
5479            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5480            msg.arg1 = appid;
5481            msg.arg2 = 0;
5482            Bundle bundle = new Bundle();
5483            bundle.putString("pkg", pkg);
5484            bundle.putString("reason", reason);
5485            msg.obj = bundle;
5486            mHandler.sendMessage(msg);
5487        } else {
5488            throw new SecurityException(callerUid + " cannot kill pkg: " +
5489                    pkg);
5490        }
5491    }
5492
5493    @Override
5494    public void closeSystemDialogs(String reason) {
5495        enforceNotIsolatedCaller("closeSystemDialogs");
5496
5497        final int pid = Binder.getCallingPid();
5498        final int uid = Binder.getCallingUid();
5499        final long origId = Binder.clearCallingIdentity();
5500        try {
5501            synchronized (this) {
5502                // Only allow this from foreground processes, so that background
5503                // applications can't abuse it to prevent system UI from being shown.
5504                if (uid >= Process.FIRST_APPLICATION_UID) {
5505                    ProcessRecord proc;
5506                    synchronized (mPidsSelfLocked) {
5507                        proc = mPidsSelfLocked.get(pid);
5508                    }
5509                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5510                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5511                                + " from background process " + proc);
5512                        return;
5513                    }
5514                }
5515                closeSystemDialogsLocked(reason);
5516            }
5517        } finally {
5518            Binder.restoreCallingIdentity(origId);
5519        }
5520    }
5521
5522    void closeSystemDialogsLocked(String reason) {
5523        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5524        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5525                | Intent.FLAG_RECEIVER_FOREGROUND);
5526        if (reason != null) {
5527            intent.putExtra("reason", reason);
5528        }
5529        mWindowManager.closeSystemDialogs(reason);
5530
5531        mStackSupervisor.closeSystemDialogsLocked();
5532
5533        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5534                AppOpsManager.OP_NONE, null, false, false,
5535                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5536    }
5537
5538    @Override
5539    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5540        enforceNotIsolatedCaller("getProcessMemoryInfo");
5541        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5542        for (int i=pids.length-1; i>=0; i--) {
5543            ProcessRecord proc;
5544            int oomAdj;
5545            synchronized (this) {
5546                synchronized (mPidsSelfLocked) {
5547                    proc = mPidsSelfLocked.get(pids[i]);
5548                    oomAdj = proc != null ? proc.setAdj : 0;
5549                }
5550            }
5551            infos[i] = new Debug.MemoryInfo();
5552            Debug.getMemoryInfo(pids[i], infos[i]);
5553            if (proc != null) {
5554                synchronized (this) {
5555                    if (proc.thread != null && proc.setAdj == oomAdj) {
5556                        // Record this for posterity if the process has been stable.
5557                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5558                                infos[i].getTotalUss(), false, proc.pkgList);
5559                    }
5560                }
5561            }
5562        }
5563        return infos;
5564    }
5565
5566    @Override
5567    public long[] getProcessPss(int[] pids) {
5568        enforceNotIsolatedCaller("getProcessPss");
5569        long[] pss = new long[pids.length];
5570        for (int i=pids.length-1; i>=0; i--) {
5571            ProcessRecord proc;
5572            int oomAdj;
5573            synchronized (this) {
5574                synchronized (mPidsSelfLocked) {
5575                    proc = mPidsSelfLocked.get(pids[i]);
5576                    oomAdj = proc != null ? proc.setAdj : 0;
5577                }
5578            }
5579            long[] tmpUss = new long[1];
5580            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5581            if (proc != null) {
5582                synchronized (this) {
5583                    if (proc.thread != null && proc.setAdj == oomAdj) {
5584                        // Record this for posterity if the process has been stable.
5585                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5586                    }
5587                }
5588            }
5589        }
5590        return pss;
5591    }
5592
5593    @Override
5594    public void killApplicationProcess(String processName, int uid) {
5595        if (processName == null) {
5596            return;
5597        }
5598
5599        int callerUid = Binder.getCallingUid();
5600        // Only the system server can kill an application
5601        if (callerUid == Process.SYSTEM_UID) {
5602            synchronized (this) {
5603                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5604                if (app != null && app.thread != null) {
5605                    try {
5606                        app.thread.scheduleSuicide();
5607                    } catch (RemoteException e) {
5608                        // If the other end already died, then our work here is done.
5609                    }
5610                } else {
5611                    Slog.w(TAG, "Process/uid not found attempting kill of "
5612                            + processName + " / " + uid);
5613                }
5614            }
5615        } else {
5616            throw new SecurityException(callerUid + " cannot kill app process: " +
5617                    processName);
5618        }
5619    }
5620
5621    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5622        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5623                false, true, false, false, UserHandle.getUserId(uid), reason);
5624        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5625                Uri.fromParts("package", packageName, null));
5626        if (!mProcessesReady) {
5627            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5628                    | Intent.FLAG_RECEIVER_FOREGROUND);
5629        }
5630        intent.putExtra(Intent.EXTRA_UID, uid);
5631        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5632        broadcastIntentLocked(null, null, intent,
5633                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5634                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5635    }
5636
5637
5638    private final boolean killPackageProcessesLocked(String packageName, int appId,
5639            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5640            boolean doit, boolean evenPersistent, String reason) {
5641        ArrayList<ProcessRecord> procs = new ArrayList<>();
5642
5643        // Remove all processes this package may have touched: all with the
5644        // same UID (except for the system or root user), and all whose name
5645        // matches the package name.
5646        final int NP = mProcessNames.getMap().size();
5647        for (int ip=0; ip<NP; ip++) {
5648            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5649            final int NA = apps.size();
5650            for (int ia=0; ia<NA; ia++) {
5651                ProcessRecord app = apps.valueAt(ia);
5652                if (app.persistent && !evenPersistent) {
5653                    // we don't kill persistent processes
5654                    continue;
5655                }
5656                if (app.removed) {
5657                    if (doit) {
5658                        procs.add(app);
5659                    }
5660                    continue;
5661                }
5662
5663                // Skip process if it doesn't meet our oom adj requirement.
5664                if (app.setAdj < minOomAdj) {
5665                    continue;
5666                }
5667
5668                // If no package is specified, we call all processes under the
5669                // give user id.
5670                if (packageName == null) {
5671                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5672                        continue;
5673                    }
5674                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5675                        continue;
5676                    }
5677                // Package has been specified, we want to hit all processes
5678                // that match it.  We need to qualify this by the processes
5679                // that are running under the specified app and user ID.
5680                } else {
5681                    final boolean isDep = app.pkgDeps != null
5682                            && app.pkgDeps.contains(packageName);
5683                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5684                        continue;
5685                    }
5686                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5687                        continue;
5688                    }
5689                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5690                        continue;
5691                    }
5692                }
5693
5694                // Process has passed all conditions, kill it!
5695                if (!doit) {
5696                    return true;
5697                }
5698                app.removed = true;
5699                procs.add(app);
5700            }
5701        }
5702
5703        int N = procs.size();
5704        for (int i=0; i<N; i++) {
5705            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5706        }
5707        updateOomAdjLocked();
5708        return N > 0;
5709    }
5710
5711    private void cleanupDisabledPackageComponentsLocked(
5712            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5713
5714        Set<String> disabledClasses = null;
5715        boolean packageDisabled = false;
5716        IPackageManager pm = AppGlobals.getPackageManager();
5717
5718        if (changedClasses == null) {
5719            // Nothing changed...
5720            return;
5721        }
5722
5723        // Determine enable/disable state of the package and its components.
5724        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5725        for (int i = changedClasses.length - 1; i >= 0; i--) {
5726            final String changedClass = changedClasses[i];
5727
5728            if (changedClass.equals(packageName)) {
5729                try {
5730                    // Entire package setting changed
5731                    enabled = pm.getApplicationEnabledSetting(packageName,
5732                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5733                } catch (Exception e) {
5734                    // No such package/component; probably racing with uninstall.  In any
5735                    // event it means we have nothing further to do here.
5736                    return;
5737                }
5738                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5739                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5740                if (packageDisabled) {
5741                    // Entire package is disabled.
5742                    // No need to continue to check component states.
5743                    disabledClasses = null;
5744                    break;
5745                }
5746            } else {
5747                try {
5748                    enabled = pm.getComponentEnabledSetting(
5749                            new ComponentName(packageName, changedClass),
5750                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5751                } catch (Exception e) {
5752                    // As above, probably racing with uninstall.
5753                    return;
5754                }
5755                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5756                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5757                    if (disabledClasses == null) {
5758                        disabledClasses = new ArraySet<>(changedClasses.length);
5759                    }
5760                    disabledClasses.add(changedClass);
5761                }
5762            }
5763        }
5764
5765        if (!packageDisabled && disabledClasses == null) {
5766            // Nothing to do here...
5767            return;
5768        }
5769
5770        // Clean-up disabled activities.
5771        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5772                packageName, disabledClasses, true, false, userId) && mBooted) {
5773            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5774            mStackSupervisor.scheduleIdleLocked();
5775        }
5776
5777        // Clean-up disabled tasks
5778        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5779
5780        // Clean-up disabled services.
5781        mServices.bringDownDisabledPackageServicesLocked(
5782                packageName, disabledClasses, userId, false, killProcess, true);
5783
5784        // Clean-up disabled providers.
5785        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5786        mProviderMap.collectPackageProvidersLocked(
5787                packageName, disabledClasses, true, false, userId, providers);
5788        for (int i = providers.size() - 1; i >= 0; i--) {
5789            removeDyingProviderLocked(null, providers.get(i), true);
5790        }
5791
5792        // Clean-up disabled broadcast receivers.
5793        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5794            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5795                    packageName, disabledClasses, userId, true);
5796        }
5797
5798    }
5799
5800    final boolean forceStopPackageLocked(String packageName, int appId,
5801            boolean callerWillRestart, boolean purgeCache, boolean doit,
5802            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5803        int i;
5804
5805        if (userId == UserHandle.USER_ALL && packageName == null) {
5806            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5807        }
5808
5809        if (appId < 0 && packageName != null) {
5810            try {
5811                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5812                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5813            } catch (RemoteException e) {
5814            }
5815        }
5816
5817        if (doit) {
5818            if (packageName != null) {
5819                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5820                        + " user=" + userId + ": " + reason);
5821            } else {
5822                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5823            }
5824
5825            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5826        }
5827
5828        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5829                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5830                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5831
5832        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5833                packageName, null, doit, evenPersistent, userId)) {
5834            if (!doit) {
5835                return true;
5836            }
5837            didSomething = true;
5838        }
5839
5840        if (mServices.bringDownDisabledPackageServicesLocked(
5841                packageName, null, userId, evenPersistent, true, doit)) {
5842            if (!doit) {
5843                return true;
5844            }
5845            didSomething = true;
5846        }
5847
5848        if (packageName == null) {
5849            // Remove all sticky broadcasts from this user.
5850            mStickyBroadcasts.remove(userId);
5851        }
5852
5853        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5854        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5855                userId, providers)) {
5856            if (!doit) {
5857                return true;
5858            }
5859            didSomething = true;
5860        }
5861        for (i = providers.size() - 1; i >= 0; i--) {
5862            removeDyingProviderLocked(null, providers.get(i), true);
5863        }
5864
5865        // Remove transient permissions granted from/to this package/user
5866        removeUriPermissionsForPackageLocked(packageName, userId, false);
5867
5868        if (doit) {
5869            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5870                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5871                        packageName, null, userId, doit);
5872            }
5873        }
5874
5875        if (packageName == null || uninstalling) {
5876            // Remove pending intents.  For now we only do this when force
5877            // stopping users, because we have some problems when doing this
5878            // for packages -- app widgets are not currently cleaned up for
5879            // such packages, so they can be left with bad pending intents.
5880            if (mIntentSenderRecords.size() > 0) {
5881                Iterator<WeakReference<PendingIntentRecord>> it
5882                        = mIntentSenderRecords.values().iterator();
5883                while (it.hasNext()) {
5884                    WeakReference<PendingIntentRecord> wpir = it.next();
5885                    if (wpir == null) {
5886                        it.remove();
5887                        continue;
5888                    }
5889                    PendingIntentRecord pir = wpir.get();
5890                    if (pir == null) {
5891                        it.remove();
5892                        continue;
5893                    }
5894                    if (packageName == null) {
5895                        // Stopping user, remove all objects for the user.
5896                        if (pir.key.userId != userId) {
5897                            // Not the same user, skip it.
5898                            continue;
5899                        }
5900                    } else {
5901                        if (UserHandle.getAppId(pir.uid) != appId) {
5902                            // Different app id, skip it.
5903                            continue;
5904                        }
5905                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5906                            // Different user, skip it.
5907                            continue;
5908                        }
5909                        if (!pir.key.packageName.equals(packageName)) {
5910                            // Different package, skip it.
5911                            continue;
5912                        }
5913                    }
5914                    if (!doit) {
5915                        return true;
5916                    }
5917                    didSomething = true;
5918                    it.remove();
5919                    pir.canceled = true;
5920                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5921                        pir.key.activity.pendingResults.remove(pir.ref);
5922                    }
5923                }
5924            }
5925        }
5926
5927        if (doit) {
5928            if (purgeCache && packageName != null) {
5929                AttributeCache ac = AttributeCache.instance();
5930                if (ac != null) {
5931                    ac.removePackage(packageName);
5932                }
5933            }
5934            if (mBooted) {
5935                mStackSupervisor.resumeFocusedStackTopActivityLocked();
5936                mStackSupervisor.scheduleIdleLocked();
5937            }
5938        }
5939
5940        return didSomething;
5941    }
5942
5943    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5944        ProcessRecord old = mProcessNames.remove(name, uid);
5945        if (old != null) {
5946            old.uidRecord.numProcs--;
5947            if (old.uidRecord.numProcs == 0) {
5948                // No more processes using this uid, tell clients it is gone.
5949                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5950                        "No more processes in " + old.uidRecord);
5951                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
5952                mActiveUids.remove(uid);
5953                mBatteryStatsService.noteUidProcessState(uid,
5954                        ActivityManager.PROCESS_STATE_NONEXISTENT);
5955            }
5956            old.uidRecord = null;
5957        }
5958        mIsolatedProcesses.remove(uid);
5959        return old;
5960    }
5961
5962    private final void addProcessNameLocked(ProcessRecord proc) {
5963        // We shouldn't already have a process under this name, but just in case we
5964        // need to clean up whatever may be there now.
5965        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5966        if (old == proc && proc.persistent) {
5967            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
5968            Slog.w(TAG, "Re-adding persistent process " + proc);
5969        } else if (old != null) {
5970            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5971        }
5972        UidRecord uidRec = mActiveUids.get(proc.uid);
5973        if (uidRec == null) {
5974            uidRec = new UidRecord(proc.uid);
5975            // This is the first appearance of the uid, report it now!
5976            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5977                    "Creating new process uid: " + uidRec);
5978            mActiveUids.put(proc.uid, uidRec);
5979            mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
5980            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
5981        }
5982        proc.uidRecord = uidRec;
5983        uidRec.numProcs++;
5984        mProcessNames.put(proc.processName, proc.uid, proc);
5985        if (proc.isolated) {
5986            mIsolatedProcesses.put(proc.uid, proc);
5987        }
5988    }
5989
5990    boolean removeProcessLocked(ProcessRecord app,
5991            boolean callerWillRestart, boolean allowRestart, String reason) {
5992        final String name = app.processName;
5993        final int uid = app.uid;
5994        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5995            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5996
5997        removeProcessNameLocked(name, uid);
5998        if (mHeavyWeightProcess == app) {
5999            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6000                    mHeavyWeightProcess.userId, 0));
6001            mHeavyWeightProcess = null;
6002        }
6003        boolean needRestart = false;
6004        if (app.pid > 0 && app.pid != MY_PID) {
6005            int pid = app.pid;
6006            synchronized (mPidsSelfLocked) {
6007                mPidsSelfLocked.remove(pid);
6008                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6009            }
6010            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6011            if (app.isolated) {
6012                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6013            }
6014            boolean willRestart = false;
6015            if (app.persistent && !app.isolated) {
6016                if (!callerWillRestart) {
6017                    willRestart = true;
6018                } else {
6019                    needRestart = true;
6020                }
6021            }
6022            app.kill(reason, true);
6023            handleAppDiedLocked(app, willRestart, allowRestart);
6024            if (willRestart) {
6025                removeLruProcessLocked(app);
6026                addAppLocked(app.info, false, null /* ABI override */);
6027            }
6028        } else {
6029            mRemovedProcesses.add(app);
6030        }
6031
6032        return needRestart;
6033    }
6034
6035    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6036        cleanupAppInLaunchingProvidersLocked(app, true);
6037        removeProcessLocked(app, false, true, "timeout publishing content providers");
6038    }
6039
6040    private final void processStartTimedOutLocked(ProcessRecord app) {
6041        final int pid = app.pid;
6042        boolean gone = false;
6043        synchronized (mPidsSelfLocked) {
6044            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6045            if (knownApp != null && knownApp.thread == null) {
6046                mPidsSelfLocked.remove(pid);
6047                gone = true;
6048            }
6049        }
6050
6051        if (gone) {
6052            Slog.w(TAG, "Process " + app + " failed to attach");
6053            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6054                    pid, app.uid, app.processName);
6055            removeProcessNameLocked(app.processName, app.uid);
6056            if (mHeavyWeightProcess == app) {
6057                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6058                        mHeavyWeightProcess.userId, 0));
6059                mHeavyWeightProcess = null;
6060            }
6061            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6062            if (app.isolated) {
6063                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6064            }
6065            // Take care of any launching providers waiting for this process.
6066            cleanupAppInLaunchingProvidersLocked(app, true);
6067            // Take care of any services that are waiting for the process.
6068            mServices.processStartTimedOutLocked(app);
6069            app.kill("start timeout", true);
6070            removeLruProcessLocked(app);
6071            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6072                Slog.w(TAG, "Unattached app died before backup, skipping");
6073                try {
6074                    IBackupManager bm = IBackupManager.Stub.asInterface(
6075                            ServiceManager.getService(Context.BACKUP_SERVICE));
6076                    bm.agentDisconnected(app.info.packageName);
6077                } catch (RemoteException e) {
6078                    // Can't happen; the backup manager is local
6079                }
6080            }
6081            if (isPendingBroadcastProcessLocked(pid)) {
6082                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6083                skipPendingBroadcastLocked(pid);
6084            }
6085        } else {
6086            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6087        }
6088    }
6089
6090    private final boolean attachApplicationLocked(IApplicationThread thread,
6091            int pid) {
6092
6093        // Find the application record that is being attached...  either via
6094        // the pid if we are running in multiple processes, or just pull the
6095        // next app record if we are emulating process with anonymous threads.
6096        ProcessRecord app;
6097        if (pid != MY_PID && pid >= 0) {
6098            synchronized (mPidsSelfLocked) {
6099                app = mPidsSelfLocked.get(pid);
6100            }
6101        } else {
6102            app = null;
6103        }
6104
6105        if (app == null) {
6106            Slog.w(TAG, "No pending application record for pid " + pid
6107                    + " (IApplicationThread " + thread + "); dropping process");
6108            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6109            if (pid > 0 && pid != MY_PID) {
6110                Process.killProcessQuiet(pid);
6111                //TODO: killProcessGroup(app.info.uid, pid);
6112            } else {
6113                try {
6114                    thread.scheduleExit();
6115                } catch (Exception e) {
6116                    // Ignore exceptions.
6117                }
6118            }
6119            return false;
6120        }
6121
6122        // If this application record is still attached to a previous
6123        // process, clean it up now.
6124        if (app.thread != null) {
6125            handleAppDiedLocked(app, true, true);
6126        }
6127
6128        // Tell the process all about itself.
6129
6130        if (DEBUG_ALL) Slog.v(
6131                TAG, "Binding process pid " + pid + " to record " + app);
6132
6133        final String processName = app.processName;
6134        try {
6135            AppDeathRecipient adr = new AppDeathRecipient(
6136                    app, pid, thread);
6137            thread.asBinder().linkToDeath(adr, 0);
6138            app.deathRecipient = adr;
6139        } catch (RemoteException e) {
6140            app.resetPackageList(mProcessStats);
6141            startProcessLocked(app, "link fail", processName);
6142            return false;
6143        }
6144
6145        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6146
6147        app.makeActive(thread, mProcessStats);
6148        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6149        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6150        app.forcingToForeground = null;
6151        updateProcessForegroundLocked(app, false, false);
6152        app.hasShownUi = false;
6153        app.debugging = false;
6154        app.cached = false;
6155        app.killedByAm = false;
6156
6157        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6158
6159        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6160        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6161
6162        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6163            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6164            msg.obj = app;
6165            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6166        }
6167
6168        if (!normalMode) {
6169            Slog.i(TAG, "Launching preboot mode app: " + app);
6170        }
6171
6172        if (DEBUG_ALL) Slog.v(
6173            TAG, "New app record " + app
6174            + " thread=" + thread.asBinder() + " pid=" + pid);
6175        try {
6176            int testMode = IApplicationThread.DEBUG_OFF;
6177            if (mDebugApp != null && mDebugApp.equals(processName)) {
6178                testMode = mWaitForDebugger
6179                    ? IApplicationThread.DEBUG_WAIT
6180                    : IApplicationThread.DEBUG_ON;
6181                app.debugging = true;
6182                if (mDebugTransient) {
6183                    mDebugApp = mOrigDebugApp;
6184                    mWaitForDebugger = mOrigWaitForDebugger;
6185                }
6186            }
6187            String profileFile = app.instrumentationProfileFile;
6188            ParcelFileDescriptor profileFd = null;
6189            int samplingInterval = 0;
6190            boolean profileAutoStop = false;
6191            if (mProfileApp != null && mProfileApp.equals(processName)) {
6192                mProfileProc = app;
6193                profileFile = mProfileFile;
6194                profileFd = mProfileFd;
6195                samplingInterval = mSamplingInterval;
6196                profileAutoStop = mAutoStopProfiler;
6197            }
6198            boolean enableTrackAllocation = false;
6199            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6200                enableTrackAllocation = true;
6201                mTrackAllocationApp = null;
6202            }
6203
6204            // If the app is being launched for restore or full backup, set it up specially
6205            boolean isRestrictedBackupMode = false;
6206            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6207                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6208                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6209                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6210            }
6211
6212            notifyPackageUse(app.instrumentationInfo != null
6213                    ? app.instrumentationInfo.packageName
6214                    : app.info.packageName);
6215            if (app.instrumentationClass != null) {
6216                notifyPackageUse(app.instrumentationClass.getPackageName());
6217            }
6218            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6219                    + processName + " with config " + mConfiguration);
6220            ApplicationInfo appInfo = app.instrumentationInfo != null
6221                    ? app.instrumentationInfo : app.info;
6222            app.compat = compatibilityInfoForPackageLocked(appInfo);
6223            if (profileFd != null) {
6224                profileFd = profileFd.dup();
6225            }
6226            ProfilerInfo profilerInfo = profileFile == null ? null
6227                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6228            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6229                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6230                    app.instrumentationUiAutomationConnection, testMode,
6231                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6232                    isRestrictedBackupMode || !normalMode, app.persistent,
6233                    new Configuration(mConfiguration), app.compat,
6234                    getCommonServicesLocked(app.isolated),
6235                    mCoreSettingsObserver.getCoreSettingsLocked());
6236            updateLruProcessLocked(app, false, null);
6237            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6238        } catch (Exception e) {
6239            // todo: Yikes!  What should we do?  For now we will try to
6240            // start another process, but that could easily get us in
6241            // an infinite loop of restarting processes...
6242            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6243
6244            app.resetPackageList(mProcessStats);
6245            app.unlinkDeathRecipient();
6246            startProcessLocked(app, "bind fail", processName);
6247            return false;
6248        }
6249
6250        // Remove this record from the list of starting applications.
6251        mPersistentStartingProcesses.remove(app);
6252        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6253                "Attach application locked removing on hold: " + app);
6254        mProcessesOnHold.remove(app);
6255
6256        boolean badApp = false;
6257        boolean didSomething = false;
6258
6259        // See if the top visible activity is waiting to run in this process...
6260        if (normalMode) {
6261            try {
6262                if (mStackSupervisor.attachApplicationLocked(app)) {
6263                    didSomething = true;
6264                }
6265            } catch (Exception e) {
6266                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6267                badApp = true;
6268            }
6269        }
6270
6271        // Find any services that should be running in this process...
6272        if (!badApp) {
6273            try {
6274                didSomething |= mServices.attachApplicationLocked(app, processName);
6275            } catch (Exception e) {
6276                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6277                badApp = true;
6278            }
6279        }
6280
6281        // Check if a next-broadcast receiver is in this process...
6282        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6283            try {
6284                didSomething |= sendPendingBroadcastsLocked(app);
6285            } catch (Exception e) {
6286                // If the app died trying to launch the receiver we declare it 'bad'
6287                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6288                badApp = true;
6289            }
6290        }
6291
6292        // Check whether the next backup agent is in this process...
6293        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6294            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6295                    "New app is backup target, launching agent for " + app);
6296            notifyPackageUse(mBackupTarget.appInfo.packageName);
6297            try {
6298                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6299                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6300                        mBackupTarget.backupMode);
6301            } catch (Exception e) {
6302                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6303                badApp = true;
6304            }
6305        }
6306
6307        if (badApp) {
6308            app.kill("error during init", true);
6309            handleAppDiedLocked(app, false, true);
6310            return false;
6311        }
6312
6313        if (!didSomething) {
6314            updateOomAdjLocked();
6315        }
6316
6317        return true;
6318    }
6319
6320    @Override
6321    public final void attachApplication(IApplicationThread thread) {
6322        synchronized (this) {
6323            int callingPid = Binder.getCallingPid();
6324            final long origId = Binder.clearCallingIdentity();
6325            attachApplicationLocked(thread, callingPid);
6326            Binder.restoreCallingIdentity(origId);
6327        }
6328    }
6329
6330    @Override
6331    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6332        final long origId = Binder.clearCallingIdentity();
6333        synchronized (this) {
6334            ActivityStack stack = ActivityRecord.getStackLocked(token);
6335            if (stack != null) {
6336                ActivityRecord r =
6337                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6338                if (stopProfiling) {
6339                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6340                        try {
6341                            mProfileFd.close();
6342                        } catch (IOException e) {
6343                        }
6344                        clearProfilerLocked();
6345                    }
6346                }
6347            }
6348        }
6349        Binder.restoreCallingIdentity(origId);
6350    }
6351
6352    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6353        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6354                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6355    }
6356
6357    void enableScreenAfterBoot() {
6358        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6359                SystemClock.uptimeMillis());
6360        mWindowManager.enableScreenAfterBoot();
6361
6362        synchronized (this) {
6363            updateEventDispatchingLocked();
6364        }
6365    }
6366
6367    @Override
6368    public void showBootMessage(final CharSequence msg, final boolean always) {
6369        if (Binder.getCallingUid() != Process.myUid()) {
6370            // These days only the core system can call this, so apps can't get in
6371            // the way of what we show about running them.
6372        }
6373        mWindowManager.showBootMessage(msg, always);
6374    }
6375
6376    @Override
6377    public void keyguardWaitingForActivityDrawn() {
6378        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6379        final long token = Binder.clearCallingIdentity();
6380        try {
6381            synchronized (this) {
6382                if (DEBUG_LOCKSCREEN) logLockScreen("");
6383                mWindowManager.keyguardWaitingForActivityDrawn();
6384                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6385                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6386                    updateSleepIfNeededLocked();
6387                }
6388            }
6389        } finally {
6390            Binder.restoreCallingIdentity(token);
6391        }
6392    }
6393
6394    @Override
6395    public void keyguardGoingAway(boolean disableWindowAnimations,
6396            boolean keyguardGoingToNotificationShade) {
6397        enforceNotIsolatedCaller("keyguardGoingAway");
6398        final long token = Binder.clearCallingIdentity();
6399        try {
6400            synchronized (this) {
6401                if (DEBUG_LOCKSCREEN) logLockScreen("");
6402                mWindowManager.keyguardGoingAway(disableWindowAnimations,
6403                        keyguardGoingToNotificationShade);
6404                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6405                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6406                    updateSleepIfNeededLocked();
6407                }
6408            }
6409        } finally {
6410            Binder.restoreCallingIdentity(token);
6411        }
6412    }
6413
6414    final void finishBooting() {
6415        synchronized (this) {
6416            if (!mBootAnimationComplete) {
6417                mCallFinishBooting = true;
6418                return;
6419            }
6420            mCallFinishBooting = false;
6421        }
6422
6423        ArraySet<String> completedIsas = new ArraySet<String>();
6424        for (String abi : Build.SUPPORTED_ABIS) {
6425            Process.establishZygoteConnectionForAbi(abi);
6426            final String instructionSet = VMRuntime.getInstructionSet(abi);
6427            if (!completedIsas.contains(instructionSet)) {
6428                try {
6429                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6430                } catch (InstallerException e) {
6431                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6432                }
6433                completedIsas.add(instructionSet);
6434            }
6435        }
6436
6437        IntentFilter pkgFilter = new IntentFilter();
6438        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6439        pkgFilter.addDataScheme("package");
6440        mContext.registerReceiver(new BroadcastReceiver() {
6441            @Override
6442            public void onReceive(Context context, Intent intent) {
6443                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6444                if (pkgs != null) {
6445                    for (String pkg : pkgs) {
6446                        synchronized (ActivityManagerService.this) {
6447                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6448                                    0, "query restart")) {
6449                                setResultCode(Activity.RESULT_OK);
6450                                return;
6451                            }
6452                        }
6453                    }
6454                }
6455            }
6456        }, pkgFilter);
6457
6458        IntentFilter dumpheapFilter = new IntentFilter();
6459        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6460        mContext.registerReceiver(new BroadcastReceiver() {
6461            @Override
6462            public void onReceive(Context context, Intent intent) {
6463                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6464                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6465                } else {
6466                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6467                }
6468            }
6469        }, dumpheapFilter);
6470
6471        mProcessStartLogger.registerListener(mContext);
6472
6473        // Let system services know.
6474        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6475
6476        synchronized (this) {
6477            // Ensure that any processes we had put on hold are now started
6478            // up.
6479            final int NP = mProcessesOnHold.size();
6480            if (NP > 0) {
6481                ArrayList<ProcessRecord> procs =
6482                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6483                for (int ip=0; ip<NP; ip++) {
6484                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6485                            + procs.get(ip));
6486                    startProcessLocked(procs.get(ip), "on-hold", null);
6487                }
6488            }
6489
6490            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6491                // Start looking for apps that are abusing wake locks.
6492                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6493                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6494                // Tell anyone interested that we are done booting!
6495                SystemProperties.set("sys.boot_completed", "1");
6496
6497                // And trigger dev.bootcomplete if we are not showing encryption progress
6498                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6499                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6500                    SystemProperties.set("dev.bootcomplete", "1");
6501                }
6502                mUserController.sendBootCompletedLocked(
6503                        new IIntentReceiver.Stub() {
6504                            @Override
6505                            public void performReceive(Intent intent, int resultCode,
6506                                    String data, Bundle extras, boolean ordered,
6507                                    boolean sticky, int sendingUser) {
6508                                synchronized (ActivityManagerService.this) {
6509                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6510                                            true, false);
6511                                }
6512                            }
6513                        });
6514                scheduleStartProfilesLocked();
6515            }
6516        }
6517    }
6518
6519    @Override
6520    public void bootAnimationComplete() {
6521        final boolean callFinishBooting;
6522        synchronized (this) {
6523            callFinishBooting = mCallFinishBooting;
6524            mBootAnimationComplete = true;
6525        }
6526        if (callFinishBooting) {
6527            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6528            finishBooting();
6529            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6530        }
6531    }
6532
6533    final void ensureBootCompleted() {
6534        boolean booting;
6535        boolean enableScreen;
6536        synchronized (this) {
6537            booting = mBooting;
6538            mBooting = false;
6539            enableScreen = !mBooted;
6540            mBooted = true;
6541        }
6542
6543        if (booting) {
6544            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6545            finishBooting();
6546            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6547        }
6548
6549        if (enableScreen) {
6550            enableScreenAfterBoot();
6551        }
6552    }
6553
6554    @Override
6555    public final void activityResumed(IBinder token) {
6556        final long origId = Binder.clearCallingIdentity();
6557        synchronized(this) {
6558            ActivityStack stack = ActivityRecord.getStackLocked(token);
6559            if (stack != null) {
6560                ActivityRecord.activityResumedLocked(token);
6561            }
6562        }
6563        Binder.restoreCallingIdentity(origId);
6564    }
6565
6566    @Override
6567    public final void activityPaused(IBinder token) {
6568        final long origId = Binder.clearCallingIdentity();
6569        synchronized(this) {
6570            ActivityStack stack = ActivityRecord.getStackLocked(token);
6571            if (stack != null) {
6572                stack.activityPausedLocked(token, false);
6573            }
6574        }
6575        Binder.restoreCallingIdentity(origId);
6576    }
6577
6578    @Override
6579    public final void activityStopped(IBinder token, Bundle icicle,
6580            PersistableBundle persistentState, CharSequence description) {
6581        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6582
6583        // Refuse possible leaked file descriptors
6584        if (icicle != null && icicle.hasFileDescriptors()) {
6585            throw new IllegalArgumentException("File descriptors passed in Bundle");
6586        }
6587
6588        final long origId = Binder.clearCallingIdentity();
6589
6590        synchronized (this) {
6591            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6592            if (r != null) {
6593                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6594            }
6595        }
6596
6597        trimApplications();
6598
6599        Binder.restoreCallingIdentity(origId);
6600    }
6601
6602    @Override
6603    public final void activityDestroyed(IBinder token) {
6604        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6605        synchronized (this) {
6606            ActivityStack stack = ActivityRecord.getStackLocked(token);
6607            if (stack != null) {
6608                stack.activityDestroyedLocked(token, "activityDestroyed");
6609            }
6610        }
6611    }
6612
6613    @Override
6614    public final void activityRelaunched(IBinder token) {
6615        final long origId = Binder.clearCallingIdentity();
6616        synchronized (this) {
6617            mStackSupervisor.activityRelaunchedLocked(token);
6618        }
6619        Binder.restoreCallingIdentity(origId);
6620    }
6621
6622    @Override
6623    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6624            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6625        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6626                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6627        synchronized (this) {
6628            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6629            if (record == null) {
6630                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6631                        + "found for: " + token);
6632            }
6633            record.setSizeConfigurations(horizontalSizeConfiguration,
6634                    verticalSizeConfigurations, smallestSizeConfigurations);
6635        }
6636    }
6637
6638    @Override
6639    public final void backgroundResourcesReleased(IBinder token) {
6640        final long origId = Binder.clearCallingIdentity();
6641        try {
6642            synchronized (this) {
6643                ActivityStack stack = ActivityRecord.getStackLocked(token);
6644                if (stack != null) {
6645                    stack.backgroundResourcesReleased();
6646                }
6647            }
6648        } finally {
6649            Binder.restoreCallingIdentity(origId);
6650        }
6651    }
6652
6653    @Override
6654    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6655        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6656    }
6657
6658    @Override
6659    public final void notifyEnterAnimationComplete(IBinder token) {
6660        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6661    }
6662
6663    @Override
6664    public String getCallingPackage(IBinder token) {
6665        synchronized (this) {
6666            ActivityRecord r = getCallingRecordLocked(token);
6667            return r != null ? r.info.packageName : null;
6668        }
6669    }
6670
6671    @Override
6672    public ComponentName getCallingActivity(IBinder token) {
6673        synchronized (this) {
6674            ActivityRecord r = getCallingRecordLocked(token);
6675            return r != null ? r.intent.getComponent() : null;
6676        }
6677    }
6678
6679    private ActivityRecord getCallingRecordLocked(IBinder token) {
6680        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6681        if (r == null) {
6682            return null;
6683        }
6684        return r.resultTo;
6685    }
6686
6687    @Override
6688    public ComponentName getActivityClassForToken(IBinder token) {
6689        synchronized(this) {
6690            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6691            if (r == null) {
6692                return null;
6693            }
6694            return r.intent.getComponent();
6695        }
6696    }
6697
6698    @Override
6699    public String getPackageForToken(IBinder token) {
6700        synchronized(this) {
6701            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6702            if (r == null) {
6703                return null;
6704            }
6705            return r.packageName;
6706        }
6707    }
6708
6709    @Override
6710    public boolean isRootVoiceInteraction(IBinder token) {
6711        synchronized(this) {
6712            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6713            if (r == null) {
6714                return false;
6715            }
6716            return r.rootVoiceInteraction;
6717        }
6718    }
6719
6720    @Override
6721    public IIntentSender getIntentSender(int type,
6722            String packageName, IBinder token, String resultWho,
6723            int requestCode, Intent[] intents, String[] resolvedTypes,
6724            int flags, Bundle bOptions, int userId) {
6725        enforceNotIsolatedCaller("getIntentSender");
6726        // Refuse possible leaked file descriptors
6727        if (intents != null) {
6728            if (intents.length < 1) {
6729                throw new IllegalArgumentException("Intents array length must be >= 1");
6730            }
6731            for (int i=0; i<intents.length; i++) {
6732                Intent intent = intents[i];
6733                if (intent != null) {
6734                    if (intent.hasFileDescriptors()) {
6735                        throw new IllegalArgumentException("File descriptors passed in Intent");
6736                    }
6737                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6738                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6739                        throw new IllegalArgumentException(
6740                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6741                    }
6742                    intents[i] = new Intent(intent);
6743                }
6744            }
6745            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6746                throw new IllegalArgumentException(
6747                        "Intent array length does not match resolvedTypes length");
6748            }
6749        }
6750        if (bOptions != null) {
6751            if (bOptions.hasFileDescriptors()) {
6752                throw new IllegalArgumentException("File descriptors passed in options");
6753            }
6754        }
6755
6756        synchronized(this) {
6757            int callingUid = Binder.getCallingUid();
6758            int origUserId = userId;
6759            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6760                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6761                    ALLOW_NON_FULL, "getIntentSender", null);
6762            if (origUserId == UserHandle.USER_CURRENT) {
6763                // We don't want to evaluate this until the pending intent is
6764                // actually executed.  However, we do want to always do the
6765                // security checking for it above.
6766                userId = UserHandle.USER_CURRENT;
6767            }
6768            try {
6769                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6770                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6771                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6772                    if (!UserHandle.isSameApp(callingUid, uid)) {
6773                        String msg = "Permission Denial: getIntentSender() from pid="
6774                            + Binder.getCallingPid()
6775                            + ", uid=" + Binder.getCallingUid()
6776                            + ", (need uid=" + uid + ")"
6777                            + " is not allowed to send as package " + packageName;
6778                        Slog.w(TAG, msg);
6779                        throw new SecurityException(msg);
6780                    }
6781                }
6782
6783                return getIntentSenderLocked(type, packageName, callingUid, userId,
6784                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6785
6786            } catch (RemoteException e) {
6787                throw new SecurityException(e);
6788            }
6789        }
6790    }
6791
6792    IIntentSender getIntentSenderLocked(int type, String packageName,
6793            int callingUid, int userId, IBinder token, String resultWho,
6794            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6795            Bundle bOptions) {
6796        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6797        ActivityRecord activity = null;
6798        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6799            activity = ActivityRecord.isInStackLocked(token);
6800            if (activity == null) {
6801                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6802                return null;
6803            }
6804            if (activity.finishing) {
6805                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6806                return null;
6807            }
6808        }
6809
6810        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6811        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6812        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6813        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6814                |PendingIntent.FLAG_UPDATE_CURRENT);
6815
6816        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6817                type, packageName, activity, resultWho,
6818                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6819        WeakReference<PendingIntentRecord> ref;
6820        ref = mIntentSenderRecords.get(key);
6821        PendingIntentRecord rec = ref != null ? ref.get() : null;
6822        if (rec != null) {
6823            if (!cancelCurrent) {
6824                if (updateCurrent) {
6825                    if (rec.key.requestIntent != null) {
6826                        rec.key.requestIntent.replaceExtras(intents != null ?
6827                                intents[intents.length - 1] : null);
6828                    }
6829                    if (intents != null) {
6830                        intents[intents.length-1] = rec.key.requestIntent;
6831                        rec.key.allIntents = intents;
6832                        rec.key.allResolvedTypes = resolvedTypes;
6833                    } else {
6834                        rec.key.allIntents = null;
6835                        rec.key.allResolvedTypes = null;
6836                    }
6837                }
6838                return rec;
6839            }
6840            rec.canceled = true;
6841            mIntentSenderRecords.remove(key);
6842        }
6843        if (noCreate) {
6844            return rec;
6845        }
6846        rec = new PendingIntentRecord(this, key, callingUid);
6847        mIntentSenderRecords.put(key, rec.ref);
6848        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6849            if (activity.pendingResults == null) {
6850                activity.pendingResults
6851                        = new HashSet<WeakReference<PendingIntentRecord>>();
6852            }
6853            activity.pendingResults.add(rec.ref);
6854        }
6855        return rec;
6856    }
6857
6858    @Override
6859    public void cancelIntentSender(IIntentSender sender) {
6860        if (!(sender instanceof PendingIntentRecord)) {
6861            return;
6862        }
6863        synchronized(this) {
6864            PendingIntentRecord rec = (PendingIntentRecord)sender;
6865            try {
6866                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
6867                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
6868                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6869                    String msg = "Permission Denial: cancelIntentSender() from pid="
6870                        + Binder.getCallingPid()
6871                        + ", uid=" + Binder.getCallingUid()
6872                        + " is not allowed to cancel packges "
6873                        + rec.key.packageName;
6874                    Slog.w(TAG, msg);
6875                    throw new SecurityException(msg);
6876                }
6877            } catch (RemoteException e) {
6878                throw new SecurityException(e);
6879            }
6880            cancelIntentSenderLocked(rec, true);
6881        }
6882    }
6883
6884    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6885        rec.canceled = true;
6886        mIntentSenderRecords.remove(rec.key);
6887        if (cleanActivity && rec.key.activity != null) {
6888            rec.key.activity.pendingResults.remove(rec.ref);
6889        }
6890    }
6891
6892    @Override
6893    public String getPackageForIntentSender(IIntentSender pendingResult) {
6894        if (!(pendingResult instanceof PendingIntentRecord)) {
6895            return null;
6896        }
6897        try {
6898            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6899            return res.key.packageName;
6900        } catch (ClassCastException e) {
6901        }
6902        return null;
6903    }
6904
6905    @Override
6906    public int getUidForIntentSender(IIntentSender sender) {
6907        if (sender instanceof PendingIntentRecord) {
6908            try {
6909                PendingIntentRecord res = (PendingIntentRecord)sender;
6910                return res.uid;
6911            } catch (ClassCastException e) {
6912            }
6913        }
6914        return -1;
6915    }
6916
6917    @Override
6918    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6919        if (!(pendingResult instanceof PendingIntentRecord)) {
6920            return false;
6921        }
6922        try {
6923            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6924            if (res.key.allIntents == null) {
6925                return false;
6926            }
6927            for (int i=0; i<res.key.allIntents.length; i++) {
6928                Intent intent = res.key.allIntents[i];
6929                if (intent.getPackage() != null && intent.getComponent() != null) {
6930                    return false;
6931                }
6932            }
6933            return true;
6934        } catch (ClassCastException e) {
6935        }
6936        return false;
6937    }
6938
6939    @Override
6940    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6941        if (!(pendingResult instanceof PendingIntentRecord)) {
6942            return false;
6943        }
6944        try {
6945            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6946            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6947                return true;
6948            }
6949            return false;
6950        } catch (ClassCastException e) {
6951        }
6952        return false;
6953    }
6954
6955    @Override
6956    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6957        if (!(pendingResult instanceof PendingIntentRecord)) {
6958            return null;
6959        }
6960        try {
6961            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6962            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6963        } catch (ClassCastException e) {
6964        }
6965        return null;
6966    }
6967
6968    @Override
6969    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6970        if (!(pendingResult instanceof PendingIntentRecord)) {
6971            return null;
6972        }
6973        try {
6974            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6975            synchronized (this) {
6976                return getTagForIntentSenderLocked(res, prefix);
6977            }
6978        } catch (ClassCastException e) {
6979        }
6980        return null;
6981    }
6982
6983    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6984        final Intent intent = res.key.requestIntent;
6985        if (intent != null) {
6986            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6987                    || res.lastTagPrefix.equals(prefix))) {
6988                return res.lastTag;
6989            }
6990            res.lastTagPrefix = prefix;
6991            final StringBuilder sb = new StringBuilder(128);
6992            if (prefix != null) {
6993                sb.append(prefix);
6994            }
6995            if (intent.getAction() != null) {
6996                sb.append(intent.getAction());
6997            } else if (intent.getComponent() != null) {
6998                intent.getComponent().appendShortString(sb);
6999            } else {
7000                sb.append("?");
7001            }
7002            return res.lastTag = sb.toString();
7003        }
7004        return null;
7005    }
7006
7007    @Override
7008    public void setProcessLimit(int max) {
7009        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7010                "setProcessLimit()");
7011        synchronized (this) {
7012            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7013            mProcessLimitOverride = max;
7014        }
7015        trimApplications();
7016    }
7017
7018    @Override
7019    public int getProcessLimit() {
7020        synchronized (this) {
7021            return mProcessLimitOverride;
7022        }
7023    }
7024
7025    void foregroundTokenDied(ForegroundToken token) {
7026        synchronized (ActivityManagerService.this) {
7027            synchronized (mPidsSelfLocked) {
7028                ForegroundToken cur
7029                    = mForegroundProcesses.get(token.pid);
7030                if (cur != token) {
7031                    return;
7032                }
7033                mForegroundProcesses.remove(token.pid);
7034                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7035                if (pr == null) {
7036                    return;
7037                }
7038                pr.forcingToForeground = null;
7039                updateProcessForegroundLocked(pr, false, false);
7040            }
7041            updateOomAdjLocked();
7042        }
7043    }
7044
7045    @Override
7046    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7047        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7048                "setProcessForeground()");
7049        synchronized(this) {
7050            boolean changed = false;
7051
7052            synchronized (mPidsSelfLocked) {
7053                ProcessRecord pr = mPidsSelfLocked.get(pid);
7054                if (pr == null && isForeground) {
7055                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7056                    return;
7057                }
7058                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7059                if (oldToken != null) {
7060                    oldToken.token.unlinkToDeath(oldToken, 0);
7061                    mForegroundProcesses.remove(pid);
7062                    if (pr != null) {
7063                        pr.forcingToForeground = null;
7064                    }
7065                    changed = true;
7066                }
7067                if (isForeground && token != null) {
7068                    ForegroundToken newToken = new ForegroundToken() {
7069                        @Override
7070                        public void binderDied() {
7071                            foregroundTokenDied(this);
7072                        }
7073                    };
7074                    newToken.pid = pid;
7075                    newToken.token = token;
7076                    try {
7077                        token.linkToDeath(newToken, 0);
7078                        mForegroundProcesses.put(pid, newToken);
7079                        pr.forcingToForeground = token;
7080                        changed = true;
7081                    } catch (RemoteException e) {
7082                        // If the process died while doing this, we will later
7083                        // do the cleanup with the process death link.
7084                    }
7085                }
7086            }
7087
7088            if (changed) {
7089                updateOomAdjLocked();
7090            }
7091        }
7092    }
7093
7094    @Override
7095    public boolean isAppForeground(int uid) throws RemoteException {
7096        synchronized (this) {
7097            UidRecord uidRec = mActiveUids.get(uid);
7098            if (uidRec == null || uidRec.idle) {
7099                return false;
7100            }
7101            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7102        }
7103    }
7104
7105    @Override
7106    public boolean inMultiWindow(IBinder token) {
7107        final long origId = Binder.clearCallingIdentity();
7108        try {
7109            synchronized(this) {
7110                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7111                if (r == null) {
7112                    return false;
7113                }
7114                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7115                return !r.task.mFullscreen;
7116            }
7117        } finally {
7118            Binder.restoreCallingIdentity(origId);
7119        }
7120    }
7121
7122    @Override
7123    public boolean inPictureInPicture(IBinder token) {
7124        final long origId = Binder.clearCallingIdentity();
7125        try {
7126            synchronized(this) {
7127                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7128                if (stack == null) {
7129                    return false;
7130                }
7131                return stack.mStackId == PINNED_STACK_ID;
7132            }
7133        } finally {
7134            Binder.restoreCallingIdentity(origId);
7135        }
7136    }
7137
7138    @Override
7139    public void enterPictureInPicture(IBinder token) {
7140        final long origId = Binder.clearCallingIdentity();
7141        try {
7142            synchronized(this) {
7143                if (!mSupportsPictureInPicture) {
7144                    throw new IllegalStateException("enterPictureInPicture: "
7145                            + "Device doesn't support picture-in-picture mode.");
7146                }
7147
7148                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7149
7150                if (r == null) {
7151                    throw new IllegalStateException("enterPictureInPicture: "
7152                            + "Can't find activity for token=" + token);
7153                }
7154
7155                if (!r.supportsPictureInPicture()) {
7156                    throw new IllegalArgumentException("enterPictureInPicture: "
7157                            + "Picture-In-Picture not supported for r=" + r);
7158                }
7159
7160                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7161                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7162                        ? mDefaultPinnedStackBounds : null;
7163
7164                mStackSupervisor.moveActivityToStackLocked(
7165                        r, PINNED_STACK_ID, "enterPictureInPicture", bounds);
7166            }
7167        } finally {
7168            Binder.restoreCallingIdentity(origId);
7169        }
7170    }
7171
7172    // =========================================================
7173    // PROCESS INFO
7174    // =========================================================
7175
7176    static class ProcessInfoService extends IProcessInfoService.Stub {
7177        final ActivityManagerService mActivityManagerService;
7178        ProcessInfoService(ActivityManagerService activityManagerService) {
7179            mActivityManagerService = activityManagerService;
7180        }
7181
7182        @Override
7183        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7184            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7185                    /*in*/ pids, /*out*/ states, null);
7186        }
7187
7188        @Override
7189        public void getProcessStatesAndOomScoresFromPids(
7190                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7191            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7192                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7193        }
7194    }
7195
7196    /**
7197     * For each PID in the given input array, write the current process state
7198     * for that process into the states array, or -1 to indicate that no
7199     * process with the given PID exists. If scores array is provided, write
7200     * the oom score for the process into the scores array, with INVALID_ADJ
7201     * indicating the PID doesn't exist.
7202     */
7203    public void getProcessStatesAndOomScoresForPIDs(
7204            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7205        if (scores != null) {
7206            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7207                    "getProcessStatesAndOomScoresForPIDs()");
7208        }
7209
7210        if (pids == null) {
7211            throw new NullPointerException("pids");
7212        } else if (states == null) {
7213            throw new NullPointerException("states");
7214        } else if (pids.length != states.length) {
7215            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7216        } else if (scores != null && pids.length != scores.length) {
7217            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7218        }
7219
7220        synchronized (mPidsSelfLocked) {
7221            for (int i = 0; i < pids.length; i++) {
7222                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7223                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7224                        pr.curProcState;
7225                if (scores != null) {
7226                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7227                }
7228            }
7229        }
7230    }
7231
7232    // =========================================================
7233    // PERMISSIONS
7234    // =========================================================
7235
7236    static class PermissionController extends IPermissionController.Stub {
7237        ActivityManagerService mActivityManagerService;
7238        PermissionController(ActivityManagerService activityManagerService) {
7239            mActivityManagerService = activityManagerService;
7240        }
7241
7242        @Override
7243        public boolean checkPermission(String permission, int pid, int uid) {
7244            return mActivityManagerService.checkPermission(permission, pid,
7245                    uid) == PackageManager.PERMISSION_GRANTED;
7246        }
7247
7248        @Override
7249        public String[] getPackagesForUid(int uid) {
7250            return mActivityManagerService.mContext.getPackageManager()
7251                    .getPackagesForUid(uid);
7252        }
7253
7254        @Override
7255        public boolean isRuntimePermission(String permission) {
7256            try {
7257                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7258                        .getPermissionInfo(permission, 0);
7259                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7260            } catch (NameNotFoundException nnfe) {
7261                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7262            }
7263            return false;
7264        }
7265    }
7266
7267    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7268        @Override
7269        public int checkComponentPermission(String permission, int pid, int uid,
7270                int owningUid, boolean exported) {
7271            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7272                    owningUid, exported);
7273        }
7274
7275        @Override
7276        public Object getAMSLock() {
7277            return ActivityManagerService.this;
7278        }
7279    }
7280
7281    /**
7282     * This can be called with or without the global lock held.
7283     */
7284    int checkComponentPermission(String permission, int pid, int uid,
7285            int owningUid, boolean exported) {
7286        if (pid == MY_PID) {
7287            return PackageManager.PERMISSION_GRANTED;
7288        }
7289        return ActivityManager.checkComponentPermission(permission, uid,
7290                owningUid, exported);
7291    }
7292
7293    /**
7294     * As the only public entry point for permissions checking, this method
7295     * can enforce the semantic that requesting a check on a null global
7296     * permission is automatically denied.  (Internally a null permission
7297     * string is used when calling {@link #checkComponentPermission} in cases
7298     * when only uid-based security is needed.)
7299     *
7300     * This can be called with or without the global lock held.
7301     */
7302    @Override
7303    public int checkPermission(String permission, int pid, int uid) {
7304        if (permission == null) {
7305            return PackageManager.PERMISSION_DENIED;
7306        }
7307        return checkComponentPermission(permission, pid, uid, -1, true);
7308    }
7309
7310    @Override
7311    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7312        if (permission == null) {
7313            return PackageManager.PERMISSION_DENIED;
7314        }
7315
7316        // We might be performing an operation on behalf of an indirect binder
7317        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7318        // client identity accordingly before proceeding.
7319        Identity tlsIdentity = sCallerIdentity.get();
7320        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7321            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7322                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7323            uid = tlsIdentity.uid;
7324            pid = tlsIdentity.pid;
7325        }
7326
7327        return checkComponentPermission(permission, pid, uid, -1, true);
7328    }
7329
7330    /**
7331     * Binder IPC calls go through the public entry point.
7332     * This can be called with or without the global lock held.
7333     */
7334    int checkCallingPermission(String permission) {
7335        return checkPermission(permission,
7336                Binder.getCallingPid(),
7337                UserHandle.getAppId(Binder.getCallingUid()));
7338    }
7339
7340    /**
7341     * This can be called with or without the global lock held.
7342     */
7343    void enforceCallingPermission(String permission, String func) {
7344        if (checkCallingPermission(permission)
7345                == PackageManager.PERMISSION_GRANTED) {
7346            return;
7347        }
7348
7349        String msg = "Permission Denial: " + func + " from pid="
7350                + Binder.getCallingPid()
7351                + ", uid=" + Binder.getCallingUid()
7352                + " requires " + permission;
7353        Slog.w(TAG, msg);
7354        throw new SecurityException(msg);
7355    }
7356
7357    /**
7358     * Determine if UID is holding permissions required to access {@link Uri} in
7359     * the given {@link ProviderInfo}. Final permission checking is always done
7360     * in {@link ContentProvider}.
7361     */
7362    private final boolean checkHoldingPermissionsLocked(
7363            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7364        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7365                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7366        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7367            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7368                    != PERMISSION_GRANTED) {
7369                return false;
7370            }
7371        }
7372        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7373    }
7374
7375    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7376            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7377        if (pi.applicationInfo.uid == uid) {
7378            return true;
7379        } else if (!pi.exported) {
7380            return false;
7381        }
7382
7383        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7384        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7385        try {
7386            // check if target holds top-level <provider> permissions
7387            if (!readMet && pi.readPermission != null && considerUidPermissions
7388                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7389                readMet = true;
7390            }
7391            if (!writeMet && pi.writePermission != null && considerUidPermissions
7392                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7393                writeMet = true;
7394            }
7395
7396            // track if unprotected read/write is allowed; any denied
7397            // <path-permission> below removes this ability
7398            boolean allowDefaultRead = pi.readPermission == null;
7399            boolean allowDefaultWrite = pi.writePermission == null;
7400
7401            // check if target holds any <path-permission> that match uri
7402            final PathPermission[] pps = pi.pathPermissions;
7403            if (pps != null) {
7404                final String path = grantUri.uri.getPath();
7405                int i = pps.length;
7406                while (i > 0 && (!readMet || !writeMet)) {
7407                    i--;
7408                    PathPermission pp = pps[i];
7409                    if (pp.match(path)) {
7410                        if (!readMet) {
7411                            final String pprperm = pp.getReadPermission();
7412                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7413                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7414                                    + ": match=" + pp.match(path)
7415                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7416                            if (pprperm != null) {
7417                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7418                                        == PERMISSION_GRANTED) {
7419                                    readMet = true;
7420                                } else {
7421                                    allowDefaultRead = false;
7422                                }
7423                            }
7424                        }
7425                        if (!writeMet) {
7426                            final String ppwperm = pp.getWritePermission();
7427                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7428                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7429                                    + ": match=" + pp.match(path)
7430                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7431                            if (ppwperm != null) {
7432                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7433                                        == PERMISSION_GRANTED) {
7434                                    writeMet = true;
7435                                } else {
7436                                    allowDefaultWrite = false;
7437                                }
7438                            }
7439                        }
7440                    }
7441                }
7442            }
7443
7444            // grant unprotected <provider> read/write, if not blocked by
7445            // <path-permission> above
7446            if (allowDefaultRead) readMet = true;
7447            if (allowDefaultWrite) writeMet = true;
7448
7449        } catch (RemoteException e) {
7450            return false;
7451        }
7452
7453        return readMet && writeMet;
7454    }
7455
7456    public int getAppStartMode(int uid, String packageName) {
7457        synchronized (this) {
7458            return checkAllowBackgroundLocked(uid, packageName, -1);
7459        }
7460    }
7461
7462    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7463        UidRecord uidRec = mActiveUids.get(uid);
7464        if (uidRec == null || uidRec.idle) {
7465            if (callingPid >= 0) {
7466                ProcessRecord proc;
7467                synchronized (mPidsSelfLocked) {
7468                    proc = mPidsSelfLocked.get(callingPid);
7469                }
7470                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7471                    // Whoever is instigating this is in the foreground, so we will allow it
7472                    // to go through.
7473                    return ActivityManager.APP_START_MODE_NORMAL;
7474                }
7475            }
7476            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7477                    != AppOpsManager.MODE_ALLOWED) {
7478                return ActivityManager.APP_START_MODE_DELAYED;
7479            }
7480        }
7481        return ActivityManager.APP_START_MODE_NORMAL;
7482    }
7483
7484    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7485        ProviderInfo pi = null;
7486        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7487        if (cpr != null) {
7488            pi = cpr.info;
7489        } else {
7490            try {
7491                pi = AppGlobals.getPackageManager().resolveContentProvider(
7492                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7493            } catch (RemoteException ex) {
7494            }
7495        }
7496        return pi;
7497    }
7498
7499    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7500        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7501        if (targetUris != null) {
7502            return targetUris.get(grantUri);
7503        }
7504        return null;
7505    }
7506
7507    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7508            String targetPkg, int targetUid, GrantUri grantUri) {
7509        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7510        if (targetUris == null) {
7511            targetUris = Maps.newArrayMap();
7512            mGrantedUriPermissions.put(targetUid, targetUris);
7513        }
7514
7515        UriPermission perm = targetUris.get(grantUri);
7516        if (perm == null) {
7517            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7518            targetUris.put(grantUri, perm);
7519        }
7520
7521        return perm;
7522    }
7523
7524    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7525            final int modeFlags) {
7526        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7527        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7528                : UriPermission.STRENGTH_OWNED;
7529
7530        // Root gets to do everything.
7531        if (uid == 0) {
7532            return true;
7533        }
7534
7535        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7536        if (perms == null) return false;
7537
7538        // First look for exact match
7539        final UriPermission exactPerm = perms.get(grantUri);
7540        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7541            return true;
7542        }
7543
7544        // No exact match, look for prefixes
7545        final int N = perms.size();
7546        for (int i = 0; i < N; i++) {
7547            final UriPermission perm = perms.valueAt(i);
7548            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7549                    && perm.getStrength(modeFlags) >= minStrength) {
7550                return true;
7551            }
7552        }
7553
7554        return false;
7555    }
7556
7557    /**
7558     * @param uri This uri must NOT contain an embedded userId.
7559     * @param userId The userId in which the uri is to be resolved.
7560     */
7561    @Override
7562    public int checkUriPermission(Uri uri, int pid, int uid,
7563            final int modeFlags, int userId, IBinder callerToken) {
7564        enforceNotIsolatedCaller("checkUriPermission");
7565
7566        // Another redirected-binder-call permissions check as in
7567        // {@link checkPermissionWithToken}.
7568        Identity tlsIdentity = sCallerIdentity.get();
7569        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7570            uid = tlsIdentity.uid;
7571            pid = tlsIdentity.pid;
7572        }
7573
7574        // Our own process gets to do everything.
7575        if (pid == MY_PID) {
7576            return PackageManager.PERMISSION_GRANTED;
7577        }
7578        synchronized (this) {
7579            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7580                    ? PackageManager.PERMISSION_GRANTED
7581                    : PackageManager.PERMISSION_DENIED;
7582        }
7583    }
7584
7585    /**
7586     * Check if the targetPkg can be granted permission to access uri by
7587     * the callingUid using the given modeFlags.  Throws a security exception
7588     * if callingUid is not allowed to do this.  Returns the uid of the target
7589     * if the URI permission grant should be performed; returns -1 if it is not
7590     * needed (for example targetPkg already has permission to access the URI).
7591     * If you already know the uid of the target, you can supply it in
7592     * lastTargetUid else set that to -1.
7593     */
7594    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7595            final int modeFlags, int lastTargetUid) {
7596        if (!Intent.isAccessUriMode(modeFlags)) {
7597            return -1;
7598        }
7599
7600        if (targetPkg != null) {
7601            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7602                    "Checking grant " + targetPkg + " permission to " + grantUri);
7603        }
7604
7605        final IPackageManager pm = AppGlobals.getPackageManager();
7606
7607        // If this is not a content: uri, we can't do anything with it.
7608        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7609            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7610                    "Can't grant URI permission for non-content URI: " + grantUri);
7611            return -1;
7612        }
7613
7614        final String authority = grantUri.uri.getAuthority();
7615        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7616        if (pi == null) {
7617            Slog.w(TAG, "No content provider found for permission check: " +
7618                    grantUri.uri.toSafeString());
7619            return -1;
7620        }
7621
7622        int targetUid = lastTargetUid;
7623        if (targetUid < 0 && targetPkg != null) {
7624            try {
7625                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7626                        UserHandle.getUserId(callingUid));
7627                if (targetUid < 0) {
7628                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7629                            "Can't grant URI permission no uid for: " + targetPkg);
7630                    return -1;
7631                }
7632            } catch (RemoteException ex) {
7633                return -1;
7634            }
7635        }
7636
7637        if (targetUid >= 0) {
7638            // First...  does the target actually need this permission?
7639            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7640                // No need to grant the target this permission.
7641                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7642                        "Target " + targetPkg + " already has full permission to " + grantUri);
7643                return -1;
7644            }
7645        } else {
7646            // First...  there is no target package, so can anyone access it?
7647            boolean allowed = pi.exported;
7648            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7649                if (pi.readPermission != null) {
7650                    allowed = false;
7651                }
7652            }
7653            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7654                if (pi.writePermission != null) {
7655                    allowed = false;
7656                }
7657            }
7658            if (allowed) {
7659                return -1;
7660            }
7661        }
7662
7663        /* There is a special cross user grant if:
7664         * - The target is on another user.
7665         * - Apps on the current user can access the uri without any uid permissions.
7666         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7667         * grant uri permissions.
7668         */
7669        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7670                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7671                modeFlags, false /*without considering the uid permissions*/);
7672
7673        // Second...  is the provider allowing granting of URI permissions?
7674        if (!specialCrossUserGrant) {
7675            if (!pi.grantUriPermissions) {
7676                throw new SecurityException("Provider " + pi.packageName
7677                        + "/" + pi.name
7678                        + " does not allow granting of Uri permissions (uri "
7679                        + grantUri + ")");
7680            }
7681            if (pi.uriPermissionPatterns != null) {
7682                final int N = pi.uriPermissionPatterns.length;
7683                boolean allowed = false;
7684                for (int i=0; i<N; i++) {
7685                    if (pi.uriPermissionPatterns[i] != null
7686                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7687                        allowed = true;
7688                        break;
7689                    }
7690                }
7691                if (!allowed) {
7692                    throw new SecurityException("Provider " + pi.packageName
7693                            + "/" + pi.name
7694                            + " does not allow granting of permission to path of Uri "
7695                            + grantUri);
7696                }
7697            }
7698        }
7699
7700        // Third...  does the caller itself have permission to access
7701        // this uri?
7702        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7703            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7704                // Require they hold a strong enough Uri permission
7705                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7706                    throw new SecurityException("Uid " + callingUid
7707                            + " does not have permission to uri " + grantUri);
7708                }
7709            }
7710        }
7711        return targetUid;
7712    }
7713
7714    /**
7715     * @param uri This uri must NOT contain an embedded userId.
7716     * @param userId The userId in which the uri is to be resolved.
7717     */
7718    @Override
7719    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7720            final int modeFlags, int userId) {
7721        enforceNotIsolatedCaller("checkGrantUriPermission");
7722        synchronized(this) {
7723            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7724                    new GrantUri(userId, uri, false), modeFlags, -1);
7725        }
7726    }
7727
7728    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7729            final int modeFlags, UriPermissionOwner owner) {
7730        if (!Intent.isAccessUriMode(modeFlags)) {
7731            return;
7732        }
7733
7734        // So here we are: the caller has the assumed permission
7735        // to the uri, and the target doesn't.  Let's now give this to
7736        // the target.
7737
7738        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7739                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7740
7741        final String authority = grantUri.uri.getAuthority();
7742        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7743        if (pi == null) {
7744            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7745            return;
7746        }
7747
7748        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7749            grantUri.prefix = true;
7750        }
7751        final UriPermission perm = findOrCreateUriPermissionLocked(
7752                pi.packageName, targetPkg, targetUid, grantUri);
7753        perm.grantModes(modeFlags, owner);
7754    }
7755
7756    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7757            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7758        if (targetPkg == null) {
7759            throw new NullPointerException("targetPkg");
7760        }
7761        int targetUid;
7762        final IPackageManager pm = AppGlobals.getPackageManager();
7763        try {
7764            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7765        } catch (RemoteException ex) {
7766            return;
7767        }
7768
7769        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7770                targetUid);
7771        if (targetUid < 0) {
7772            return;
7773        }
7774
7775        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7776                owner);
7777    }
7778
7779    static class NeededUriGrants extends ArrayList<GrantUri> {
7780        final String targetPkg;
7781        final int targetUid;
7782        final int flags;
7783
7784        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7785            this.targetPkg = targetPkg;
7786            this.targetUid = targetUid;
7787            this.flags = flags;
7788        }
7789    }
7790
7791    /**
7792     * Like checkGrantUriPermissionLocked, but takes an Intent.
7793     */
7794    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7795            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7796        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7797                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7798                + " clip=" + (intent != null ? intent.getClipData() : null)
7799                + " from " + intent + "; flags=0x"
7800                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7801
7802        if (targetPkg == null) {
7803            throw new NullPointerException("targetPkg");
7804        }
7805
7806        if (intent == null) {
7807            return null;
7808        }
7809        Uri data = intent.getData();
7810        ClipData clip = intent.getClipData();
7811        if (data == null && clip == null) {
7812            return null;
7813        }
7814        // Default userId for uris in the intent (if they don't specify it themselves)
7815        int contentUserHint = intent.getContentUserHint();
7816        if (contentUserHint == UserHandle.USER_CURRENT) {
7817            contentUserHint = UserHandle.getUserId(callingUid);
7818        }
7819        final IPackageManager pm = AppGlobals.getPackageManager();
7820        int targetUid;
7821        if (needed != null) {
7822            targetUid = needed.targetUid;
7823        } else {
7824            try {
7825                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7826                        targetUserId);
7827            } catch (RemoteException ex) {
7828                return null;
7829            }
7830            if (targetUid < 0) {
7831                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7832                        "Can't grant URI permission no uid for: " + targetPkg
7833                        + " on user " + targetUserId);
7834                return null;
7835            }
7836        }
7837        if (data != null) {
7838            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7839            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7840                    targetUid);
7841            if (targetUid > 0) {
7842                if (needed == null) {
7843                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7844                }
7845                needed.add(grantUri);
7846            }
7847        }
7848        if (clip != null) {
7849            for (int i=0; i<clip.getItemCount(); i++) {
7850                Uri uri = clip.getItemAt(i).getUri();
7851                if (uri != null) {
7852                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7853                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7854                            targetUid);
7855                    if (targetUid > 0) {
7856                        if (needed == null) {
7857                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7858                        }
7859                        needed.add(grantUri);
7860                    }
7861                } else {
7862                    Intent clipIntent = clip.getItemAt(i).getIntent();
7863                    if (clipIntent != null) {
7864                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7865                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7866                        if (newNeeded != null) {
7867                            needed = newNeeded;
7868                        }
7869                    }
7870                }
7871            }
7872        }
7873
7874        return needed;
7875    }
7876
7877    /**
7878     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7879     */
7880    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7881            UriPermissionOwner owner) {
7882        if (needed != null) {
7883            for (int i=0; i<needed.size(); i++) {
7884                GrantUri grantUri = needed.get(i);
7885                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7886                        grantUri, needed.flags, owner);
7887            }
7888        }
7889    }
7890
7891    void grantUriPermissionFromIntentLocked(int callingUid,
7892            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7893        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7894                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7895        if (needed == null) {
7896            return;
7897        }
7898
7899        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7900    }
7901
7902    /**
7903     * @param uri This uri must NOT contain an embedded userId.
7904     * @param userId The userId in which the uri is to be resolved.
7905     */
7906    @Override
7907    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7908            final int modeFlags, int userId) {
7909        enforceNotIsolatedCaller("grantUriPermission");
7910        GrantUri grantUri = new GrantUri(userId, uri, false);
7911        synchronized(this) {
7912            final ProcessRecord r = getRecordForAppLocked(caller);
7913            if (r == null) {
7914                throw new SecurityException("Unable to find app for caller "
7915                        + caller
7916                        + " when granting permission to uri " + grantUri);
7917            }
7918            if (targetPkg == null) {
7919                throw new IllegalArgumentException("null target");
7920            }
7921            if (grantUri == null) {
7922                throw new IllegalArgumentException("null uri");
7923            }
7924
7925            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7926                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7927                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7928                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7929
7930            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7931                    UserHandle.getUserId(r.uid));
7932        }
7933    }
7934
7935    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7936        if (perm.modeFlags == 0) {
7937            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7938                    perm.targetUid);
7939            if (perms != null) {
7940                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7941                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7942
7943                perms.remove(perm.uri);
7944                if (perms.isEmpty()) {
7945                    mGrantedUriPermissions.remove(perm.targetUid);
7946                }
7947            }
7948        }
7949    }
7950
7951    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7952        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7953                "Revoking all granted permissions to " + grantUri);
7954
7955        final IPackageManager pm = AppGlobals.getPackageManager();
7956        final String authority = grantUri.uri.getAuthority();
7957        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7958        if (pi == null) {
7959            Slog.w(TAG, "No content provider found for permission revoke: "
7960                    + grantUri.toSafeString());
7961            return;
7962        }
7963
7964        // Does the caller have this permission on the URI?
7965        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7966            // If they don't have direct access to the URI, then revoke any
7967            // ownerless URI permissions that have been granted to them.
7968            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7969            if (perms != null) {
7970                boolean persistChanged = false;
7971                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7972                    final UriPermission perm = it.next();
7973                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7974                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7975                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7976                                "Revoking non-owned " + perm.targetUid
7977                                + " permission to " + perm.uri);
7978                        persistChanged |= perm.revokeModes(
7979                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7980                        if (perm.modeFlags == 0) {
7981                            it.remove();
7982                        }
7983                    }
7984                }
7985                if (perms.isEmpty()) {
7986                    mGrantedUriPermissions.remove(callingUid);
7987                }
7988                if (persistChanged) {
7989                    schedulePersistUriGrants();
7990                }
7991            }
7992            return;
7993        }
7994
7995        boolean persistChanged = false;
7996
7997        // Go through all of the permissions and remove any that match.
7998        int N = mGrantedUriPermissions.size();
7999        for (int i = 0; i < N; i++) {
8000            final int targetUid = mGrantedUriPermissions.keyAt(i);
8001            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8002
8003            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8004                final UriPermission perm = it.next();
8005                if (perm.uri.sourceUserId == grantUri.sourceUserId
8006                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8007                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8008                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8009                    persistChanged |= perm.revokeModes(
8010                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8011                    if (perm.modeFlags == 0) {
8012                        it.remove();
8013                    }
8014                }
8015            }
8016
8017            if (perms.isEmpty()) {
8018                mGrantedUriPermissions.remove(targetUid);
8019                N--;
8020                i--;
8021            }
8022        }
8023
8024        if (persistChanged) {
8025            schedulePersistUriGrants();
8026        }
8027    }
8028
8029    /**
8030     * @param uri This uri must NOT contain an embedded userId.
8031     * @param userId The userId in which the uri is to be resolved.
8032     */
8033    @Override
8034    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8035            int userId) {
8036        enforceNotIsolatedCaller("revokeUriPermission");
8037        synchronized(this) {
8038            final ProcessRecord r = getRecordForAppLocked(caller);
8039            if (r == null) {
8040                throw new SecurityException("Unable to find app for caller "
8041                        + caller
8042                        + " when revoking permission to uri " + uri);
8043            }
8044            if (uri == null) {
8045                Slog.w(TAG, "revokeUriPermission: null uri");
8046                return;
8047            }
8048
8049            if (!Intent.isAccessUriMode(modeFlags)) {
8050                return;
8051            }
8052
8053            final String authority = uri.getAuthority();
8054            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8055            if (pi == null) {
8056                Slog.w(TAG, "No content provider found for permission revoke: "
8057                        + uri.toSafeString());
8058                return;
8059            }
8060
8061            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8062        }
8063    }
8064
8065    /**
8066     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8067     * given package.
8068     *
8069     * @param packageName Package name to match, or {@code null} to apply to all
8070     *            packages.
8071     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8072     *            to all users.
8073     * @param persistable If persistable grants should be removed.
8074     */
8075    private void removeUriPermissionsForPackageLocked(
8076            String packageName, int userHandle, boolean persistable) {
8077        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8078            throw new IllegalArgumentException("Must narrow by either package or user");
8079        }
8080
8081        boolean persistChanged = false;
8082
8083        int N = mGrantedUriPermissions.size();
8084        for (int i = 0; i < N; i++) {
8085            final int targetUid = mGrantedUriPermissions.keyAt(i);
8086            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8087
8088            // Only inspect grants matching user
8089            if (userHandle == UserHandle.USER_ALL
8090                    || userHandle == UserHandle.getUserId(targetUid)) {
8091                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8092                    final UriPermission perm = it.next();
8093
8094                    // Only inspect grants matching package
8095                    if (packageName == null || perm.sourcePkg.equals(packageName)
8096                            || perm.targetPkg.equals(packageName)) {
8097                        persistChanged |= perm.revokeModes(persistable
8098                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8099
8100                        // Only remove when no modes remain; any persisted grants
8101                        // will keep this alive.
8102                        if (perm.modeFlags == 0) {
8103                            it.remove();
8104                        }
8105                    }
8106                }
8107
8108                if (perms.isEmpty()) {
8109                    mGrantedUriPermissions.remove(targetUid);
8110                    N--;
8111                    i--;
8112                }
8113            }
8114        }
8115
8116        if (persistChanged) {
8117            schedulePersistUriGrants();
8118        }
8119    }
8120
8121    @Override
8122    public IBinder newUriPermissionOwner(String name) {
8123        enforceNotIsolatedCaller("newUriPermissionOwner");
8124        synchronized(this) {
8125            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8126            return owner.getExternalTokenLocked();
8127        }
8128    }
8129
8130    @Override
8131    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8132        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8133        synchronized(this) {
8134            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8135            if (r == null) {
8136                throw new IllegalArgumentException("Activity does not exist; token="
8137                        + activityToken);
8138            }
8139            return r.getUriPermissionsLocked().getExternalTokenLocked();
8140        }
8141    }
8142    /**
8143     * @param uri This uri must NOT contain an embedded userId.
8144     * @param sourceUserId The userId in which the uri is to be resolved.
8145     * @param targetUserId The userId of the app that receives the grant.
8146     */
8147    @Override
8148    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8149            final int modeFlags, int sourceUserId, int targetUserId) {
8150        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8151                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8152                "grantUriPermissionFromOwner", null);
8153        synchronized(this) {
8154            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8155            if (owner == null) {
8156                throw new IllegalArgumentException("Unknown owner: " + token);
8157            }
8158            if (fromUid != Binder.getCallingUid()) {
8159                if (Binder.getCallingUid() != Process.myUid()) {
8160                    // Only system code can grant URI permissions on behalf
8161                    // of other users.
8162                    throw new SecurityException("nice try");
8163                }
8164            }
8165            if (targetPkg == null) {
8166                throw new IllegalArgumentException("null target");
8167            }
8168            if (uri == null) {
8169                throw new IllegalArgumentException("null uri");
8170            }
8171
8172            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8173                    modeFlags, owner, targetUserId);
8174        }
8175    }
8176
8177    /**
8178     * @param uri This uri must NOT contain an embedded userId.
8179     * @param userId The userId in which the uri is to be resolved.
8180     */
8181    @Override
8182    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8183        synchronized(this) {
8184            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8185            if (owner == null) {
8186                throw new IllegalArgumentException("Unknown owner: " + token);
8187            }
8188
8189            if (uri == null) {
8190                owner.removeUriPermissionsLocked(mode);
8191            } else {
8192                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8193            }
8194        }
8195    }
8196
8197    private void schedulePersistUriGrants() {
8198        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8199            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8200                    10 * DateUtils.SECOND_IN_MILLIS);
8201        }
8202    }
8203
8204    private void writeGrantedUriPermissions() {
8205        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8206
8207        // Snapshot permissions so we can persist without lock
8208        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8209        synchronized (this) {
8210            final int size = mGrantedUriPermissions.size();
8211            for (int i = 0; i < size; i++) {
8212                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8213                for (UriPermission perm : perms.values()) {
8214                    if (perm.persistedModeFlags != 0) {
8215                        persist.add(perm.snapshot());
8216                    }
8217                }
8218            }
8219        }
8220
8221        FileOutputStream fos = null;
8222        try {
8223            fos = mGrantFile.startWrite();
8224
8225            XmlSerializer out = new FastXmlSerializer();
8226            out.setOutput(fos, StandardCharsets.UTF_8.name());
8227            out.startDocument(null, true);
8228            out.startTag(null, TAG_URI_GRANTS);
8229            for (UriPermission.Snapshot perm : persist) {
8230                out.startTag(null, TAG_URI_GRANT);
8231                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8232                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8233                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8234                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8235                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8236                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8237                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8238                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8239                out.endTag(null, TAG_URI_GRANT);
8240            }
8241            out.endTag(null, TAG_URI_GRANTS);
8242            out.endDocument();
8243
8244            mGrantFile.finishWrite(fos);
8245        } catch (IOException e) {
8246            if (fos != null) {
8247                mGrantFile.failWrite(fos);
8248            }
8249        }
8250    }
8251
8252    private void readGrantedUriPermissionsLocked() {
8253        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8254
8255        final long now = System.currentTimeMillis();
8256
8257        FileInputStream fis = null;
8258        try {
8259            fis = mGrantFile.openRead();
8260            final XmlPullParser in = Xml.newPullParser();
8261            in.setInput(fis, StandardCharsets.UTF_8.name());
8262
8263            int type;
8264            while ((type = in.next()) != END_DOCUMENT) {
8265                final String tag = in.getName();
8266                if (type == START_TAG) {
8267                    if (TAG_URI_GRANT.equals(tag)) {
8268                        final int sourceUserId;
8269                        final int targetUserId;
8270                        final int userHandle = readIntAttribute(in,
8271                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8272                        if (userHandle != UserHandle.USER_NULL) {
8273                            // For backwards compatibility.
8274                            sourceUserId = userHandle;
8275                            targetUserId = userHandle;
8276                        } else {
8277                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8278                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8279                        }
8280                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8281                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8282                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8283                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8284                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8285                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8286
8287                        // Sanity check that provider still belongs to source package
8288                        final ProviderInfo pi = getProviderInfoLocked(
8289                                uri.getAuthority(), sourceUserId);
8290                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8291                            int targetUid = -1;
8292                            try {
8293                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8294                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8295                            } catch (RemoteException e) {
8296                            }
8297                            if (targetUid != -1) {
8298                                final UriPermission perm = findOrCreateUriPermissionLocked(
8299                                        sourcePkg, targetPkg, targetUid,
8300                                        new GrantUri(sourceUserId, uri, prefix));
8301                                perm.initPersistedModes(modeFlags, createdTime);
8302                            }
8303                        } else {
8304                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8305                                    + " but instead found " + pi);
8306                        }
8307                    }
8308                }
8309            }
8310        } catch (FileNotFoundException e) {
8311            // Missing grants is okay
8312        } catch (IOException e) {
8313            Slog.wtf(TAG, "Failed reading Uri grants", e);
8314        } catch (XmlPullParserException e) {
8315            Slog.wtf(TAG, "Failed reading Uri grants", e);
8316        } finally {
8317            IoUtils.closeQuietly(fis);
8318        }
8319    }
8320
8321    /**
8322     * @param uri This uri must NOT contain an embedded userId.
8323     * @param userId The userId in which the uri is to be resolved.
8324     */
8325    @Override
8326    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8327        enforceNotIsolatedCaller("takePersistableUriPermission");
8328
8329        Preconditions.checkFlagsArgument(modeFlags,
8330                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8331
8332        synchronized (this) {
8333            final int callingUid = Binder.getCallingUid();
8334            boolean persistChanged = false;
8335            GrantUri grantUri = new GrantUri(userId, uri, false);
8336
8337            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8338                    new GrantUri(userId, uri, false));
8339            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8340                    new GrantUri(userId, uri, true));
8341
8342            final boolean exactValid = (exactPerm != null)
8343                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8344            final boolean prefixValid = (prefixPerm != null)
8345                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8346
8347            if (!(exactValid || prefixValid)) {
8348                throw new SecurityException("No persistable permission grants found for UID "
8349                        + callingUid + " and Uri " + grantUri.toSafeString());
8350            }
8351
8352            if (exactValid) {
8353                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8354            }
8355            if (prefixValid) {
8356                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8357            }
8358
8359            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8360
8361            if (persistChanged) {
8362                schedulePersistUriGrants();
8363            }
8364        }
8365    }
8366
8367    /**
8368     * @param uri This uri must NOT contain an embedded userId.
8369     * @param userId The userId in which the uri is to be resolved.
8370     */
8371    @Override
8372    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8373        enforceNotIsolatedCaller("releasePersistableUriPermission");
8374
8375        Preconditions.checkFlagsArgument(modeFlags,
8376                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8377
8378        synchronized (this) {
8379            final int callingUid = Binder.getCallingUid();
8380            boolean persistChanged = false;
8381
8382            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8383                    new GrantUri(userId, uri, false));
8384            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8385                    new GrantUri(userId, uri, true));
8386            if (exactPerm == null && prefixPerm == null) {
8387                throw new SecurityException("No permission grants found for UID " + callingUid
8388                        + " and Uri " + uri.toSafeString());
8389            }
8390
8391            if (exactPerm != null) {
8392                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8393                removeUriPermissionIfNeededLocked(exactPerm);
8394            }
8395            if (prefixPerm != null) {
8396                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8397                removeUriPermissionIfNeededLocked(prefixPerm);
8398            }
8399
8400            if (persistChanged) {
8401                schedulePersistUriGrants();
8402            }
8403        }
8404    }
8405
8406    /**
8407     * Prune any older {@link UriPermission} for the given UID until outstanding
8408     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8409     *
8410     * @return if any mutations occured that require persisting.
8411     */
8412    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8413        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8414        if (perms == null) return false;
8415        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8416
8417        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8418        for (UriPermission perm : perms.values()) {
8419            if (perm.persistedModeFlags != 0) {
8420                persisted.add(perm);
8421            }
8422        }
8423
8424        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8425        if (trimCount <= 0) return false;
8426
8427        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8428        for (int i = 0; i < trimCount; i++) {
8429            final UriPermission perm = persisted.get(i);
8430
8431            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8432                    "Trimming grant created at " + perm.persistedCreateTime);
8433
8434            perm.releasePersistableModes(~0);
8435            removeUriPermissionIfNeededLocked(perm);
8436        }
8437
8438        return true;
8439    }
8440
8441    @Override
8442    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8443            String packageName, boolean incoming) {
8444        enforceNotIsolatedCaller("getPersistedUriPermissions");
8445        Preconditions.checkNotNull(packageName, "packageName");
8446
8447        final int callingUid = Binder.getCallingUid();
8448        final IPackageManager pm = AppGlobals.getPackageManager();
8449        try {
8450            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8451                    UserHandle.getUserId(callingUid));
8452            if (packageUid != callingUid) {
8453                throw new SecurityException(
8454                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8455            }
8456        } catch (RemoteException e) {
8457            throw new SecurityException("Failed to verify package name ownership");
8458        }
8459
8460        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8461        synchronized (this) {
8462            if (incoming) {
8463                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8464                        callingUid);
8465                if (perms == null) {
8466                    Slog.w(TAG, "No permission grants found for " + packageName);
8467                } else {
8468                    for (UriPermission perm : perms.values()) {
8469                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8470                            result.add(perm.buildPersistedPublicApiObject());
8471                        }
8472                    }
8473                }
8474            } else {
8475                final int size = mGrantedUriPermissions.size();
8476                for (int i = 0; i < size; i++) {
8477                    final ArrayMap<GrantUri, UriPermission> perms =
8478                            mGrantedUriPermissions.valueAt(i);
8479                    for (UriPermission perm : perms.values()) {
8480                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8481                            result.add(perm.buildPersistedPublicApiObject());
8482                        }
8483                    }
8484                }
8485            }
8486        }
8487        return new ParceledListSlice<android.content.UriPermission>(result);
8488    }
8489
8490    @Override
8491    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8492            String packageName, int userId) {
8493        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8494                "getGrantedUriPermissions");
8495
8496        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8497        synchronized (this) {
8498            final int size = mGrantedUriPermissions.size();
8499            for (int i = 0; i < size; i++) {
8500                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8501                for (UriPermission perm : perms.values()) {
8502                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8503                            && perm.persistedModeFlags != 0) {
8504                        result.add(perm.buildPersistedPublicApiObject());
8505                    }
8506                }
8507            }
8508        }
8509        return new ParceledListSlice<android.content.UriPermission>(result);
8510    }
8511
8512    @Override
8513    public void clearGrantedUriPermissions(String packageName, int userId) {
8514        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8515                "clearGrantedUriPermissions");
8516        removeUriPermissionsForPackageLocked(packageName, userId, true);
8517    }
8518
8519    @Override
8520    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8521        synchronized (this) {
8522            ProcessRecord app =
8523                who != null ? getRecordForAppLocked(who) : null;
8524            if (app == null) return;
8525
8526            Message msg = Message.obtain();
8527            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8528            msg.obj = app;
8529            msg.arg1 = waiting ? 1 : 0;
8530            mUiHandler.sendMessage(msg);
8531        }
8532    }
8533
8534    @Override
8535    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8536        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8537        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8538        outInfo.availMem = Process.getFreeMemory();
8539        outInfo.totalMem = Process.getTotalMemory();
8540        outInfo.threshold = homeAppMem;
8541        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8542        outInfo.hiddenAppThreshold = cachedAppMem;
8543        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8544                ProcessList.SERVICE_ADJ);
8545        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8546                ProcessList.VISIBLE_APP_ADJ);
8547        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8548                ProcessList.FOREGROUND_APP_ADJ);
8549    }
8550
8551    // =========================================================
8552    // TASK MANAGEMENT
8553    // =========================================================
8554
8555    @Override
8556    public List<IAppTask> getAppTasks(String callingPackage) {
8557        int callingUid = Binder.getCallingUid();
8558        long ident = Binder.clearCallingIdentity();
8559
8560        synchronized(this) {
8561            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8562            try {
8563                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8564
8565                final int N = mRecentTasks.size();
8566                for (int i = 0; i < N; i++) {
8567                    TaskRecord tr = mRecentTasks.get(i);
8568                    // Skip tasks that do not match the caller.  We don't need to verify
8569                    // callingPackage, because we are also limiting to callingUid and know
8570                    // that will limit to the correct security sandbox.
8571                    if (tr.effectiveUid != callingUid) {
8572                        continue;
8573                    }
8574                    Intent intent = tr.getBaseIntent();
8575                    if (intent == null ||
8576                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8577                        continue;
8578                    }
8579                    ActivityManager.RecentTaskInfo taskInfo =
8580                            createRecentTaskInfoFromTaskRecord(tr);
8581                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8582                    list.add(taskImpl);
8583                }
8584            } finally {
8585                Binder.restoreCallingIdentity(ident);
8586            }
8587            return list;
8588        }
8589    }
8590
8591    @Override
8592    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8593        final int callingUid = Binder.getCallingUid();
8594        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8595
8596        synchronized(this) {
8597            if (DEBUG_ALL) Slog.v(
8598                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8599
8600            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8601                    callingUid);
8602
8603            // TODO: Improve with MRU list from all ActivityStacks.
8604            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8605        }
8606
8607        return list;
8608    }
8609
8610    /**
8611     * Creates a new RecentTaskInfo from a TaskRecord.
8612     */
8613    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8614        // Update the task description to reflect any changes in the task stack
8615        tr.updateTaskDescription();
8616
8617        // Compose the recent task info
8618        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8619        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8620        rti.persistentId = tr.taskId;
8621        rti.baseIntent = new Intent(tr.getBaseIntent());
8622        rti.origActivity = tr.origActivity;
8623        rti.realActivity = tr.realActivity;
8624        rti.description = tr.lastDescription;
8625        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8626        rti.userId = tr.userId;
8627        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8628        rti.firstActiveTime = tr.firstActiveTime;
8629        rti.lastActiveTime = tr.lastActiveTime;
8630        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8631        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8632        rti.numActivities = 0;
8633        if (tr.mBounds != null) {
8634            rti.bounds = new Rect(tr.mBounds);
8635        }
8636        rti.isDockable = tr.canGoInDockedStack();
8637
8638        ActivityRecord base = null;
8639        ActivityRecord top = null;
8640        ActivityRecord tmp;
8641
8642        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8643            tmp = tr.mActivities.get(i);
8644            if (tmp.finishing) {
8645                continue;
8646            }
8647            base = tmp;
8648            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8649                top = base;
8650            }
8651            rti.numActivities++;
8652        }
8653
8654        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8655        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8656
8657        return rti;
8658    }
8659
8660    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8661        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8662                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8663        if (!allowed) {
8664            if (checkPermission(android.Manifest.permission.GET_TASKS,
8665                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8666                // Temporary compatibility: some existing apps on the system image may
8667                // still be requesting the old permission and not switched to the new
8668                // one; if so, we'll still allow them full access.  This means we need
8669                // to see if they are holding the old permission and are a system app.
8670                try {
8671                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8672                        allowed = true;
8673                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8674                                + " is using old GET_TASKS but privileged; allowing");
8675                    }
8676                } catch (RemoteException e) {
8677                }
8678            }
8679        }
8680        if (!allowed) {
8681            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8682                    + " does not hold REAL_GET_TASKS; limiting output");
8683        }
8684        return allowed;
8685    }
8686
8687    @Override
8688    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8689        final int callingUid = Binder.getCallingUid();
8690        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8691                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8692
8693        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8694        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8695        synchronized (this) {
8696            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8697                    callingUid);
8698            final boolean detailed = checkCallingPermission(
8699                    android.Manifest.permission.GET_DETAILED_TASKS)
8700                    == PackageManager.PERMISSION_GRANTED;
8701
8702            mRecentTasks.loadUserRecentsLocked(userId);
8703
8704            final int recentsCount = mRecentTasks.size();
8705            ArrayList<ActivityManager.RecentTaskInfo> res =
8706                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8707
8708            final Set<Integer> includedUsers;
8709            if (includeProfiles) {
8710                includedUsers = mUserController.getProfileIds(userId);
8711            } else {
8712                includedUsers = new HashSet<>();
8713            }
8714            includedUsers.add(Integer.valueOf(userId));
8715
8716            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8717                TaskRecord tr = mRecentTasks.get(i);
8718                // Only add calling user or related users recent tasks
8719                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8720                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8721                    continue;
8722                }
8723
8724                if (tr.realActivitySuspended) {
8725                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8726                    continue;
8727                }
8728
8729                // Return the entry if desired by the caller.  We always return
8730                // the first entry, because callers always expect this to be the
8731                // foreground app.  We may filter others if the caller has
8732                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8733                // we should exclude the entry.
8734
8735                if (i == 0
8736                        || withExcluded
8737                        || (tr.intent == null)
8738                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8739                                == 0)) {
8740                    if (!allowed) {
8741                        // If the caller doesn't have the GET_TASKS permission, then only
8742                        // allow them to see a small subset of tasks -- their own and home.
8743                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8744                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8745                            continue;
8746                        }
8747                    }
8748                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8749                        if (tr.stack != null && tr.stack.isHomeStack()) {
8750                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8751                                    "Skipping, home stack task: " + tr);
8752                            continue;
8753                        }
8754                    }
8755                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
8756                        if (tr.stack != null && tr.stack.isDockedStack()) {
8757                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8758                                    "Skipping, docked stack task: " + tr);
8759                            continue;
8760                        }
8761                    }
8762                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8763                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8764                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8765                                    "Skipping, pinned stack task: " + tr);
8766                            continue;
8767                        }
8768                    }
8769                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8770                        // Don't include auto remove tasks that are finished or finishing.
8771                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8772                                "Skipping, auto-remove without activity: " + tr);
8773                        continue;
8774                    }
8775                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8776                            && !tr.isAvailable) {
8777                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8778                                "Skipping, unavail real act: " + tr);
8779                        continue;
8780                    }
8781
8782                    if (!tr.mUserSetupComplete) {
8783                        // Don't include task launched while user is not done setting-up.
8784                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8785                                "Skipping, user setup not complete: " + tr);
8786                        continue;
8787                    }
8788
8789                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8790                    if (!detailed) {
8791                        rti.baseIntent.replaceExtras((Bundle)null);
8792                    }
8793
8794                    res.add(rti);
8795                    maxNum--;
8796                }
8797            }
8798            return res;
8799        }
8800    }
8801
8802    @Override
8803    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8804        synchronized (this) {
8805            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8806                    "getTaskThumbnail()");
8807            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8808                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8809            if (tr != null) {
8810                return tr.getTaskThumbnailLocked();
8811            }
8812        }
8813        return null;
8814    }
8815
8816    @Override
8817    public int addAppTask(IBinder activityToken, Intent intent,
8818            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8819        final int callingUid = Binder.getCallingUid();
8820        final long callingIdent = Binder.clearCallingIdentity();
8821
8822        try {
8823            synchronized (this) {
8824                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8825                if (r == null) {
8826                    throw new IllegalArgumentException("Activity does not exist; token="
8827                            + activityToken);
8828                }
8829                ComponentName comp = intent.getComponent();
8830                if (comp == null) {
8831                    throw new IllegalArgumentException("Intent " + intent
8832                            + " must specify explicit component");
8833                }
8834                if (thumbnail.getWidth() != mThumbnailWidth
8835                        || thumbnail.getHeight() != mThumbnailHeight) {
8836                    throw new IllegalArgumentException("Bad thumbnail size: got "
8837                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8838                            + mThumbnailWidth + "x" + mThumbnailHeight);
8839                }
8840                if (intent.getSelector() != null) {
8841                    intent.setSelector(null);
8842                }
8843                if (intent.getSourceBounds() != null) {
8844                    intent.setSourceBounds(null);
8845                }
8846                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8847                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8848                        // The caller has added this as an auto-remove task...  that makes no
8849                        // sense, so turn off auto-remove.
8850                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8851                    }
8852                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8853                    // Must be a new task.
8854                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8855                }
8856                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8857                    mLastAddedTaskActivity = null;
8858                }
8859                ActivityInfo ainfo = mLastAddedTaskActivity;
8860                if (ainfo == null) {
8861                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8862                            comp, 0, UserHandle.getUserId(callingUid));
8863                    if (ainfo.applicationInfo.uid != callingUid) {
8864                        throw new SecurityException(
8865                                "Can't add task for another application: target uid="
8866                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8867                    }
8868                }
8869
8870                // Use the full screen as the context for the task thumbnail
8871                final Point displaySize = new Point();
8872                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
8873                r.task.stack.getDisplaySize(displaySize);
8874                thumbnailInfo.taskWidth = displaySize.x;
8875                thumbnailInfo.taskHeight = displaySize.y;
8876                thumbnailInfo.screenOrientation = mConfiguration.orientation;
8877
8878                TaskRecord task = new TaskRecord(this,
8879                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
8880                        ainfo, intent, description, thumbnailInfo);
8881
8882                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8883                if (trimIdx >= 0) {
8884                    // If this would have caused a trim, then we'll abort because that
8885                    // means it would be added at the end of the list but then just removed.
8886                    return INVALID_TASK_ID;
8887                }
8888
8889                final int N = mRecentTasks.size();
8890                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8891                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8892                    tr.removedFromRecents();
8893                }
8894
8895                task.inRecents = true;
8896                mRecentTasks.add(task);
8897                r.task.stack.addTask(task, false, "addAppTask");
8898
8899                task.setLastThumbnailLocked(thumbnail);
8900                task.freeLastThumbnail();
8901
8902                return task.taskId;
8903            }
8904        } finally {
8905            Binder.restoreCallingIdentity(callingIdent);
8906        }
8907    }
8908
8909    @Override
8910    public Point getAppTaskThumbnailSize() {
8911        synchronized (this) {
8912            return new Point(mThumbnailWidth,  mThumbnailHeight);
8913        }
8914    }
8915
8916    @Override
8917    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8918        synchronized (this) {
8919            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8920            if (r != null) {
8921                r.setTaskDescription(td);
8922                r.task.updateTaskDescription();
8923            }
8924        }
8925    }
8926
8927    @Override
8928    public void setTaskResizeable(int taskId, int resizeableMode) {
8929        synchronized (this) {
8930            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8931                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8932            if (task == null) {
8933                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8934                return;
8935            }
8936            if (task.mResizeMode != resizeableMode) {
8937                task.mResizeMode = resizeableMode;
8938                mWindowManager.setTaskResizeable(taskId, resizeableMode);
8939                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
8940                mStackSupervisor.resumeFocusedStackTopActivityLocked();
8941            }
8942        }
8943    }
8944
8945    @Override
8946    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
8947        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
8948        long ident = Binder.clearCallingIdentity();
8949        try {
8950            synchronized (this) {
8951                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8952                if (task == null) {
8953                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8954                    return;
8955                }
8956                int stackId = task.stack.mStackId;
8957                // We allow the task to scroll instead of resizing if this is a non-resizeable task
8958                // in crop windows resize mode or if the task size is affected by the docked stack
8959                // changing size. No need to update configuration.
8960                if (bounds != null && task.inCropWindowsResizeMode()
8961                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
8962                    mWindowManager.scrollTask(task.taskId, bounds);
8963                    return;
8964                }
8965
8966                // Place the task in the right stack if it isn't there already based on
8967                // the requested bounds.
8968                // The stack transition logic is:
8969                // - a null bounds on a freeform task moves that task to fullscreen
8970                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
8971                //   that task to freeform
8972                // - otherwise the task is not moved
8973                if (!StackId.isTaskResizeAllowed(stackId)) {
8974                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
8975                }
8976                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
8977                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
8978                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
8979                    stackId = FREEFORM_WORKSPACE_STACK_ID;
8980                }
8981                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
8982                if (stackId != task.stack.mStackId) {
8983                    mStackSupervisor.moveTaskToStackUncheckedLocked(
8984                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
8985                    preserveWindow = false;
8986                }
8987
8988                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
8989            }
8990        } finally {
8991            Binder.restoreCallingIdentity(ident);
8992        }
8993    }
8994
8995    @Override
8996    public Rect getTaskBounds(int taskId) {
8997        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
8998        long ident = Binder.clearCallingIdentity();
8999        Rect rect = new Rect();
9000        try {
9001            synchronized (this) {
9002                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9003                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9004                if (task == null) {
9005                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9006                    return rect;
9007                }
9008                if (task.stack != null) {
9009                    // Return the bounds from window manager since it will be adjusted for various
9010                    // things like the presense of a docked stack for tasks that aren't resizeable.
9011                    mWindowManager.getTaskBounds(task.taskId, rect);
9012                } else {
9013                    // Task isn't in window manager yet since it isn't associated with a stack.
9014                    // Return the persist value from activity manager
9015                    if (task.mBounds != null) {
9016                        rect.set(task.mBounds);
9017                    } else if (task.mLastNonFullscreenBounds != null) {
9018                        rect.set(task.mLastNonFullscreenBounds);
9019                    }
9020                }
9021            }
9022        } finally {
9023            Binder.restoreCallingIdentity(ident);
9024        }
9025        return rect;
9026    }
9027
9028    @Override
9029    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9030        if (userId != UserHandle.getCallingUserId()) {
9031            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9032                    "getTaskDescriptionIcon");
9033        }
9034        final File passedIconFile = new File(filePath);
9035        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9036                passedIconFile.getName());
9037        if (!legitIconFile.getPath().equals(filePath)
9038                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9039            throw new IllegalArgumentException("Bad file path: " + filePath
9040                    + " passed for userId " + userId);
9041        }
9042        return mRecentTasks.getTaskDescriptionIcon(filePath);
9043    }
9044
9045    @Override
9046    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9047            throws RemoteException {
9048        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9049                opts.getCustomInPlaceResId() == 0) {
9050            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9051                    "with valid animation");
9052        }
9053        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
9054        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9055                opts.getCustomInPlaceResId());
9056        mWindowManager.executeAppTransition();
9057    }
9058
9059    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9060            boolean removeFromRecents) {
9061        if (removeFromRecents) {
9062            mRecentTasks.remove(tr);
9063            tr.removedFromRecents();
9064        }
9065        ComponentName component = tr.getBaseIntent().getComponent();
9066        if (component == null) {
9067            Slog.w(TAG, "No component for base intent of task: " + tr);
9068            return;
9069        }
9070
9071        // Find any running services associated with this app and stop if needed.
9072        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9073
9074        if (!killProcess) {
9075            return;
9076        }
9077
9078        // Determine if the process(es) for this task should be killed.
9079        final String pkg = component.getPackageName();
9080        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9081        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9082        for (int i = 0; i < pmap.size(); i++) {
9083
9084            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9085            for (int j = 0; j < uids.size(); j++) {
9086                ProcessRecord proc = uids.valueAt(j);
9087                if (proc.userId != tr.userId) {
9088                    // Don't kill process for a different user.
9089                    continue;
9090                }
9091                if (proc == mHomeProcess) {
9092                    // Don't kill the home process along with tasks from the same package.
9093                    continue;
9094                }
9095                if (!proc.pkgList.containsKey(pkg)) {
9096                    // Don't kill process that is not associated with this task.
9097                    continue;
9098                }
9099
9100                for (int k = 0; k < proc.activities.size(); k++) {
9101                    TaskRecord otherTask = proc.activities.get(k).task;
9102                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9103                        // Don't kill process(es) that has an activity in a different task that is
9104                        // also in recents.
9105                        return;
9106                    }
9107                }
9108
9109                if (proc.foregroundServices) {
9110                    // Don't kill process(es) with foreground service.
9111                    return;
9112                }
9113
9114                // Add process to kill list.
9115                procsToKill.add(proc);
9116            }
9117        }
9118
9119        // Kill the running processes.
9120        for (int i = 0; i < procsToKill.size(); i++) {
9121            ProcessRecord pr = procsToKill.get(i);
9122            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
9123                    && pr.curReceiver == null) {
9124                pr.kill("remove task", true);
9125            } else {
9126                // We delay killing processes that are not in the background or running a receiver.
9127                pr.waitingToKill = "remove task";
9128            }
9129        }
9130    }
9131
9132    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9133        // Remove all tasks with activities in the specified package from the list of recent tasks
9134        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9135            TaskRecord tr = mRecentTasks.get(i);
9136            if (tr.userId != userId) continue;
9137
9138            ComponentName cn = tr.intent.getComponent();
9139            if (cn != null && cn.getPackageName().equals(packageName)) {
9140                // If the package name matches, remove the task.
9141                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9142            }
9143        }
9144    }
9145
9146    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9147            int userId) {
9148
9149        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9150            TaskRecord tr = mRecentTasks.get(i);
9151            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9152                continue;
9153            }
9154
9155            ComponentName cn = tr.intent.getComponent();
9156            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9157                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9158            if (sameComponent) {
9159                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9160            }
9161        }
9162    }
9163
9164    /**
9165     * Removes the task with the specified task id.
9166     *
9167     * @param taskId Identifier of the task to be removed.
9168     * @param killProcess Kill any process associated with the task if possible.
9169     * @param removeFromRecents Whether to also remove the task from recents.
9170     * @return Returns true if the given task was found and removed.
9171     */
9172    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9173            boolean removeFromRecents) {
9174        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9175                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9176        if (tr != null) {
9177            tr.removeTaskActivitiesLocked();
9178            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9179            if (tr.isPersistable) {
9180                notifyTaskPersisterLocked(null, true);
9181            }
9182            return true;
9183        }
9184        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9185        return false;
9186    }
9187
9188    @Override
9189    public boolean removeTask(int taskId) {
9190        synchronized (this) {
9191            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
9192                    "removeTask()");
9193            long ident = Binder.clearCallingIdentity();
9194            try {
9195                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9196            } finally {
9197                Binder.restoreCallingIdentity(ident);
9198            }
9199        }
9200    }
9201
9202    /**
9203     * TODO: Add mController hook
9204     */
9205    @Override
9206    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9207        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9208
9209        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9210        synchronized(this) {
9211            moveTaskToFrontLocked(taskId, flags, bOptions);
9212        }
9213    }
9214
9215    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9216        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9217
9218        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9219                Binder.getCallingUid(), -1, -1, "Task to front")) {
9220            ActivityOptions.abort(options);
9221            return;
9222        }
9223        final long origId = Binder.clearCallingIdentity();
9224        try {
9225            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9226            if (task == null) {
9227                Slog.d(TAG, "Could not find task for id: "+ taskId);
9228                return;
9229            }
9230            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9231                mStackSupervisor.showLockTaskToast();
9232                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9233                return;
9234            }
9235            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9236            if (prev != null && prev.isRecentsActivity()) {
9237                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9238            }
9239            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9240        } finally {
9241            Binder.restoreCallingIdentity(origId);
9242        }
9243        ActivityOptions.abort(options);
9244    }
9245
9246    /**
9247     * Moves an activity, and all of the other activities within the same task, to the bottom
9248     * of the history stack.  The activity's order within the task is unchanged.
9249     *
9250     * @param token A reference to the activity we wish to move
9251     * @param nonRoot If false then this only works if the activity is the root
9252     *                of a task; if true it will work for any activity in a task.
9253     * @return Returns true if the move completed, false if not.
9254     */
9255    @Override
9256    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9257        enforceNotIsolatedCaller("moveActivityTaskToBack");
9258        synchronized(this) {
9259            final long origId = Binder.clearCallingIdentity();
9260            try {
9261                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9262                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9263                if (task != null) {
9264                    if (mStackSupervisor.isLockedTask(task)) {
9265                        mStackSupervisor.showLockTaskToast();
9266                        return false;
9267                    }
9268                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9269                }
9270            } finally {
9271                Binder.restoreCallingIdentity(origId);
9272            }
9273        }
9274        return false;
9275    }
9276
9277    @Override
9278    public void moveTaskBackwards(int task) {
9279        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9280                "moveTaskBackwards()");
9281
9282        synchronized(this) {
9283            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9284                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9285                return;
9286            }
9287            final long origId = Binder.clearCallingIdentity();
9288            moveTaskBackwardsLocked(task);
9289            Binder.restoreCallingIdentity(origId);
9290        }
9291    }
9292
9293    private final void moveTaskBackwardsLocked(int task) {
9294        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9295    }
9296
9297    @Override
9298    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9299            IActivityContainerCallback callback) throws RemoteException {
9300        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9301        synchronized (this) {
9302            if (parentActivityToken == null) {
9303                throw new IllegalArgumentException("parent token must not be null");
9304            }
9305            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9306            if (r == null) {
9307                return null;
9308            }
9309            if (callback == null) {
9310                throw new IllegalArgumentException("callback must not be null");
9311            }
9312            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9313        }
9314    }
9315
9316    @Override
9317    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9318        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9319        synchronized (this) {
9320            mStackSupervisor.deleteActivityContainer(container);
9321        }
9322    }
9323
9324    @Override
9325    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9326        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9327        synchronized (this) {
9328            final int stackId = mStackSupervisor.getNextStackId();
9329            final ActivityStack stack =
9330                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9331            if (stack == null) {
9332                return null;
9333            }
9334            return stack.mActivityContainer;
9335        }
9336    }
9337
9338    @Override
9339    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9340        synchronized (this) {
9341            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9342            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9343                return stack.mActivityContainer.getDisplayId();
9344            }
9345            return Display.DEFAULT_DISPLAY;
9346        }
9347    }
9348
9349    @Override
9350    public int getActivityStackId(IBinder token) throws RemoteException {
9351        synchronized (this) {
9352            ActivityStack stack = ActivityRecord.getStackLocked(token);
9353            if (stack == null) {
9354                return INVALID_STACK_ID;
9355            }
9356            return stack.mStackId;
9357        }
9358    }
9359
9360    @Override
9361    public void exitFreeformMode(IBinder token) throws RemoteException {
9362        synchronized (this) {
9363            long ident = Binder.clearCallingIdentity();
9364            try {
9365                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9366                if (r == null) {
9367                    throw new IllegalArgumentException(
9368                            "exitFreeformMode: No activity record matching token=" + token);
9369                }
9370                final ActivityStack stack = r.getStackLocked(token);
9371                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9372                    throw new IllegalStateException(
9373                            "exitFreeformMode: You can only go fullscreen from freeform.");
9374                }
9375                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9376                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9377                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9378            } finally {
9379                Binder.restoreCallingIdentity(ident);
9380            }
9381        }
9382    }
9383
9384    @Override
9385    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9386        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9387        if (stackId == HOME_STACK_ID) {
9388            throw new IllegalArgumentException(
9389                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9390        }
9391        synchronized (this) {
9392            long ident = Binder.clearCallingIdentity();
9393            try {
9394                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9395                        + " to stackId=" + stackId + " toTop=" + toTop);
9396                if (stackId == DOCKED_STACK_ID) {
9397                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9398                            null /* initialBounds */);
9399                }
9400                mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9401                        "moveTaskToStack", ANIMATE);
9402            } finally {
9403                Binder.restoreCallingIdentity(ident);
9404            }
9405        }
9406    }
9407
9408    /**
9409     * Moves the input task to the docked stack.
9410     *
9411     * @param taskId Id of task to move.
9412     * @param createMode The mode the docked stack should be created in if it doesn't exist
9413     *                   already. See
9414     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9415     *                   and
9416     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9417     * @param toTop If the task and stack should be moved to the top.
9418     * @param animate Whether we should play an animation for the moving the task
9419     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9420     *                      docked stack. Pass {@code null} to use default bounds.
9421     */
9422    @Override
9423    public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9424            Rect initialBounds) {
9425        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9426        synchronized (this) {
9427            long ident = Binder.clearCallingIdentity();
9428            try {
9429                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9430                        + " to createMode=" + createMode + " toTop=" + toTop);
9431                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9432                mStackSupervisor.moveTaskToStackLocked(taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9433                        "moveTaskToDockedStack", animate);
9434            } finally {
9435                Binder.restoreCallingIdentity(ident);
9436            }
9437        }
9438    }
9439
9440    /**
9441     * Moves the top activity in the input stackId to the pinned stack.
9442     *
9443     * @param stackId Id of stack to move the top activity to pinned stack.
9444     * @param bounds Bounds to use for pinned stack.
9445     *
9446     * @return True if the top activity of the input stack was successfully moved to the pinned
9447     *          stack.
9448     */
9449    @Override
9450    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9451        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9452        synchronized (this) {
9453            if (!mSupportsPictureInPicture) {
9454                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9455                        + "Device doesn't support picture-in-pciture mode");
9456            }
9457
9458            long ident = Binder.clearCallingIdentity();
9459            try {
9460                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9461            } finally {
9462                Binder.restoreCallingIdentity(ident);
9463            }
9464        }
9465    }
9466
9467    @Override
9468    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9469            boolean preserveWindows, boolean animate) {
9470        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9471        long ident = Binder.clearCallingIdentity();
9472        try {
9473            synchronized (this) {
9474                if (animate) {
9475                    if (stackId == PINNED_STACK_ID) {
9476                        mWindowManager.animateResizePinnedStack(bounds);
9477                    } else {
9478                        throw new IllegalArgumentException("Stack: " + stackId
9479                                + " doesn't support animated resize.");
9480                    }
9481                } else {
9482                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9483                            null /* tempTaskInsetBounds */, preserveWindows,
9484                            allowResizeInDockedMode);
9485                }
9486            }
9487        } finally {
9488            Binder.restoreCallingIdentity(ident);
9489        }
9490    }
9491
9492    @Override
9493    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9494            Rect tempDockedTaskInsetBounds,
9495            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9496        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9497                "resizeDockedStack()");
9498        long ident = Binder.clearCallingIdentity();
9499        try {
9500            synchronized (this) {
9501                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9502                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9503                        PRESERVE_WINDOWS);
9504            }
9505        } finally {
9506            Binder.restoreCallingIdentity(ident);
9507        }
9508    }
9509
9510    @Override
9511    public void positionTaskInStack(int taskId, int stackId, int position) {
9512        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9513        if (stackId == HOME_STACK_ID) {
9514            throw new IllegalArgumentException(
9515                    "positionTaskInStack: Attempt to change the position of task "
9516                    + taskId + " in/to home stack");
9517        }
9518        synchronized (this) {
9519            long ident = Binder.clearCallingIdentity();
9520            try {
9521                if (DEBUG_STACK) Slog.d(TAG_STACK,
9522                        "positionTaskInStack: positioning task=" + taskId
9523                        + " in stackId=" + stackId + " at position=" + position);
9524                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9525            } finally {
9526                Binder.restoreCallingIdentity(ident);
9527            }
9528        }
9529    }
9530
9531    @Override
9532    public List<StackInfo> getAllStackInfos() {
9533        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9534        long ident = Binder.clearCallingIdentity();
9535        try {
9536            synchronized (this) {
9537                return mStackSupervisor.getAllStackInfosLocked();
9538            }
9539        } finally {
9540            Binder.restoreCallingIdentity(ident);
9541        }
9542    }
9543
9544    @Override
9545    public StackInfo getStackInfo(int stackId) {
9546        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9547        long ident = Binder.clearCallingIdentity();
9548        try {
9549            synchronized (this) {
9550                return mStackSupervisor.getStackInfoLocked(stackId);
9551            }
9552        } finally {
9553            Binder.restoreCallingIdentity(ident);
9554        }
9555    }
9556
9557    @Override
9558    public boolean isInHomeStack(int taskId) {
9559        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9560        long ident = Binder.clearCallingIdentity();
9561        try {
9562            synchronized (this) {
9563                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9564                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9565                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9566            }
9567        } finally {
9568            Binder.restoreCallingIdentity(ident);
9569        }
9570    }
9571
9572    @Override
9573    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9574        synchronized(this) {
9575            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9576        }
9577    }
9578
9579    @Override
9580    public void updateDeviceOwner(String packageName) {
9581        final int callingUid = Binder.getCallingUid();
9582        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9583            throw new SecurityException("updateDeviceOwner called from non-system process");
9584        }
9585        synchronized (this) {
9586            mDeviceOwnerName = packageName;
9587        }
9588    }
9589
9590    @Override
9591    public void updateLockTaskPackages(int userId, String[] packages) {
9592        final int callingUid = Binder.getCallingUid();
9593        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9594            throw new SecurityException("updateLockTaskPackage called from non-system process");
9595        }
9596        synchronized (this) {
9597            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9598                    Arrays.toString(packages));
9599            mLockTaskPackages.put(userId, packages);
9600            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9601        }
9602    }
9603
9604
9605    void startLockTaskModeLocked(TaskRecord task) {
9606        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9607        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9608            return;
9609        }
9610
9611        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9612        // is initiated by system after the pinning request was shown and locked mode is initiated
9613        // by an authorized app directly
9614        final int callingUid = Binder.getCallingUid();
9615        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9616        long ident = Binder.clearCallingIdentity();
9617        try {
9618            final ActivityStack stack = mStackSupervisor.getFocusedStack();
9619            if (!isSystemInitiated) {
9620                task.mLockTaskUid = callingUid;
9621                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9622                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9623                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9624                    StatusBarManagerInternal statusBarManager =
9625                            LocalServices.getService(StatusBarManagerInternal.class);
9626                    if (statusBarManager != null) {
9627                        statusBarManager.showScreenPinningRequest();
9628                    }
9629                    return;
9630                }
9631
9632                if (stack == null || task != stack.topTask()) {
9633                    throw new IllegalArgumentException("Invalid task, not in foreground");
9634                }
9635            }
9636            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9637                    "Locking fully");
9638            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9639                    ActivityManager.LOCK_TASK_MODE_PINNED :
9640                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9641                    "startLockTask", true);
9642        } finally {
9643            Binder.restoreCallingIdentity(ident);
9644        }
9645    }
9646
9647    @Override
9648    public void startLockTaskMode(int taskId) {
9649        synchronized (this) {
9650            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9651            if (task != null) {
9652                startLockTaskModeLocked(task);
9653            }
9654        }
9655    }
9656
9657    @Override
9658    public void startLockTaskMode(IBinder token) {
9659        synchronized (this) {
9660            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9661            if (r == null) {
9662                return;
9663            }
9664            final TaskRecord task = r.task;
9665            if (task != null) {
9666                startLockTaskModeLocked(task);
9667            }
9668        }
9669    }
9670
9671    @Override
9672    public void startLockTaskModeOnCurrent() throws RemoteException {
9673        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9674        long ident = Binder.clearCallingIdentity();
9675        try {
9676            synchronized (this) {
9677                ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9678                if (r != null) {
9679                    startLockTaskModeLocked(r.task);
9680                }
9681            }
9682        } finally {
9683            Binder.restoreCallingIdentity(ident);
9684        }
9685    }
9686
9687    @Override
9688    public void stopLockTaskMode() {
9689        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9690        if (lockTask == null) {
9691            // Our work here is done.
9692            return;
9693        }
9694
9695        final int callingUid = Binder.getCallingUid();
9696        final int lockTaskUid = lockTask.mLockTaskUid;
9697        // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9698        // It is possible lockTaskMode was started by the system process because
9699        // android:lockTaskMode is set to a locking value in the application manifest instead of
9700        // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9701        // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9702        if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9703                callingUid != lockTaskUid
9704                && (lockTaskUid != 0
9705                    || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9706            throw new SecurityException("Invalid uid, expected " + lockTaskUid
9707                    + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9708        }
9709
9710        long ident = Binder.clearCallingIdentity();
9711        try {
9712            Log.d(TAG, "stopLockTaskMode");
9713            // Stop lock task
9714            synchronized (this) {
9715                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9716                        "stopLockTask", true);
9717            }
9718        } finally {
9719            Binder.restoreCallingIdentity(ident);
9720        }
9721    }
9722
9723    @Override
9724    public void stopLockTaskModeOnCurrent() throws RemoteException {
9725        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9726        long ident = Binder.clearCallingIdentity();
9727        try {
9728            stopLockTaskMode();
9729        } finally {
9730            Binder.restoreCallingIdentity(ident);
9731        }
9732    }
9733
9734    @Override
9735    public boolean isInLockTaskMode() {
9736        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9737    }
9738
9739    @Override
9740    public int getLockTaskModeState() {
9741        synchronized (this) {
9742            return mStackSupervisor.getLockTaskModeState();
9743        }
9744    }
9745
9746    @Override
9747    public void showLockTaskEscapeMessage(IBinder token) {
9748        synchronized (this) {
9749            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9750            if (r == null) {
9751                return;
9752            }
9753            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9754        }
9755    }
9756
9757    // =========================================================
9758    // CONTENT PROVIDERS
9759    // =========================================================
9760
9761    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9762        List<ProviderInfo> providers = null;
9763        try {
9764            ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager()
9765                    .queryContentProviders(app.processName, app.uid,
9766                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
9767                                    | MATCH_DEBUG_TRIAGED_MISSING);
9768            providers = slice != null ? slice.getList() : null;
9769        } catch (RemoteException ex) {
9770        }
9771        if (DEBUG_MU) Slog.v(TAG_MU,
9772                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9773        int userId = app.userId;
9774        if (providers != null) {
9775            int N = providers.size();
9776            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9777            for (int i=0; i<N; i++) {
9778                ProviderInfo cpi =
9779                    (ProviderInfo)providers.get(i);
9780                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9781                        cpi.name, cpi.flags);
9782                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9783                    // This is a singleton provider, but a user besides the
9784                    // default user is asking to initialize a process it runs
9785                    // in...  well, no, it doesn't actually run in this process,
9786                    // it runs in the process of the default user.  Get rid of it.
9787                    providers.remove(i);
9788                    N--;
9789                    i--;
9790                    continue;
9791                }
9792
9793                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9794                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9795                if (cpr == null) {
9796                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9797                    mProviderMap.putProviderByClass(comp, cpr);
9798                }
9799                if (DEBUG_MU) Slog.v(TAG_MU,
9800                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9801                app.pubProviders.put(cpi.name, cpr);
9802                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9803                    // Don't add this if it is a platform component that is marked
9804                    // to run in multiple processes, because this is actually
9805                    // part of the framework so doesn't make sense to track as a
9806                    // separate apk in the process.
9807                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9808                            mProcessStats);
9809                }
9810                notifyPackageUse(cpi.applicationInfo.packageName);
9811            }
9812        }
9813        return providers;
9814    }
9815
9816    /**
9817     * Check if {@link ProcessRecord} has a possible chance at accessing the
9818     * given {@link ProviderInfo}. Final permission checking is always done
9819     * in {@link ContentProvider}.
9820     */
9821    private final String checkContentProviderPermissionLocked(
9822            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9823        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9824        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9825        boolean checkedGrants = false;
9826        if (checkUser) {
9827            // Looking for cross-user grants before enforcing the typical cross-users permissions
9828            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9829            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9830                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9831                    return null;
9832                }
9833                checkedGrants = true;
9834            }
9835            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9836                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9837            if (userId != tmpTargetUserId) {
9838                // When we actually went to determine the final targer user ID, this ended
9839                // up different than our initial check for the authority.  This is because
9840                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9841                // SELF.  So we need to re-check the grants again.
9842                checkedGrants = false;
9843            }
9844        }
9845        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9846                cpi.applicationInfo.uid, cpi.exported)
9847                == PackageManager.PERMISSION_GRANTED) {
9848            return null;
9849        }
9850        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9851                cpi.applicationInfo.uid, cpi.exported)
9852                == PackageManager.PERMISSION_GRANTED) {
9853            return null;
9854        }
9855
9856        PathPermission[] pps = cpi.pathPermissions;
9857        if (pps != null) {
9858            int i = pps.length;
9859            while (i > 0) {
9860                i--;
9861                PathPermission pp = pps[i];
9862                String pprperm = pp.getReadPermission();
9863                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9864                        cpi.applicationInfo.uid, cpi.exported)
9865                        == PackageManager.PERMISSION_GRANTED) {
9866                    return null;
9867                }
9868                String ppwperm = pp.getWritePermission();
9869                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9870                        cpi.applicationInfo.uid, cpi.exported)
9871                        == PackageManager.PERMISSION_GRANTED) {
9872                    return null;
9873                }
9874            }
9875        }
9876        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9877            return null;
9878        }
9879
9880        String msg;
9881        if (!cpi.exported) {
9882            msg = "Permission Denial: opening provider " + cpi.name
9883                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9884                    + ", uid=" + callingUid + ") that is not exported from uid "
9885                    + cpi.applicationInfo.uid;
9886        } else {
9887            msg = "Permission Denial: opening provider " + cpi.name
9888                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9889                    + ", uid=" + callingUid + ") requires "
9890                    + cpi.readPermission + " or " + cpi.writePermission;
9891        }
9892        Slog.w(TAG, msg);
9893        return msg;
9894    }
9895
9896    /**
9897     * Returns if the ContentProvider has granted a uri to callingUid
9898     */
9899    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9900        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9901        if (perms != null) {
9902            for (int i=perms.size()-1; i>=0; i--) {
9903                GrantUri grantUri = perms.keyAt(i);
9904                if (grantUri.sourceUserId == userId || !checkUser) {
9905                    if (matchesProvider(grantUri.uri, cpi)) {
9906                        return true;
9907                    }
9908                }
9909            }
9910        }
9911        return false;
9912    }
9913
9914    /**
9915     * Returns true if the uri authority is one of the authorities specified in the provider.
9916     */
9917    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9918        String uriAuth = uri.getAuthority();
9919        String cpiAuth = cpi.authority;
9920        if (cpiAuth.indexOf(';') == -1) {
9921            return cpiAuth.equals(uriAuth);
9922        }
9923        String[] cpiAuths = cpiAuth.split(";");
9924        int length = cpiAuths.length;
9925        for (int i = 0; i < length; i++) {
9926            if (cpiAuths[i].equals(uriAuth)) return true;
9927        }
9928        return false;
9929    }
9930
9931    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9932            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9933        if (r != null) {
9934            for (int i=0; i<r.conProviders.size(); i++) {
9935                ContentProviderConnection conn = r.conProviders.get(i);
9936                if (conn.provider == cpr) {
9937                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9938                            "Adding provider requested by "
9939                            + r.processName + " from process "
9940                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9941                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9942                    if (stable) {
9943                        conn.stableCount++;
9944                        conn.numStableIncs++;
9945                    } else {
9946                        conn.unstableCount++;
9947                        conn.numUnstableIncs++;
9948                    }
9949                    return conn;
9950                }
9951            }
9952            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9953            if (stable) {
9954                conn.stableCount = 1;
9955                conn.numStableIncs = 1;
9956            } else {
9957                conn.unstableCount = 1;
9958                conn.numUnstableIncs = 1;
9959            }
9960            cpr.connections.add(conn);
9961            r.conProviders.add(conn);
9962            startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9963            return conn;
9964        }
9965        cpr.addExternalProcessHandleLocked(externalProcessToken);
9966        return null;
9967    }
9968
9969    boolean decProviderCountLocked(ContentProviderConnection conn,
9970            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9971        if (conn != null) {
9972            cpr = conn.provider;
9973            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9974                    "Removing provider requested by "
9975                    + conn.client.processName + " from process "
9976                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9977                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9978            if (stable) {
9979                conn.stableCount--;
9980            } else {
9981                conn.unstableCount--;
9982            }
9983            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9984                cpr.connections.remove(conn);
9985                conn.client.conProviders.remove(conn);
9986                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
9987                    // The client is more important than last activity -- note the time this
9988                    // is happening, so we keep the old provider process around a bit as last
9989                    // activity to avoid thrashing it.
9990                    if (cpr.proc != null) {
9991                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
9992                    }
9993                }
9994                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9995                return true;
9996            }
9997            return false;
9998        }
9999        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10000        return false;
10001    }
10002
10003    private void checkTime(long startTime, String where) {
10004        long now = SystemClock.elapsedRealtime();
10005        if ((now-startTime) > 1000) {
10006            // If we are taking more than a second, log about it.
10007            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10008        }
10009    }
10010
10011    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10012            String name, IBinder token, boolean stable, int userId) {
10013        ContentProviderRecord cpr;
10014        ContentProviderConnection conn = null;
10015        ProviderInfo cpi = null;
10016
10017        synchronized(this) {
10018            long startTime = SystemClock.elapsedRealtime();
10019
10020            ProcessRecord r = null;
10021            if (caller != null) {
10022                r = getRecordForAppLocked(caller);
10023                if (r == null) {
10024                    throw new SecurityException(
10025                            "Unable to find app for caller " + caller
10026                          + " (pid=" + Binder.getCallingPid()
10027                          + ") when getting content provider " + name);
10028                }
10029            }
10030
10031            boolean checkCrossUser = true;
10032
10033            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10034
10035            // First check if this content provider has been published...
10036            cpr = mProviderMap.getProviderByName(name, userId);
10037            // If that didn't work, check if it exists for user 0 and then
10038            // verify that it's a singleton provider before using it.
10039            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10040                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10041                if (cpr != null) {
10042                    cpi = cpr.info;
10043                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10044                            cpi.name, cpi.flags)
10045                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10046                        userId = UserHandle.USER_SYSTEM;
10047                        checkCrossUser = false;
10048                    } else {
10049                        cpr = null;
10050                        cpi = null;
10051                    }
10052                }
10053            }
10054
10055            boolean providerRunning = cpr != null;
10056            if (providerRunning) {
10057                cpi = cpr.info;
10058                String msg;
10059                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10060                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10061                        != null) {
10062                    throw new SecurityException(msg);
10063                }
10064                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10065
10066                if (r != null && cpr.canRunHere(r)) {
10067                    // This provider has been published or is in the process
10068                    // of being published...  but it is also allowed to run
10069                    // in the caller's process, so don't make a connection
10070                    // and just let the caller instantiate its own instance.
10071                    ContentProviderHolder holder = cpr.newHolder(null);
10072                    // don't give caller the provider object, it needs
10073                    // to make its own.
10074                    holder.provider = null;
10075                    return holder;
10076                }
10077
10078                final long origId = Binder.clearCallingIdentity();
10079
10080                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10081
10082                // In this case the provider instance already exists, so we can
10083                // return it right away.
10084                conn = incProviderCountLocked(r, cpr, token, stable);
10085                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10086                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10087                        // If this is a perceptible app accessing the provider,
10088                        // make sure to count it as being accessed and thus
10089                        // back up on the LRU list.  This is good because
10090                        // content providers are often expensive to start.
10091                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10092                        updateLruProcessLocked(cpr.proc, false, null);
10093                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10094                    }
10095                }
10096
10097                if (cpr.proc != null) {
10098                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10099                    boolean success = updateOomAdjLocked(cpr.proc);
10100                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10101                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10102                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10103                    // NOTE: there is still a race here where a signal could be
10104                    // pending on the process even though we managed to update its
10105                    // adj level.  Not sure what to do about this, but at least
10106                    // the race is now smaller.
10107                    if (!success) {
10108                        // Uh oh...  it looks like the provider's process
10109                        // has been killed on us.  We need to wait for a new
10110                        // process to be started, and make sure its death
10111                        // doesn't kill our process.
10112                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10113                                + " is crashing; detaching " + r);
10114                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10115                        checkTime(startTime, "getContentProviderImpl: before appDied");
10116                        appDiedLocked(cpr.proc);
10117                        checkTime(startTime, "getContentProviderImpl: after appDied");
10118                        if (!lastRef) {
10119                            // This wasn't the last ref our process had on
10120                            // the provider...  we have now been killed, bail.
10121                            return null;
10122                        }
10123                        providerRunning = false;
10124                        conn = null;
10125                    }
10126                }
10127
10128                Binder.restoreCallingIdentity(origId);
10129            }
10130
10131            if (!providerRunning) {
10132                try {
10133                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10134                    cpi = AppGlobals.getPackageManager().
10135                        resolveContentProvider(name,
10136                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10137                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10138                } catch (RemoteException ex) {
10139                }
10140                if (cpi == null) {
10141                    return null;
10142                }
10143                // If the provider is a singleton AND
10144                // (it's a call within the same user || the provider is a
10145                // privileged app)
10146                // Then allow connecting to the singleton provider
10147                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10148                        cpi.name, cpi.flags)
10149                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10150                if (singleton) {
10151                    userId = UserHandle.USER_SYSTEM;
10152                }
10153                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10154                checkTime(startTime, "getContentProviderImpl: got app info for user");
10155
10156                String msg;
10157                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10158                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10159                        != null) {
10160                    throw new SecurityException(msg);
10161                }
10162                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10163
10164                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10165                        && !cpi.processName.equals("system")) {
10166                    // If this content provider does not run in the system
10167                    // process, and the system is not yet ready to run other
10168                    // processes, then fail fast instead of hanging.
10169                    throw new IllegalArgumentException(
10170                            "Attempt to launch content provider before system ready");
10171                }
10172
10173                // Make sure that the user who owns this provider is running.  If not,
10174                // we don't want to allow it to run.
10175                if (!mUserController.isUserRunningLocked(userId, 0)) {
10176                    Slog.w(TAG, "Unable to launch app "
10177                            + cpi.applicationInfo.packageName + "/"
10178                            + cpi.applicationInfo.uid + " for provider "
10179                            + name + ": user " + userId + " is stopped");
10180                    return null;
10181                }
10182
10183                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10184                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10185                cpr = mProviderMap.getProviderByClass(comp, userId);
10186                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10187                final boolean firstClass = cpr == null;
10188                if (firstClass) {
10189                    final long ident = Binder.clearCallingIdentity();
10190
10191                    // If permissions need a review before any of the app components can run,
10192                    // we return no provider and launch a review activity if the calling app
10193                    // is in the foreground.
10194                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10195                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10196                            return null;
10197                        }
10198                    }
10199
10200                    try {
10201                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10202                        ApplicationInfo ai =
10203                            AppGlobals.getPackageManager().
10204                                getApplicationInfo(
10205                                        cpi.applicationInfo.packageName,
10206                                        STOCK_PM_FLAGS, userId);
10207                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10208                        if (ai == null) {
10209                            Slog.w(TAG, "No package info for content provider "
10210                                    + cpi.name);
10211                            return null;
10212                        }
10213                        ai = getAppInfoForUser(ai, userId);
10214                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10215                    } catch (RemoteException ex) {
10216                        // pm is in same process, this will never happen.
10217                    } finally {
10218                        Binder.restoreCallingIdentity(ident);
10219                    }
10220                }
10221
10222                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10223
10224                if (r != null && cpr.canRunHere(r)) {
10225                    // If this is a multiprocess provider, then just return its
10226                    // info and allow the caller to instantiate it.  Only do
10227                    // this if the provider is the same user as the caller's
10228                    // process, or can run as root (so can be in any process).
10229                    return cpr.newHolder(null);
10230                }
10231
10232                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10233                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10234                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10235
10236                // This is single process, and our app is now connecting to it.
10237                // See if we are already in the process of launching this
10238                // provider.
10239                final int N = mLaunchingProviders.size();
10240                int i;
10241                for (i = 0; i < N; i++) {
10242                    if (mLaunchingProviders.get(i) == cpr) {
10243                        break;
10244                    }
10245                }
10246
10247                // If the provider is not already being launched, then get it
10248                // started.
10249                if (i >= N) {
10250                    final long origId = Binder.clearCallingIdentity();
10251
10252                    try {
10253                        // Content provider is now in use, its package can't be stopped.
10254                        try {
10255                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10256                            AppGlobals.getPackageManager().setPackageStoppedState(
10257                                    cpr.appInfo.packageName, false, userId);
10258                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10259                        } catch (RemoteException e) {
10260                        } catch (IllegalArgumentException e) {
10261                            Slog.w(TAG, "Failed trying to unstop package "
10262                                    + cpr.appInfo.packageName + ": " + e);
10263                        }
10264
10265                        // Use existing process if already started
10266                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10267                        ProcessRecord proc = getProcessRecordLocked(
10268                                cpi.processName, cpr.appInfo.uid, false);
10269                        if (proc != null && proc.thread != null) {
10270                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10271                                    "Installing in existing process " + proc);
10272                            if (!proc.pubProviders.containsKey(cpi.name)) {
10273                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10274                                proc.pubProviders.put(cpi.name, cpr);
10275                                try {
10276                                    proc.thread.scheduleInstallProvider(cpi);
10277                                } catch (RemoteException e) {
10278                                }
10279                            }
10280                        } else {
10281                            checkTime(startTime, "getContentProviderImpl: before start process");
10282                            proc = startProcessLocked(cpi.processName,
10283                                    cpr.appInfo, false, 0, "content provider",
10284                                    new ComponentName(cpi.applicationInfo.packageName,
10285                                            cpi.name), false, false, false);
10286                            checkTime(startTime, "getContentProviderImpl: after start process");
10287                            if (proc == null) {
10288                                Slog.w(TAG, "Unable to launch app "
10289                                        + cpi.applicationInfo.packageName + "/"
10290                                        + cpi.applicationInfo.uid + " for provider "
10291                                        + name + ": process is bad");
10292                                return null;
10293                            }
10294                        }
10295                        cpr.launchingApp = proc;
10296                        mLaunchingProviders.add(cpr);
10297                    } finally {
10298                        Binder.restoreCallingIdentity(origId);
10299                    }
10300                }
10301
10302                checkTime(startTime, "getContentProviderImpl: updating data structures");
10303
10304                // Make sure the provider is published (the same provider class
10305                // may be published under multiple names).
10306                if (firstClass) {
10307                    mProviderMap.putProviderByClass(comp, cpr);
10308                }
10309
10310                mProviderMap.putProviderByName(name, cpr);
10311                conn = incProviderCountLocked(r, cpr, token, stable);
10312                if (conn != null) {
10313                    conn.waiting = true;
10314                }
10315            }
10316            checkTime(startTime, "getContentProviderImpl: done!");
10317        }
10318
10319        // Wait for the provider to be published...
10320        synchronized (cpr) {
10321            while (cpr.provider == null) {
10322                if (cpr.launchingApp == null) {
10323                    Slog.w(TAG, "Unable to launch app "
10324                            + cpi.applicationInfo.packageName + "/"
10325                            + cpi.applicationInfo.uid + " for provider "
10326                            + name + ": launching app became null");
10327                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10328                            UserHandle.getUserId(cpi.applicationInfo.uid),
10329                            cpi.applicationInfo.packageName,
10330                            cpi.applicationInfo.uid, name);
10331                    return null;
10332                }
10333                try {
10334                    if (DEBUG_MU) Slog.v(TAG_MU,
10335                            "Waiting to start provider " + cpr
10336                            + " launchingApp=" + cpr.launchingApp);
10337                    if (conn != null) {
10338                        conn.waiting = true;
10339                    }
10340                    cpr.wait();
10341                } catch (InterruptedException ex) {
10342                } finally {
10343                    if (conn != null) {
10344                        conn.waiting = false;
10345                    }
10346                }
10347            }
10348        }
10349        return cpr != null ? cpr.newHolder(conn) : null;
10350    }
10351
10352    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10353            ProcessRecord r, final int userId) {
10354        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10355                cpi.packageName, r.userId)) {
10356
10357            final boolean callerForeground = r != null ? r.setSchedGroup
10358                    != Process.THREAD_GROUP_BG_NONINTERACTIVE : true;
10359
10360            // Show a permission review UI only for starting from a foreground app
10361            if (!callerForeground) {
10362                Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10363                        + cpi.packageName + " requires a permissions review");
10364                return false;
10365            }
10366
10367            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10368            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10369                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10370            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10371
10372            if (DEBUG_PERMISSIONS_REVIEW) {
10373                Slog.i(TAG, "u" + r.userId + " Launching permission review "
10374                        + "for package " + cpi.packageName);
10375            }
10376
10377            final UserHandle userHandle = new UserHandle(userId);
10378            mHandler.post(new Runnable() {
10379                @Override
10380                public void run() {
10381                    mContext.startActivityAsUser(intent, userHandle);
10382                }
10383            });
10384
10385            return false;
10386        }
10387
10388        return true;
10389    }
10390
10391    PackageManagerInternal getPackageManagerInternalLocked() {
10392        if (mPackageManagerInt == null) {
10393            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10394        }
10395        return mPackageManagerInt;
10396    }
10397
10398    @Override
10399    public final ContentProviderHolder getContentProvider(
10400            IApplicationThread caller, String name, int userId, boolean stable) {
10401        enforceNotIsolatedCaller("getContentProvider");
10402        if (caller == null) {
10403            String msg = "null IApplicationThread when getting content provider "
10404                    + name;
10405            Slog.w(TAG, msg);
10406            throw new SecurityException(msg);
10407        }
10408        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10409        // with cross-user grant.
10410        return getContentProviderImpl(caller, name, null, stable, userId);
10411    }
10412
10413    public ContentProviderHolder getContentProviderExternal(
10414            String name, int userId, IBinder token) {
10415        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10416            "Do not have permission in call getContentProviderExternal()");
10417        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10418                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10419        return getContentProviderExternalUnchecked(name, token, userId);
10420    }
10421
10422    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10423            IBinder token, int userId) {
10424        return getContentProviderImpl(null, name, token, true, userId);
10425    }
10426
10427    /**
10428     * Drop a content provider from a ProcessRecord's bookkeeping
10429     */
10430    public void removeContentProvider(IBinder connection, boolean stable) {
10431        enforceNotIsolatedCaller("removeContentProvider");
10432        long ident = Binder.clearCallingIdentity();
10433        try {
10434            synchronized (this) {
10435                ContentProviderConnection conn;
10436                try {
10437                    conn = (ContentProviderConnection)connection;
10438                } catch (ClassCastException e) {
10439                    String msg ="removeContentProvider: " + connection
10440                            + " not a ContentProviderConnection";
10441                    Slog.w(TAG, msg);
10442                    throw new IllegalArgumentException(msg);
10443                }
10444                if (conn == null) {
10445                    throw new NullPointerException("connection is null");
10446                }
10447                if (decProviderCountLocked(conn, null, null, stable)) {
10448                    updateOomAdjLocked();
10449                }
10450            }
10451        } finally {
10452            Binder.restoreCallingIdentity(ident);
10453        }
10454    }
10455
10456    public void removeContentProviderExternal(String name, IBinder token) {
10457        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10458            "Do not have permission in call removeContentProviderExternal()");
10459        int userId = UserHandle.getCallingUserId();
10460        long ident = Binder.clearCallingIdentity();
10461        try {
10462            removeContentProviderExternalUnchecked(name, token, userId);
10463        } finally {
10464            Binder.restoreCallingIdentity(ident);
10465        }
10466    }
10467
10468    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10469        synchronized (this) {
10470            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10471            if(cpr == null) {
10472                //remove from mProvidersByClass
10473                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10474                return;
10475            }
10476
10477            //update content provider record entry info
10478            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10479            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10480            if (localCpr.hasExternalProcessHandles()) {
10481                if (localCpr.removeExternalProcessHandleLocked(token)) {
10482                    updateOomAdjLocked();
10483                } else {
10484                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10485                            + " with no external reference for token: "
10486                            + token + ".");
10487                }
10488            } else {
10489                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10490                        + " with no external references.");
10491            }
10492        }
10493    }
10494
10495    public final void publishContentProviders(IApplicationThread caller,
10496            List<ContentProviderHolder> providers) {
10497        if (providers == null) {
10498            return;
10499        }
10500
10501        enforceNotIsolatedCaller("publishContentProviders");
10502        synchronized (this) {
10503            final ProcessRecord r = getRecordForAppLocked(caller);
10504            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10505            if (r == null) {
10506                throw new SecurityException(
10507                        "Unable to find app for caller " + caller
10508                      + " (pid=" + Binder.getCallingPid()
10509                      + ") when publishing content providers");
10510            }
10511
10512            final long origId = Binder.clearCallingIdentity();
10513
10514            final int N = providers.size();
10515            for (int i = 0; i < N; i++) {
10516                ContentProviderHolder src = providers.get(i);
10517                if (src == null || src.info == null || src.provider == null) {
10518                    continue;
10519                }
10520                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10521                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10522                if (dst != null) {
10523                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10524                    mProviderMap.putProviderByClass(comp, dst);
10525                    String names[] = dst.info.authority.split(";");
10526                    for (int j = 0; j < names.length; j++) {
10527                        mProviderMap.putProviderByName(names[j], dst);
10528                    }
10529
10530                    int launchingCount = mLaunchingProviders.size();
10531                    int j;
10532                    boolean wasInLaunchingProviders = false;
10533                    for (j = 0; j < launchingCount; j++) {
10534                        if (mLaunchingProviders.get(j) == dst) {
10535                            mLaunchingProviders.remove(j);
10536                            wasInLaunchingProviders = true;
10537                            j--;
10538                            launchingCount--;
10539                        }
10540                    }
10541                    if (wasInLaunchingProviders) {
10542                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10543                    }
10544                    synchronized (dst) {
10545                        dst.provider = src.provider;
10546                        dst.proc = r;
10547                        dst.notifyAll();
10548                    }
10549                    updateOomAdjLocked(r);
10550                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10551                            src.info.authority);
10552                }
10553            }
10554
10555            Binder.restoreCallingIdentity(origId);
10556        }
10557    }
10558
10559    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10560        ContentProviderConnection conn;
10561        try {
10562            conn = (ContentProviderConnection)connection;
10563        } catch (ClassCastException e) {
10564            String msg ="refContentProvider: " + connection
10565                    + " not a ContentProviderConnection";
10566            Slog.w(TAG, msg);
10567            throw new IllegalArgumentException(msg);
10568        }
10569        if (conn == null) {
10570            throw new NullPointerException("connection is null");
10571        }
10572
10573        synchronized (this) {
10574            if (stable > 0) {
10575                conn.numStableIncs += stable;
10576            }
10577            stable = conn.stableCount + stable;
10578            if (stable < 0) {
10579                throw new IllegalStateException("stableCount < 0: " + stable);
10580            }
10581
10582            if (unstable > 0) {
10583                conn.numUnstableIncs += unstable;
10584            }
10585            unstable = conn.unstableCount + unstable;
10586            if (unstable < 0) {
10587                throw new IllegalStateException("unstableCount < 0: " + unstable);
10588            }
10589
10590            if ((stable+unstable) <= 0) {
10591                throw new IllegalStateException("ref counts can't go to zero here: stable="
10592                        + stable + " unstable=" + unstable);
10593            }
10594            conn.stableCount = stable;
10595            conn.unstableCount = unstable;
10596            return !conn.dead;
10597        }
10598    }
10599
10600    public void unstableProviderDied(IBinder connection) {
10601        ContentProviderConnection conn;
10602        try {
10603            conn = (ContentProviderConnection)connection;
10604        } catch (ClassCastException e) {
10605            String msg ="refContentProvider: " + connection
10606                    + " not a ContentProviderConnection";
10607            Slog.w(TAG, msg);
10608            throw new IllegalArgumentException(msg);
10609        }
10610        if (conn == null) {
10611            throw new NullPointerException("connection is null");
10612        }
10613
10614        // Safely retrieve the content provider associated with the connection.
10615        IContentProvider provider;
10616        synchronized (this) {
10617            provider = conn.provider.provider;
10618        }
10619
10620        if (provider == null) {
10621            // Um, yeah, we're way ahead of you.
10622            return;
10623        }
10624
10625        // Make sure the caller is being honest with us.
10626        if (provider.asBinder().pingBinder()) {
10627            // Er, no, still looks good to us.
10628            synchronized (this) {
10629                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10630                        + " says " + conn + " died, but we don't agree");
10631                return;
10632            }
10633        }
10634
10635        // Well look at that!  It's dead!
10636        synchronized (this) {
10637            if (conn.provider.provider != provider) {
10638                // But something changed...  good enough.
10639                return;
10640            }
10641
10642            ProcessRecord proc = conn.provider.proc;
10643            if (proc == null || proc.thread == null) {
10644                // Seems like the process is already cleaned up.
10645                return;
10646            }
10647
10648            // As far as we're concerned, this is just like receiving a
10649            // death notification...  just a bit prematurely.
10650            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10651                    + ") early provider death");
10652            final long ident = Binder.clearCallingIdentity();
10653            try {
10654                appDiedLocked(proc);
10655            } finally {
10656                Binder.restoreCallingIdentity(ident);
10657            }
10658        }
10659    }
10660
10661    @Override
10662    public void appNotRespondingViaProvider(IBinder connection) {
10663        enforceCallingPermission(
10664                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10665
10666        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10667        if (conn == null) {
10668            Slog.w(TAG, "ContentProviderConnection is null");
10669            return;
10670        }
10671
10672        final ProcessRecord host = conn.provider.proc;
10673        if (host == null) {
10674            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10675            return;
10676        }
10677
10678        final long token = Binder.clearCallingIdentity();
10679        try {
10680            mAppErrors.appNotResponding(host, null, null, false, "ContentProvider not responding");
10681        } finally {
10682            Binder.restoreCallingIdentity(token);
10683        }
10684    }
10685
10686    public final void installSystemProviders() {
10687        List<ProviderInfo> providers;
10688        synchronized (this) {
10689            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10690            providers = generateApplicationProvidersLocked(app);
10691            if (providers != null) {
10692                for (int i=providers.size()-1; i>=0; i--) {
10693                    ProviderInfo pi = (ProviderInfo)providers.get(i);
10694                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10695                        Slog.w(TAG, "Not installing system proc provider " + pi.name
10696                                + ": not system .apk");
10697                        providers.remove(i);
10698                    }
10699                }
10700            }
10701        }
10702        if (providers != null) {
10703            mSystemThread.installSystemProviders(providers);
10704        }
10705
10706        mCoreSettingsObserver = new CoreSettingsObserver(this);
10707        mFontScaleSettingObserver = new FontScaleSettingObserver();
10708
10709        //mUsageStatsService.monitorPackages();
10710    }
10711
10712    /**
10713     * When a user is unlocked, we need to install encryption-unaware providers
10714     * belonging to any running apps.
10715     */
10716    private void installEncryptionUnawareProviders(int userId) {
10717        if (!StorageManager.isFileBasedEncryptionEnabled()) {
10718            // TODO: eventually pivot this back to look at current user state,
10719            // similar to the comment in UserManager.isUserUnlocked(), but for
10720            // now, if we started apps when "unlocked" then unaware providers
10721            // have already been spun up.
10722            return;
10723        }
10724
10725        synchronized (this) {
10726            final int NP = mProcessNames.getMap().size();
10727            for (int ip = 0; ip < NP; ip++) {
10728                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10729                final int NA = apps.size();
10730                for (int ia = 0; ia < NA; ia++) {
10731                    final ProcessRecord app = apps.valueAt(ia);
10732                    if (app.userId != userId || app.thread == null) continue;
10733
10734                    final int NG = app.pkgList.size();
10735                    for (int ig = 0; ig < NG; ig++) {
10736                        try {
10737                            final String pkgName = app.pkgList.keyAt(ig);
10738                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
10739                                    .getPackageInfo(pkgName,
10740                                            GET_PROVIDERS | MATCH_ENCRYPTION_UNAWARE, userId);
10741                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
10742                                for (ProviderInfo provInfo : pkgInfo.providers) {
10743                                    Log.v(TAG, "Installing " + provInfo);
10744                                    app.thread.scheduleInstallProvider(provInfo);
10745                                }
10746                            }
10747                        } catch (RemoteException ignored) {
10748                        }
10749                    }
10750                }
10751            }
10752        }
10753    }
10754
10755    /**
10756     * Allows apps to retrieve the MIME type of a URI.
10757     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10758     * users, then it does not need permission to access the ContentProvider.
10759     * Either, it needs cross-user uri grants.
10760     *
10761     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10762     *
10763     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10764     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10765     */
10766    public String getProviderMimeType(Uri uri, int userId) {
10767        enforceNotIsolatedCaller("getProviderMimeType");
10768        final String name = uri.getAuthority();
10769        int callingUid = Binder.getCallingUid();
10770        int callingPid = Binder.getCallingPid();
10771        long ident = 0;
10772        boolean clearedIdentity = false;
10773        synchronized (this) {
10774            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10775        }
10776        if (canClearIdentity(callingPid, callingUid, userId)) {
10777            clearedIdentity = true;
10778            ident = Binder.clearCallingIdentity();
10779        }
10780        ContentProviderHolder holder = null;
10781        try {
10782            holder = getContentProviderExternalUnchecked(name, null, userId);
10783            if (holder != null) {
10784                return holder.provider.getType(uri);
10785            }
10786        } catch (RemoteException e) {
10787            Log.w(TAG, "Content provider dead retrieving " + uri, e);
10788            return null;
10789        } finally {
10790            // We need to clear the identity to call removeContentProviderExternalUnchecked
10791            if (!clearedIdentity) {
10792                ident = Binder.clearCallingIdentity();
10793            }
10794            try {
10795                if (holder != null) {
10796                    removeContentProviderExternalUnchecked(name, null, userId);
10797                }
10798            } finally {
10799                Binder.restoreCallingIdentity(ident);
10800            }
10801        }
10802
10803        return null;
10804    }
10805
10806    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10807        if (UserHandle.getUserId(callingUid) == userId) {
10808            return true;
10809        }
10810        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10811                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10812                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10813                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10814                return true;
10815        }
10816        return false;
10817    }
10818
10819    // =========================================================
10820    // GLOBAL MANAGEMENT
10821    // =========================================================
10822
10823    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10824            boolean isolated, int isolatedUid) {
10825        String proc = customProcess != null ? customProcess : info.processName;
10826        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10827        final int userId = UserHandle.getUserId(info.uid);
10828        int uid = info.uid;
10829        if (isolated) {
10830            if (isolatedUid == 0) {
10831                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10832                while (true) {
10833                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10834                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10835                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10836                    }
10837                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10838                    mNextIsolatedProcessUid++;
10839                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10840                        // No process for this uid, use it.
10841                        break;
10842                    }
10843                    stepsLeft--;
10844                    if (stepsLeft <= 0) {
10845                        return null;
10846                    }
10847                }
10848            } else {
10849                // Special case for startIsolatedProcess (internal only), where
10850                // the uid of the isolated process is specified by the caller.
10851                uid = isolatedUid;
10852            }
10853        }
10854        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10855        if (!mBooted && !mBooting
10856                && userId == UserHandle.USER_SYSTEM
10857                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10858            r.persistent = true;
10859        }
10860        addProcessNameLocked(r);
10861        return r;
10862    }
10863
10864    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10865            String abiOverride) {
10866        ProcessRecord app;
10867        if (!isolated) {
10868            app = getProcessRecordLocked(info.processName, info.uid, true);
10869        } else {
10870            app = null;
10871        }
10872
10873        if (app == null) {
10874            app = newProcessRecordLocked(info, null, isolated, 0);
10875            updateLruProcessLocked(app, false, null);
10876            updateOomAdjLocked();
10877        }
10878
10879        // This package really, really can not be stopped.
10880        try {
10881            AppGlobals.getPackageManager().setPackageStoppedState(
10882                    info.packageName, false, UserHandle.getUserId(app.uid));
10883        } catch (RemoteException e) {
10884        } catch (IllegalArgumentException e) {
10885            Slog.w(TAG, "Failed trying to unstop package "
10886                    + info.packageName + ": " + e);
10887        }
10888
10889        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10890            app.persistent = true;
10891            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10892        }
10893        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10894            mPersistentStartingProcesses.add(app);
10895            startProcessLocked(app, "added application", app.processName, abiOverride,
10896                    null /* entryPoint */, null /* entryPointArgs */);
10897        }
10898
10899        return app;
10900    }
10901
10902    public void unhandledBack() {
10903        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10904                "unhandledBack()");
10905
10906        synchronized(this) {
10907            final long origId = Binder.clearCallingIdentity();
10908            try {
10909                getFocusedStack().unhandledBackLocked();
10910            } finally {
10911                Binder.restoreCallingIdentity(origId);
10912            }
10913        }
10914    }
10915
10916    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10917        enforceNotIsolatedCaller("openContentUri");
10918        final int userId = UserHandle.getCallingUserId();
10919        String name = uri.getAuthority();
10920        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10921        ParcelFileDescriptor pfd = null;
10922        if (cph != null) {
10923            // We record the binder invoker's uid in thread-local storage before
10924            // going to the content provider to open the file.  Later, in the code
10925            // that handles all permissions checks, we look for this uid and use
10926            // that rather than the Activity Manager's own uid.  The effect is that
10927            // we do the check against the caller's permissions even though it looks
10928            // to the content provider like the Activity Manager itself is making
10929            // the request.
10930            Binder token = new Binder();
10931            sCallerIdentity.set(new Identity(
10932                    token, Binder.getCallingPid(), Binder.getCallingUid()));
10933            try {
10934                pfd = cph.provider.openFile(null, uri, "r", null, token);
10935            } catch (FileNotFoundException e) {
10936                // do nothing; pfd will be returned null
10937            } finally {
10938                // Ensure that whatever happens, we clean up the identity state
10939                sCallerIdentity.remove();
10940                // Ensure we're done with the provider.
10941                removeContentProviderExternalUnchecked(name, null, userId);
10942            }
10943        } else {
10944            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10945        }
10946        return pfd;
10947    }
10948
10949    // Actually is sleeping or shutting down or whatever else in the future
10950    // is an inactive state.
10951    public boolean isSleepingOrShuttingDown() {
10952        return isSleeping() || mShuttingDown;
10953    }
10954
10955    public boolean isSleeping() {
10956        return mSleeping;
10957    }
10958
10959    void onWakefulnessChanged(int wakefulness) {
10960        synchronized(this) {
10961            mWakefulness = wakefulness;
10962            updateSleepIfNeededLocked();
10963        }
10964    }
10965
10966    void finishRunningVoiceLocked() {
10967        Slog.d(TAG, "finishRunningVoiceLocked()  >>>>");
10968        if (mRunningVoice != null) {
10969            mRunningVoice = null;
10970            mVoiceWakeLock.release();
10971            updateSleepIfNeededLocked();
10972        }
10973    }
10974
10975    void startTimeTrackingFocusedActivityLocked() {
10976        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10977            mCurAppTimeTracker.start(mFocusedActivity.packageName);
10978        }
10979    }
10980
10981    void updateSleepIfNeededLocked() {
10982        if (mSleeping && !shouldSleepLocked()) {
10983            mSleeping = false;
10984            startTimeTrackingFocusedActivityLocked();
10985            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10986            mStackSupervisor.comeOutOfSleepIfNeededLocked();
10987            updateOomAdjLocked();
10988        } else if (!mSleeping && shouldSleepLocked()) {
10989            mSleeping = true;
10990            if (mCurAppTimeTracker != null) {
10991                mCurAppTimeTracker.stop();
10992            }
10993            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10994            mStackSupervisor.goingToSleepLocked();
10995            updateOomAdjLocked();
10996
10997            // Initialize the wake times of all processes.
10998            checkExcessivePowerUsageLocked(false);
10999            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11000            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11001            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11002        }
11003    }
11004
11005    private boolean shouldSleepLocked() {
11006        // Resume applications while running a voice interactor.
11007        if (mRunningVoice != null) {
11008            return false;
11009        }
11010
11011        // TODO: Transform the lock screen state into a sleep token instead.
11012        switch (mWakefulness) {
11013            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11014            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11015            case PowerManagerInternal.WAKEFULNESS_DOZING:
11016                // Pause applications whenever the lock screen is shown or any sleep
11017                // tokens have been acquired.
11018                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11019            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11020            default:
11021                // If we're asleep then pause applications unconditionally.
11022                return true;
11023        }
11024    }
11025
11026    /** Pokes the task persister. */
11027    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11028        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11029    }
11030
11031    /** Notifies all listeners when the task stack has changed. */
11032    void notifyTaskStackChangedLocked() {
11033        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11034        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11035        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11036        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11037    }
11038
11039    /** Notifies all listeners when an Activity is pinned. */
11040    void notifyActivityPinnedLocked() {
11041        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11042        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11043    }
11044
11045    /**
11046     * Notifies all listeners when an attempt was made to start an an activity that is already
11047     * running in the pinned stack and the activity was not actually started, but the task is
11048     * either brought to the front or a new Intent is delivered to it.
11049     */
11050    void notifyPinnedActivityRestartAttemptLocked() {
11051        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11052        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11053    }
11054
11055    @Override
11056    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11057        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11058    }
11059
11060    @Override
11061    public boolean shutdown(int timeout) {
11062        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11063                != PackageManager.PERMISSION_GRANTED) {
11064            throw new SecurityException("Requires permission "
11065                    + android.Manifest.permission.SHUTDOWN);
11066        }
11067
11068        boolean timedout = false;
11069
11070        synchronized(this) {
11071            mShuttingDown = true;
11072            updateEventDispatchingLocked();
11073            timedout = mStackSupervisor.shutdownLocked(timeout);
11074        }
11075
11076        mAppOpsService.shutdown();
11077        if (mUsageStatsService != null) {
11078            mUsageStatsService.prepareShutdown();
11079        }
11080        mBatteryStatsService.shutdown();
11081        synchronized (this) {
11082            mProcessStats.shutdownLocked();
11083            notifyTaskPersisterLocked(null, true);
11084        }
11085
11086        return timedout;
11087    }
11088
11089    public final void activitySlept(IBinder token) {
11090        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11091
11092        final long origId = Binder.clearCallingIdentity();
11093
11094        synchronized (this) {
11095            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11096            if (r != null) {
11097                mStackSupervisor.activitySleptLocked(r);
11098            }
11099        }
11100
11101        Binder.restoreCallingIdentity(origId);
11102    }
11103
11104    private String lockScreenShownToString() {
11105        switch (mLockScreenShown) {
11106            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11107            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11108            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11109            default: return "Unknown=" + mLockScreenShown;
11110        }
11111    }
11112
11113    void logLockScreen(String msg) {
11114        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11115                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11116                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11117                + " mSleeping=" + mSleeping);
11118    }
11119
11120    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11121        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11122        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11123        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11124            boolean wasRunningVoice = mRunningVoice != null;
11125            mRunningVoice = session;
11126            if (!wasRunningVoice) {
11127                mVoiceWakeLock.acquire();
11128                updateSleepIfNeededLocked();
11129            }
11130        }
11131    }
11132
11133    private void updateEventDispatchingLocked() {
11134        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11135    }
11136
11137    public void setLockScreenShown(boolean shown) {
11138        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11139                != PackageManager.PERMISSION_GRANTED) {
11140            throw new SecurityException("Requires permission "
11141                    + android.Manifest.permission.DEVICE_POWER);
11142        }
11143
11144        final int user = UserHandle.myUserId();
11145        synchronized(this) {
11146            long ident = Binder.clearCallingIdentity();
11147            try {
11148                if (!shown && mStackSupervisor.isFocusedUserLockedProfile()) {
11149                    startHomeActivityLocked(user, "setLockScreenShown");
11150                }
11151                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11152                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11153                updateSleepIfNeededLocked();
11154            } finally {
11155                Binder.restoreCallingIdentity(ident);
11156            }
11157        }
11158    }
11159
11160    @Override
11161    public void stopAppSwitches() {
11162        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11163                != PackageManager.PERMISSION_GRANTED) {
11164            throw new SecurityException("viewquires permission "
11165                    + android.Manifest.permission.STOP_APP_SWITCHES);
11166        }
11167
11168        synchronized(this) {
11169            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11170                    + APP_SWITCH_DELAY_TIME;
11171            mDidAppSwitch = false;
11172            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11173            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11174            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11175        }
11176    }
11177
11178    public void resumeAppSwitches() {
11179        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11180                != PackageManager.PERMISSION_GRANTED) {
11181            throw new SecurityException("Requires permission "
11182                    + android.Manifest.permission.STOP_APP_SWITCHES);
11183        }
11184
11185        synchronized(this) {
11186            // Note that we don't execute any pending app switches... we will
11187            // let those wait until either the timeout, or the next start
11188            // activity request.
11189            mAppSwitchesAllowedTime = 0;
11190        }
11191    }
11192
11193    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11194            int callingPid, int callingUid, String name) {
11195        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11196            return true;
11197        }
11198
11199        int perm = checkComponentPermission(
11200                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11201                sourceUid, -1, true);
11202        if (perm == PackageManager.PERMISSION_GRANTED) {
11203            return true;
11204        }
11205
11206        // If the actual IPC caller is different from the logical source, then
11207        // also see if they are allowed to control app switches.
11208        if (callingUid != -1 && callingUid != sourceUid) {
11209            perm = checkComponentPermission(
11210                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11211                    callingUid, -1, true);
11212            if (perm == PackageManager.PERMISSION_GRANTED) {
11213                return true;
11214            }
11215        }
11216
11217        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11218        return false;
11219    }
11220
11221    public void setDebugApp(String packageName, boolean waitForDebugger,
11222            boolean persistent) {
11223        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11224                "setDebugApp()");
11225
11226        long ident = Binder.clearCallingIdentity();
11227        try {
11228            // Note that this is not really thread safe if there are multiple
11229            // callers into it at the same time, but that's not a situation we
11230            // care about.
11231            if (persistent) {
11232                final ContentResolver resolver = mContext.getContentResolver();
11233                Settings.Global.putString(
11234                    resolver, Settings.Global.DEBUG_APP,
11235                    packageName);
11236                Settings.Global.putInt(
11237                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11238                    waitForDebugger ? 1 : 0);
11239            }
11240
11241            synchronized (this) {
11242                if (!persistent) {
11243                    mOrigDebugApp = mDebugApp;
11244                    mOrigWaitForDebugger = mWaitForDebugger;
11245                }
11246                mDebugApp = packageName;
11247                mWaitForDebugger = waitForDebugger;
11248                mDebugTransient = !persistent;
11249                if (packageName != null) {
11250                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11251                            false, UserHandle.USER_ALL, "set debug app");
11252                }
11253            }
11254        } finally {
11255            Binder.restoreCallingIdentity(ident);
11256        }
11257    }
11258
11259    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11260        synchronized (this) {
11261            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11262            if (!isDebuggable) {
11263                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11264                    throw new SecurityException("Process not debuggable: " + app.packageName);
11265                }
11266            }
11267
11268            mTrackAllocationApp = processName;
11269        }
11270    }
11271
11272    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11273        synchronized (this) {
11274            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11275            if (!isDebuggable) {
11276                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11277                    throw new SecurityException("Process not debuggable: " + app.packageName);
11278                }
11279            }
11280            mProfileApp = processName;
11281            mProfileFile = profilerInfo.profileFile;
11282            if (mProfileFd != null) {
11283                try {
11284                    mProfileFd.close();
11285                } catch (IOException e) {
11286                }
11287                mProfileFd = null;
11288            }
11289            mProfileFd = profilerInfo.profileFd;
11290            mSamplingInterval = profilerInfo.samplingInterval;
11291            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11292            mProfileType = 0;
11293        }
11294    }
11295
11296    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11297        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11298        if (!isDebuggable) {
11299            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11300                throw new SecurityException("Process not debuggable: " + app.packageName);
11301            }
11302        }
11303        mNativeDebuggingApp = processName;
11304    }
11305
11306    @Override
11307    public void setAlwaysFinish(boolean enabled) {
11308        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11309                "setAlwaysFinish()");
11310
11311        Settings.Global.putInt(
11312                mContext.getContentResolver(),
11313                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11314
11315        synchronized (this) {
11316            mAlwaysFinishActivities = enabled;
11317        }
11318    }
11319
11320    @Override
11321    public void setActivityController(IActivityController controller) {
11322        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11323                "setActivityController()");
11324        synchronized (this) {
11325            mController = controller;
11326            Watchdog.getInstance().setActivityController(controller);
11327        }
11328    }
11329
11330    @Override
11331    public void setUserIsMonkey(boolean userIsMonkey) {
11332        synchronized (this) {
11333            synchronized (mPidsSelfLocked) {
11334                final int callingPid = Binder.getCallingPid();
11335                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11336                if (precessRecord == null) {
11337                    throw new SecurityException("Unknown process: " + callingPid);
11338                }
11339                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11340                    throw new SecurityException("Only an instrumentation process "
11341                            + "with a UiAutomation can call setUserIsMonkey");
11342                }
11343            }
11344            mUserIsMonkey = userIsMonkey;
11345        }
11346    }
11347
11348    @Override
11349    public boolean isUserAMonkey() {
11350        synchronized (this) {
11351            // If there is a controller also implies the user is a monkey.
11352            return (mUserIsMonkey || mController != null);
11353        }
11354    }
11355
11356    public void requestBugReport(int bugreportType) {
11357        String service = null;
11358        switch (bugreportType) {
11359            case ActivityManager.BUGREPORT_OPTION_FULL:
11360                service = "bugreport";
11361                break;
11362            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11363                service = "bugreportplus";
11364                break;
11365            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11366                service = "bugreportremote";
11367                break;
11368        }
11369        if (service == null) {
11370            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11371                    + bugreportType);
11372        }
11373        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11374        SystemProperties.set("ctl.start", service);
11375    }
11376
11377    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11378        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11379    }
11380
11381    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11382        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11383            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11384        }
11385        return KEY_DISPATCHING_TIMEOUT;
11386    }
11387
11388    @Override
11389    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11390        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11391                != PackageManager.PERMISSION_GRANTED) {
11392            throw new SecurityException("Requires permission "
11393                    + android.Manifest.permission.FILTER_EVENTS);
11394        }
11395        ProcessRecord proc;
11396        long timeout;
11397        synchronized (this) {
11398            synchronized (mPidsSelfLocked) {
11399                proc = mPidsSelfLocked.get(pid);
11400            }
11401            timeout = getInputDispatchingTimeoutLocked(proc);
11402        }
11403
11404        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11405            return -1;
11406        }
11407
11408        return timeout;
11409    }
11410
11411    /**
11412     * Handle input dispatching timeouts.
11413     * Returns whether input dispatching should be aborted or not.
11414     */
11415    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11416            final ActivityRecord activity, final ActivityRecord parent,
11417            final boolean aboveSystem, String reason) {
11418        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11419                != PackageManager.PERMISSION_GRANTED) {
11420            throw new SecurityException("Requires permission "
11421                    + android.Manifest.permission.FILTER_EVENTS);
11422        }
11423
11424        final String annotation;
11425        if (reason == null) {
11426            annotation = "Input dispatching timed out";
11427        } else {
11428            annotation = "Input dispatching timed out (" + reason + ")";
11429        }
11430
11431        if (proc != null) {
11432            synchronized (this) {
11433                if (proc.debugging) {
11434                    return false;
11435                }
11436
11437                if (mDidDexOpt) {
11438                    // Give more time since we were dexopting.
11439                    mDidDexOpt = false;
11440                    return false;
11441                }
11442
11443                if (proc.instrumentationClass != null) {
11444                    Bundle info = new Bundle();
11445                    info.putString("shortMsg", "keyDispatchingTimedOut");
11446                    info.putString("longMsg", annotation);
11447                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11448                    return true;
11449                }
11450            }
11451            mHandler.post(new Runnable() {
11452                @Override
11453                public void run() {
11454                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11455                }
11456            });
11457        }
11458
11459        return true;
11460    }
11461
11462    @Override
11463    public Bundle getAssistContextExtras(int requestType) {
11464        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11465                null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11466        if (pae == null) {
11467            return null;
11468        }
11469        synchronized (pae) {
11470            while (!pae.haveResult) {
11471                try {
11472                    pae.wait();
11473                } catch (InterruptedException e) {
11474                }
11475            }
11476        }
11477        synchronized (this) {
11478            buildAssistBundleLocked(pae, pae.result);
11479            mPendingAssistExtras.remove(pae);
11480            mUiHandler.removeCallbacks(pae);
11481        }
11482        return pae.extras;
11483    }
11484
11485    @Override
11486    public boolean isAssistDataAllowedOnCurrentActivity() {
11487        int userId;
11488        synchronized (this) {
11489            userId = mUserController.getCurrentUserIdLocked();
11490            ActivityRecord activity = getFocusedStack().topActivity();
11491            if (activity == null) {
11492                return false;
11493            }
11494            userId = activity.userId;
11495        }
11496        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11497                Context.DEVICE_POLICY_SERVICE);
11498        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11499    }
11500
11501    @Override
11502    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11503        long ident = Binder.clearCallingIdentity();
11504        try {
11505            synchronized (this) {
11506                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11507                ActivityRecord top = getFocusedStack().topActivity();
11508                if (top != caller) {
11509                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11510                            + " is not current top " + top);
11511                    return false;
11512                }
11513                if (!top.nowVisible) {
11514                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11515                            + " is not visible");
11516                    return false;
11517                }
11518            }
11519            AssistUtils utils = new AssistUtils(mContext);
11520            return utils.showSessionForActiveService(args,
11521                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11522        } finally {
11523            Binder.restoreCallingIdentity(ident);
11524        }
11525    }
11526
11527    @Override
11528    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11529            IBinder activityToken) {
11530        return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11531                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11532    }
11533
11534    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11535            IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11536            long timeout) {
11537        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11538                "enqueueAssistContext()");
11539        synchronized (this) {
11540            ActivityRecord activity = getFocusedStack().topActivity();
11541            if (activity == null) {
11542                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11543                return null;
11544            }
11545            if (activity.app == null || activity.app.thread == null) {
11546                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11547                return null;
11548            }
11549            if (activityToken != null) {
11550                ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11551                if (activity != caller) {
11552                    Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11553                            + " is not current top " + activity);
11554                    return null;
11555                }
11556            }
11557            PendingAssistExtras pae;
11558            Bundle extras = new Bundle();
11559            if (args != null) {
11560                extras.putAll(args);
11561            }
11562            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11563            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11564            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11565            try {
11566                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11567                        requestType);
11568                mPendingAssistExtras.add(pae);
11569                mUiHandler.postDelayed(pae, timeout);
11570            } catch (RemoteException e) {
11571                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11572                return null;
11573            }
11574            return pae;
11575        }
11576    }
11577
11578    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11579        IResultReceiver receiver;
11580        synchronized (this) {
11581            mPendingAssistExtras.remove(pae);
11582            receiver = pae.receiver;
11583        }
11584        if (receiver != null) {
11585            // Caller wants result sent back to them.
11586            try {
11587                pae.receiver.send(0, null);
11588            } catch (RemoteException e) {
11589            }
11590        }
11591    }
11592
11593    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11594        if (result != null) {
11595            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11596        }
11597        if (pae.hint != null) {
11598            pae.extras.putBoolean(pae.hint, true);
11599        }
11600    }
11601
11602    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11603            AssistContent content, Uri referrer) {
11604        PendingAssistExtras pae = (PendingAssistExtras)token;
11605        synchronized (pae) {
11606            pae.result = extras;
11607            pae.structure = structure;
11608            pae.content = content;
11609            if (referrer != null) {
11610                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11611            }
11612            pae.haveResult = true;
11613            pae.notifyAll();
11614            if (pae.intent == null && pae.receiver == null) {
11615                // Caller is just waiting for the result.
11616                return;
11617            }
11618        }
11619
11620        // We are now ready to launch the assist activity.
11621        IResultReceiver sendReceiver = null;
11622        Bundle sendBundle = null;
11623        synchronized (this) {
11624            buildAssistBundleLocked(pae, extras);
11625            boolean exists = mPendingAssistExtras.remove(pae);
11626            mUiHandler.removeCallbacks(pae);
11627            if (!exists) {
11628                // Timed out.
11629                return;
11630            }
11631            if ((sendReceiver=pae.receiver) != null) {
11632                // Caller wants result sent back to them.
11633                sendBundle = new Bundle();
11634                sendBundle.putBundle("data", pae.extras);
11635                sendBundle.putParcelable("structure", pae.structure);
11636                sendBundle.putParcelable("content", pae.content);
11637            }
11638        }
11639        if (sendReceiver != null) {
11640            try {
11641                sendReceiver.send(0, sendBundle);
11642            } catch (RemoteException e) {
11643            }
11644            return;
11645        }
11646
11647        long ident = Binder.clearCallingIdentity();
11648        try {
11649            pae.intent.replaceExtras(pae.extras);
11650            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11651                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
11652                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11653            closeSystemDialogs("assist");
11654            try {
11655                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11656            } catch (ActivityNotFoundException e) {
11657                Slog.w(TAG, "No activity to handle assist action.", e);
11658            }
11659        } finally {
11660            Binder.restoreCallingIdentity(ident);
11661        }
11662    }
11663
11664    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11665            Bundle args) {
11666        return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11667                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11668    }
11669
11670    public void registerProcessObserver(IProcessObserver observer) {
11671        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11672                "registerProcessObserver()");
11673        synchronized (this) {
11674            mProcessObservers.register(observer);
11675        }
11676    }
11677
11678    @Override
11679    public void unregisterProcessObserver(IProcessObserver observer) {
11680        synchronized (this) {
11681            mProcessObservers.unregister(observer);
11682        }
11683    }
11684
11685    @Override
11686    public void registerUidObserver(IUidObserver observer, int which) {
11687        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11688                "registerUidObserver()");
11689        synchronized (this) {
11690            mUidObservers.register(observer, which);
11691        }
11692    }
11693
11694    @Override
11695    public void unregisterUidObserver(IUidObserver observer) {
11696        synchronized (this) {
11697            mUidObservers.unregister(observer);
11698        }
11699    }
11700
11701    @Override
11702    public boolean convertFromTranslucent(IBinder token) {
11703        final long origId = Binder.clearCallingIdentity();
11704        try {
11705            synchronized (this) {
11706                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11707                if (r == null) {
11708                    return false;
11709                }
11710                final boolean translucentChanged = r.changeWindowTranslucency(true);
11711                if (translucentChanged) {
11712                    r.task.stack.releaseBackgroundResources(r);
11713                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11714                }
11715                mWindowManager.setAppFullscreen(token, true);
11716                return translucentChanged;
11717            }
11718        } finally {
11719            Binder.restoreCallingIdentity(origId);
11720        }
11721    }
11722
11723    @Override
11724    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11725        final long origId = Binder.clearCallingIdentity();
11726        try {
11727            synchronized (this) {
11728                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11729                if (r == null) {
11730                    return false;
11731                }
11732                int index = r.task.mActivities.lastIndexOf(r);
11733                if (index > 0) {
11734                    ActivityRecord under = r.task.mActivities.get(index - 1);
11735                    under.returningOptions = options;
11736                }
11737                final boolean translucentChanged = r.changeWindowTranslucency(false);
11738                if (translucentChanged) {
11739                    r.task.stack.convertActivityToTranslucent(r);
11740                }
11741                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11742                mWindowManager.setAppFullscreen(token, false);
11743                return translucentChanged;
11744            }
11745        } finally {
11746            Binder.restoreCallingIdentity(origId);
11747        }
11748    }
11749
11750    @Override
11751    public boolean requestVisibleBehind(IBinder token, boolean visible) {
11752        final long origId = Binder.clearCallingIdentity();
11753        try {
11754            synchronized (this) {
11755                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11756                if (r != null) {
11757                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11758                }
11759            }
11760            return false;
11761        } finally {
11762            Binder.restoreCallingIdentity(origId);
11763        }
11764    }
11765
11766    @Override
11767    public boolean isBackgroundVisibleBehind(IBinder token) {
11768        final long origId = Binder.clearCallingIdentity();
11769        try {
11770            synchronized (this) {
11771                final ActivityStack stack = ActivityRecord.getStackLocked(token);
11772                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11773                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11774                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11775                return visible;
11776            }
11777        } finally {
11778            Binder.restoreCallingIdentity(origId);
11779        }
11780    }
11781
11782    @Override
11783    public ActivityOptions getActivityOptions(IBinder token) {
11784        final long origId = Binder.clearCallingIdentity();
11785        try {
11786            synchronized (this) {
11787                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11788                if (r != null) {
11789                    final ActivityOptions activityOptions = r.pendingOptions;
11790                    r.pendingOptions = null;
11791                    return activityOptions;
11792                }
11793                return null;
11794            }
11795        } finally {
11796            Binder.restoreCallingIdentity(origId);
11797        }
11798    }
11799
11800    @Override
11801    public void setImmersive(IBinder token, boolean immersive) {
11802        synchronized(this) {
11803            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11804            if (r == null) {
11805                throw new IllegalArgumentException();
11806            }
11807            r.immersive = immersive;
11808
11809            // update associated state if we're frontmost
11810            if (r == mFocusedActivity) {
11811                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11812                applyUpdateLockStateLocked(r);
11813            }
11814        }
11815    }
11816
11817    @Override
11818    public boolean isImmersive(IBinder token) {
11819        synchronized (this) {
11820            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11821            if (r == null) {
11822                throw new IllegalArgumentException();
11823            }
11824            return r.immersive;
11825        }
11826    }
11827
11828    @Override
11829    public void setVrMode(IBinder token, boolean enabled) {
11830        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
11831            throw new UnsupportedOperationException("VR mode not supported on this device!");
11832        }
11833
11834        synchronized(this) {
11835            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11836            if (r == null) {
11837                throw new IllegalArgumentException();
11838            }
11839            r.isVrActivity = enabled;
11840
11841            // Update associated state if this activity is currently focused
11842            if (r == mFocusedActivity) {
11843                applyUpdateVrModeLocked(r);
11844            }
11845        }
11846    }
11847
11848    public boolean isTopActivityImmersive() {
11849        enforceNotIsolatedCaller("startActivity");
11850        synchronized (this) {
11851            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11852            return (r != null) ? r.immersive : false;
11853        }
11854    }
11855
11856    @Override
11857    public boolean isTopOfTask(IBinder token) {
11858        synchronized (this) {
11859            ActivityRecord r = ActivityRecord.isInStackLocked(token);
11860            if (r == null) {
11861                throw new IllegalArgumentException();
11862            }
11863            return r.task.getTopActivity() == r;
11864        }
11865    }
11866
11867    public final void enterSafeMode() {
11868        synchronized(this) {
11869            // It only makes sense to do this before the system is ready
11870            // and started launching other packages.
11871            if (!mSystemReady) {
11872                try {
11873                    AppGlobals.getPackageManager().enterSafeMode();
11874                } catch (RemoteException e) {
11875                }
11876            }
11877
11878            mSafeMode = true;
11879        }
11880    }
11881
11882    public final void showSafeModeOverlay() {
11883        View v = LayoutInflater.from(mContext).inflate(
11884                com.android.internal.R.layout.safe_mode, null);
11885        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11886        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11887        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11888        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11889        lp.gravity = Gravity.BOTTOM | Gravity.START;
11890        lp.format = v.getBackground().getOpacity();
11891        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11892                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11893        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11894        ((WindowManager)mContext.getSystemService(
11895                Context.WINDOW_SERVICE)).addView(v, lp);
11896    }
11897
11898    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, 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            if (mBatteryStatsService.isOnBattery()) {
11906                mBatteryStatsService.enforceCallingPermission();
11907                int MY_UID = Binder.getCallingUid();
11908                final int uid;
11909                if (sender == null) {
11910                    uid = sourceUid;
11911                } else {
11912                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11913                }
11914                BatteryStatsImpl.Uid.Pkg pkg =
11915                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11916                            sourcePkg != null ? sourcePkg : rec.key.packageName);
11917                pkg.noteWakeupAlarmLocked(tag);
11918            }
11919        }
11920    }
11921
11922    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11923        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11924            return;
11925        }
11926        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11927        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11928        synchronized (stats) {
11929            mBatteryStatsService.enforceCallingPermission();
11930            int MY_UID = Binder.getCallingUid();
11931            final int uid;
11932            if (sender == null) {
11933                uid = sourceUid;
11934            } else {
11935                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11936            }
11937            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11938        }
11939    }
11940
11941    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11942        if (sender != null && !(sender instanceof PendingIntentRecord)) {
11943            return;
11944        }
11945        final PendingIntentRecord rec = (PendingIntentRecord)sender;
11946        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11947        synchronized (stats) {
11948            mBatteryStatsService.enforceCallingPermission();
11949            int MY_UID = Binder.getCallingUid();
11950            final int uid;
11951            if (sender == null) {
11952                uid = sourceUid;
11953            } else {
11954                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11955            }
11956            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11957        }
11958    }
11959
11960    public boolean killPids(int[] pids, String pReason, boolean secure) {
11961        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11962            throw new SecurityException("killPids only available to the system");
11963        }
11964        String reason = (pReason == null) ? "Unknown" : pReason;
11965        // XXX Note: don't acquire main activity lock here, because the window
11966        // manager calls in with its locks held.
11967
11968        boolean killed = false;
11969        synchronized (mPidsSelfLocked) {
11970            int worstType = 0;
11971            for (int i=0; i<pids.length; i++) {
11972                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11973                if (proc != null) {
11974                    int type = proc.setAdj;
11975                    if (type > worstType) {
11976                        worstType = type;
11977                    }
11978                }
11979            }
11980
11981            // If the worst oom_adj is somewhere in the cached proc LRU range,
11982            // then constrain it so we will kill all cached procs.
11983            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11984                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11985                worstType = ProcessList.CACHED_APP_MIN_ADJ;
11986            }
11987
11988            // If this is not a secure call, don't let it kill processes that
11989            // are important.
11990            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11991                worstType = ProcessList.SERVICE_ADJ;
11992            }
11993
11994            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11995            for (int i=0; i<pids.length; i++) {
11996                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11997                if (proc == null) {
11998                    continue;
11999                }
12000                int adj = proc.setAdj;
12001                if (adj >= worstType && !proc.killedByAm) {
12002                    proc.kill(reason, true);
12003                    killed = true;
12004                }
12005            }
12006        }
12007        return killed;
12008    }
12009
12010    @Override
12011    public void killUid(int appId, int userId, String reason) {
12012        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12013        synchronized (this) {
12014            final long identity = Binder.clearCallingIdentity();
12015            try {
12016                killPackageProcessesLocked(null, appId, userId,
12017                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12018                        reason != null ? reason : "kill uid");
12019            } finally {
12020                Binder.restoreCallingIdentity(identity);
12021            }
12022        }
12023    }
12024
12025    @Override
12026    public boolean killProcessesBelowForeground(String reason) {
12027        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12028            throw new SecurityException("killProcessesBelowForeground() only available to system");
12029        }
12030
12031        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12032    }
12033
12034    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12035        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12036            throw new SecurityException("killProcessesBelowAdj() only available to system");
12037        }
12038
12039        boolean killed = false;
12040        synchronized (mPidsSelfLocked) {
12041            final int size = mPidsSelfLocked.size();
12042            for (int i = 0; i < size; i++) {
12043                final int pid = mPidsSelfLocked.keyAt(i);
12044                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12045                if (proc == null) continue;
12046
12047                final int adj = proc.setAdj;
12048                if (adj > belowAdj && !proc.killedByAm) {
12049                    proc.kill(reason, true);
12050                    killed = true;
12051                }
12052            }
12053        }
12054        return killed;
12055    }
12056
12057    @Override
12058    public void hang(final IBinder who, boolean allowRestart) {
12059        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12060                != PackageManager.PERMISSION_GRANTED) {
12061            throw new SecurityException("Requires permission "
12062                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12063        }
12064
12065        final IBinder.DeathRecipient death = new DeathRecipient() {
12066            @Override
12067            public void binderDied() {
12068                synchronized (this) {
12069                    notifyAll();
12070                }
12071            }
12072        };
12073
12074        try {
12075            who.linkToDeath(death, 0);
12076        } catch (RemoteException e) {
12077            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12078            return;
12079        }
12080
12081        synchronized (this) {
12082            Watchdog.getInstance().setAllowRestart(allowRestart);
12083            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12084            synchronized (death) {
12085                while (who.isBinderAlive()) {
12086                    try {
12087                        death.wait();
12088                    } catch (InterruptedException e) {
12089                    }
12090                }
12091            }
12092            Watchdog.getInstance().setAllowRestart(true);
12093        }
12094    }
12095
12096    @Override
12097    public void restart() {
12098        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12099                != PackageManager.PERMISSION_GRANTED) {
12100            throw new SecurityException("Requires permission "
12101                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12102        }
12103
12104        Log.i(TAG, "Sending shutdown broadcast...");
12105
12106        BroadcastReceiver br = new BroadcastReceiver() {
12107            @Override public void onReceive(Context context, Intent intent) {
12108                // Now the broadcast is done, finish up the low-level shutdown.
12109                Log.i(TAG, "Shutting down activity manager...");
12110                shutdown(10000);
12111                Log.i(TAG, "Shutdown complete, restarting!");
12112                Process.killProcess(Process.myPid());
12113                System.exit(10);
12114            }
12115        };
12116
12117        // First send the high-level shut down broadcast.
12118        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12119        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12120        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12121        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12122        mContext.sendOrderedBroadcastAsUser(intent,
12123                UserHandle.ALL, null, br, mHandler, 0, null, null);
12124        */
12125        br.onReceive(mContext, intent);
12126    }
12127
12128    private long getLowRamTimeSinceIdle(long now) {
12129        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12130    }
12131
12132    @Override
12133    public void performIdleMaintenance() {
12134        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12135                != PackageManager.PERMISSION_GRANTED) {
12136            throw new SecurityException("Requires permission "
12137                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12138        }
12139
12140        synchronized (this) {
12141            final long now = SystemClock.uptimeMillis();
12142            final long timeSinceLastIdle = now - mLastIdleTime;
12143            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12144            mLastIdleTime = now;
12145            mLowRamTimeSinceLastIdle = 0;
12146            if (mLowRamStartTime != 0) {
12147                mLowRamStartTime = now;
12148            }
12149
12150            StringBuilder sb = new StringBuilder(128);
12151            sb.append("Idle maintenance over ");
12152            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12153            sb.append(" low RAM for ");
12154            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12155            Slog.i(TAG, sb.toString());
12156
12157            // If at least 1/3 of our time since the last idle period has been spent
12158            // with RAM low, then we want to kill processes.
12159            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12160
12161            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12162                ProcessRecord proc = mLruProcesses.get(i);
12163                if (proc.notCachedSinceIdle) {
12164                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12165                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12166                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12167                        if (doKilling && proc.initialIdlePss != 0
12168                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12169                            sb = new StringBuilder(128);
12170                            sb.append("Kill");
12171                            sb.append(proc.processName);
12172                            sb.append(" in idle maint: pss=");
12173                            sb.append(proc.lastPss);
12174                            sb.append(", swapPss=");
12175                            sb.append(proc.lastSwapPss);
12176                            sb.append(", initialPss=");
12177                            sb.append(proc.initialIdlePss);
12178                            sb.append(", period=");
12179                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12180                            sb.append(", lowRamPeriod=");
12181                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12182                            Slog.wtfQuiet(TAG, sb.toString());
12183                            proc.kill("idle maint (pss " + proc.lastPss
12184                                    + " from " + proc.initialIdlePss + ")", true);
12185                        }
12186                    }
12187                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
12188                    proc.notCachedSinceIdle = true;
12189                    proc.initialIdlePss = 0;
12190                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
12191                            mTestPssMode, isSleeping(), now);
12192                }
12193            }
12194
12195            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12196            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12197        }
12198    }
12199
12200    private void retrieveSettings() {
12201        final ContentResolver resolver = mContext.getContentResolver();
12202        final boolean freeformWindowManagement =
12203                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12204                        || Settings.Global.getInt(
12205                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12206        final boolean supportsPictureInPicture =
12207                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12208
12209        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12210        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12211        final boolean alwaysFinishActivities =
12212                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12213        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12214        final boolean forceResizable = Settings.Global.getInt(
12215                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12216        // Transfer any global setting for forcing RTL layout, into a System Property
12217        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12218
12219        final Configuration configuration = new Configuration();
12220        Settings.System.getConfiguration(resolver, configuration);
12221        if (forceRtl) {
12222            // This will take care of setting the correct layout direction flags
12223            configuration.setLayoutDirection(configuration.locale);
12224        }
12225
12226        synchronized (this) {
12227            mDebugApp = mOrigDebugApp = debugApp;
12228            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12229            mAlwaysFinishActivities = alwaysFinishActivities;
12230            mForceResizableActivities = forceResizable;
12231            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12232            mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12233            mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12234            // This happens before any activities are started, so we can
12235            // change mConfiguration in-place.
12236            updateConfigurationLocked(configuration, null, true);
12237            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12238                    "Initial config: " + mConfiguration);
12239
12240            // Load resources only after the current configuration has been set.
12241            final Resources res = mContext.getResources();
12242            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12243            mThumbnailWidth = res.getDimensionPixelSize(
12244                    com.android.internal.R.dimen.thumbnail_width);
12245            mThumbnailHeight = res.getDimensionPixelSize(
12246                    com.android.internal.R.dimen.thumbnail_height);
12247            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12248                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12249            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12250                    com.android.internal.R.string.config_appsNotReportingCrashes));
12251        }
12252    }
12253
12254    public boolean testIsSystemReady() {
12255        // no need to synchronize(this) just to read & return the value
12256        return mSystemReady;
12257    }
12258
12259    private static File getCalledPreBootReceiversFile() {
12260        File dataDir = Environment.getDataDirectory();
12261        File systemDir = new File(dataDir, "system");
12262        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12263        return fname;
12264    }
12265
12266    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12267        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12268        File file = getCalledPreBootReceiversFile();
12269        FileInputStream fis = null;
12270        try {
12271            fis = new FileInputStream(file);
12272            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12273            int fvers = dis.readInt();
12274            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12275                String vers = dis.readUTF();
12276                String codename = dis.readUTF();
12277                String build = dis.readUTF();
12278                if (android.os.Build.VERSION.RELEASE.equals(vers)
12279                        && android.os.Build.VERSION.CODENAME.equals(codename)
12280                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12281                    int num = dis.readInt();
12282                    while (num > 0) {
12283                        num--;
12284                        String pkg = dis.readUTF();
12285                        String cls = dis.readUTF();
12286                        lastDoneReceivers.add(new ComponentName(pkg, cls));
12287                    }
12288                }
12289            }
12290        } catch (FileNotFoundException e) {
12291        } catch (IOException e) {
12292            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12293        } finally {
12294            if (fis != null) {
12295                try {
12296                    fis.close();
12297                } catch (IOException e) {
12298                }
12299            }
12300        }
12301        return lastDoneReceivers;
12302    }
12303
12304    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12305        File file = getCalledPreBootReceiversFile();
12306        FileOutputStream fos = null;
12307        DataOutputStream dos = null;
12308        try {
12309            fos = new FileOutputStream(file);
12310            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12311            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12312            dos.writeUTF(android.os.Build.VERSION.RELEASE);
12313            dos.writeUTF(android.os.Build.VERSION.CODENAME);
12314            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12315            dos.writeInt(list.size());
12316            for (int i=0; i<list.size(); i++) {
12317                dos.writeUTF(list.get(i).getPackageName());
12318                dos.writeUTF(list.get(i).getClassName());
12319            }
12320        } catch (IOException e) {
12321            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12322            file.delete();
12323        } finally {
12324            FileUtils.sync(fos);
12325            if (dos != null) {
12326                try {
12327                    dos.close();
12328                } catch (IOException e) {
12329                    // TODO Auto-generated catch block
12330                    e.printStackTrace();
12331                }
12332            }
12333        }
12334    }
12335
12336    final class PreBootContinuation extends IIntentReceiver.Stub {
12337        final Intent intent;
12338        final Runnable onFinishCallback;
12339        final ArrayList<ComponentName> doneReceivers;
12340        final List<ResolveInfo> ris;
12341        final int[] users;
12342        int lastRi = -1;
12343        int curRi = 0;
12344        int curUser = 0;
12345
12346        PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12347                ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12348            intent = _intent;
12349            onFinishCallback = _onFinishCallback;
12350            doneReceivers = _doneReceivers;
12351            ris = _ris;
12352            users = _users;
12353        }
12354
12355        void go() {
12356            if (lastRi != curRi) {
12357                ActivityInfo ai = ris.get(curRi).activityInfo;
12358                ComponentName comp = new ComponentName(ai.packageName, ai.name);
12359                intent.setComponent(comp);
12360                doneReceivers.add(comp);
12361                lastRi = curRi;
12362                CharSequence label = ai.loadLabel(mContext.getPackageManager());
12363                showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12364            }
12365            Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12366                    + " for user " + users[curUser]);
12367            EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12368            broadcastIntentLocked(null, null, intent, null, this,
12369                    0, null, null, null, AppOpsManager.OP_NONE,
12370                    null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12371        }
12372
12373        public void performReceive(Intent intent, int resultCode,
12374                String data, Bundle extras, boolean ordered,
12375                boolean sticky, int sendingUser) {
12376            curUser++;
12377            if (curUser >= users.length) {
12378                curUser = 0;
12379                curRi++;
12380                if (curRi >= ris.size()) {
12381                    // All done sending broadcasts!
12382                    if (onFinishCallback != null) {
12383                        // The raw IIntentReceiver interface is called
12384                        // with the AM lock held, so redispatch to
12385                        // execute our code without the lock.
12386                        mHandler.post(onFinishCallback);
12387                    }
12388                    return;
12389                }
12390            }
12391            go();
12392        }
12393    }
12394
12395    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12396            ArrayList<ComponentName> doneReceivers) {
12397        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12398        List<ResolveInfo> ris = null;
12399        try {
12400            ris = AppGlobals.getPackageManager().queryIntentReceivers(
12401                    intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM);
12402        } catch (RemoteException e) {
12403        }
12404        if (ris == null) {
12405            return false;
12406        }
12407        intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
12408
12409        ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12410        for (int i=0; i<ris.size(); i++) {
12411            ActivityInfo ai = ris.get(i).activityInfo;
12412            ComponentName comp = new ComponentName(ai.packageName, ai.name);
12413            if (lastDoneReceivers.contains(comp)) {
12414                // We already did the pre boot receiver for this app with the current
12415                // platform version, so don't do it again...
12416                ris.remove(i);
12417                i--;
12418                // ...however, do keep it as one that has been done, so we don't
12419                // forget about it when rewriting the file of last done receivers.
12420                doneReceivers.add(comp);
12421            }
12422        }
12423
12424        if (ris.size() <= 0) {
12425            return false;
12426        }
12427
12428        // TODO: can we still do this with per user encryption?
12429        final int[] users = mUserController.getUsers();
12430        if (users.length <= 0) {
12431            return false;
12432        }
12433
12434        PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12435                ris, users);
12436        cont.go();
12437        return true;
12438    }
12439
12440    public void systemReady(final Runnable goingCallback) {
12441        synchronized(this) {
12442            if (mSystemReady) {
12443                // If we're done calling all the receivers, run the next "boot phase" passed in
12444                // by the SystemServer
12445                if (goingCallback != null) {
12446                    goingCallback.run();
12447                }
12448                return;
12449            }
12450
12451            mLocalDeviceIdleController
12452                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12453
12454            // Make sure we have the current profile info, since it is needed for security checks.
12455            mUserController.onSystemReady();
12456
12457            mRecentTasks.onSystemReady();
12458            // Check to see if there are any update receivers to run.
12459            if (!mDidUpdate) {
12460                if (mWaitingUpdate) {
12461                    return;
12462                }
12463                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12464                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12465                    public void run() {
12466                        synchronized (ActivityManagerService.this) {
12467                            mDidUpdate = true;
12468                        }
12469                        showBootMessage(mContext.getText(
12470                                R.string.android_upgrading_complete),
12471                                false);
12472                        writeLastDonePreBootReceivers(doneReceivers);
12473                        systemReady(goingCallback);
12474                    }
12475                }, doneReceivers);
12476
12477                if (mWaitingUpdate) {
12478                    return;
12479                }
12480                mDidUpdate = true;
12481            }
12482
12483            mAppOpsService.systemReady();
12484            mSystemReady = true;
12485        }
12486
12487        ArrayList<ProcessRecord> procsToKill = null;
12488        synchronized(mPidsSelfLocked) {
12489            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12490                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12491                if (!isAllowedWhileBooting(proc.info)){
12492                    if (procsToKill == null) {
12493                        procsToKill = new ArrayList<ProcessRecord>();
12494                    }
12495                    procsToKill.add(proc);
12496                }
12497            }
12498        }
12499
12500        synchronized(this) {
12501            if (procsToKill != null) {
12502                for (int i=procsToKill.size()-1; i>=0; i--) {
12503                    ProcessRecord proc = procsToKill.get(i);
12504                    Slog.i(TAG, "Removing system update proc: " + proc);
12505                    removeProcessLocked(proc, true, false, "system update done");
12506                }
12507            }
12508
12509            // Now that we have cleaned up any update processes, we
12510            // are ready to start launching real processes and know that
12511            // we won't trample on them any more.
12512            mProcessesReady = true;
12513        }
12514
12515        Slog.i(TAG, "System now ready");
12516        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12517            SystemClock.uptimeMillis());
12518
12519        synchronized(this) {
12520            // Make sure we have no pre-ready processes sitting around.
12521
12522            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12523                ResolveInfo ri = mContext.getPackageManager()
12524                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12525                                STOCK_PM_FLAGS);
12526                CharSequence errorMsg = null;
12527                if (ri != null) {
12528                    ActivityInfo ai = ri.activityInfo;
12529                    ApplicationInfo app = ai.applicationInfo;
12530                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12531                        mTopAction = Intent.ACTION_FACTORY_TEST;
12532                        mTopData = null;
12533                        mTopComponent = new ComponentName(app.packageName,
12534                                ai.name);
12535                    } else {
12536                        errorMsg = mContext.getResources().getText(
12537                                com.android.internal.R.string.factorytest_not_system);
12538                    }
12539                } else {
12540                    errorMsg = mContext.getResources().getText(
12541                            com.android.internal.R.string.factorytest_no_action);
12542                }
12543                if (errorMsg != null) {
12544                    mTopAction = null;
12545                    mTopData = null;
12546                    mTopComponent = null;
12547                    Message msg = Message.obtain();
12548                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12549                    msg.getData().putCharSequence("msg", errorMsg);
12550                    mUiHandler.sendMessage(msg);
12551                }
12552            }
12553        }
12554
12555        retrieveSettings();
12556        final int currentUserId;
12557        synchronized (this) {
12558            currentUserId = mUserController.getCurrentUserIdLocked();
12559            readGrantedUriPermissionsLocked();
12560        }
12561
12562        if (goingCallback != null) goingCallback.run();
12563
12564        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12565                Integer.toString(currentUserId), currentUserId);
12566        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12567                Integer.toString(currentUserId), currentUserId);
12568        mSystemServiceManager.startUser(currentUserId);
12569
12570        synchronized (this) {
12571            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12572                try {
12573                    List apps = AppGlobals.getPackageManager().
12574                        getPersistentApplications(STOCK_PM_FLAGS);
12575                    if (apps != null) {
12576                        int N = apps.size();
12577                        int i;
12578                        for (i=0; i<N; i++) {
12579                            ApplicationInfo info
12580                                = (ApplicationInfo)apps.get(i);
12581                            if (info != null &&
12582                                    !info.packageName.equals("android")) {
12583                                addAppLocked(info, false, null /* ABI override */);
12584                            }
12585                        }
12586                    }
12587                } catch (RemoteException ex) {
12588                    // pm is in same process, this will never happen.
12589                }
12590            }
12591
12592            // Start up initial activity.
12593            mBooting = true;
12594            // Enable home activity for system user, so that the system can always boot
12595            if (UserManager.isSplitSystemUser()) {
12596                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12597                try {
12598                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12599                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12600                            UserHandle.USER_SYSTEM);
12601                } catch (RemoteException e) {
12602                    e.rethrowAsRuntimeException();
12603                }
12604            }
12605            startHomeActivityLocked(currentUserId, "systemReady");
12606
12607            try {
12608                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12609                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12610                            + " data partition or your device will be unstable.");
12611                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12612                }
12613            } catch (RemoteException e) {
12614            }
12615
12616            if (!Build.isBuildConsistent()) {
12617                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12618                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12619            }
12620
12621            long ident = Binder.clearCallingIdentity();
12622            try {
12623                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12624                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12625                        | Intent.FLAG_RECEIVER_FOREGROUND);
12626                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12627                broadcastIntentLocked(null, null, intent,
12628                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12629                        null, false, false, MY_PID, Process.SYSTEM_UID,
12630                        currentUserId);
12631                intent = new Intent(Intent.ACTION_USER_STARTING);
12632                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12633                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12634                broadcastIntentLocked(null, null, intent,
12635                        null, new IIntentReceiver.Stub() {
12636                            @Override
12637                            public void performReceive(Intent intent, int resultCode, String data,
12638                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12639                                    throws RemoteException {
12640                            }
12641                        }, 0, null, null,
12642                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12643                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12644            } catch (Throwable t) {
12645                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12646            } finally {
12647                Binder.restoreCallingIdentity(ident);
12648            }
12649            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12650            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12651        }
12652    }
12653
12654    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12655        synchronized (this) {
12656            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12657        }
12658    }
12659
12660    void skipCurrentReceiverLocked(ProcessRecord app) {
12661        for (BroadcastQueue queue : mBroadcastQueues) {
12662            queue.skipCurrentReceiverLocked(app);
12663        }
12664    }
12665
12666    /**
12667     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12668     * The application process will exit immediately after this call returns.
12669     * @param app object of the crashing app, null for the system server
12670     * @param crashInfo describing the exception
12671     */
12672    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12673        ProcessRecord r = findAppProcess(app, "Crash");
12674        final String processName = app == null ? "system_server"
12675                : (r == null ? "unknown" : r.processName);
12676
12677        handleApplicationCrashInner("crash", r, processName, crashInfo);
12678    }
12679
12680    /* Native crash reporting uses this inner version because it needs to be somewhat
12681     * decoupled from the AM-managed cleanup lifecycle
12682     */
12683    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12684            ApplicationErrorReport.CrashInfo crashInfo) {
12685        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12686                UserHandle.getUserId(Binder.getCallingUid()), processName,
12687                r == null ? -1 : r.info.flags,
12688                crashInfo.exceptionClassName,
12689                crashInfo.exceptionMessage,
12690                crashInfo.throwFileName,
12691                crashInfo.throwLineNumber);
12692
12693        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12694
12695        mAppErrors.crashApplication(r, crashInfo);
12696    }
12697
12698    public void handleApplicationStrictModeViolation(
12699            IBinder app,
12700            int violationMask,
12701            StrictMode.ViolationInfo info) {
12702        ProcessRecord r = findAppProcess(app, "StrictMode");
12703        if (r == null) {
12704            return;
12705        }
12706
12707        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12708            Integer stackFingerprint = info.hashCode();
12709            boolean logIt = true;
12710            synchronized (mAlreadyLoggedViolatedStacks) {
12711                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12712                    logIt = false;
12713                    // TODO: sub-sample into EventLog for these, with
12714                    // the info.durationMillis?  Then we'd get
12715                    // the relative pain numbers, without logging all
12716                    // the stack traces repeatedly.  We'd want to do
12717                    // likewise in the client code, which also does
12718                    // dup suppression, before the Binder call.
12719                } else {
12720                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12721                        mAlreadyLoggedViolatedStacks.clear();
12722                    }
12723                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12724                }
12725            }
12726            if (logIt) {
12727                logStrictModeViolationToDropBox(r, info);
12728            }
12729        }
12730
12731        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12732            AppErrorResult result = new AppErrorResult();
12733            synchronized (this) {
12734                final long origId = Binder.clearCallingIdentity();
12735
12736                Message msg = Message.obtain();
12737                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12738                HashMap<String, Object> data = new HashMap<String, Object>();
12739                data.put("result", result);
12740                data.put("app", r);
12741                data.put("violationMask", violationMask);
12742                data.put("info", info);
12743                msg.obj = data;
12744                mUiHandler.sendMessage(msg);
12745
12746                Binder.restoreCallingIdentity(origId);
12747            }
12748            int res = result.get();
12749            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12750        }
12751    }
12752
12753    // Depending on the policy in effect, there could be a bunch of
12754    // these in quick succession so we try to batch these together to
12755    // minimize disk writes, number of dropbox entries, and maximize
12756    // compression, by having more fewer, larger records.
12757    private void logStrictModeViolationToDropBox(
12758            ProcessRecord process,
12759            StrictMode.ViolationInfo info) {
12760        if (info == null) {
12761            return;
12762        }
12763        final boolean isSystemApp = process == null ||
12764                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12765                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12766        final String processName = process == null ? "unknown" : process.processName;
12767        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12768        final DropBoxManager dbox = (DropBoxManager)
12769                mContext.getSystemService(Context.DROPBOX_SERVICE);
12770
12771        // Exit early if the dropbox isn't configured to accept this report type.
12772        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12773
12774        boolean bufferWasEmpty;
12775        boolean needsFlush;
12776        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12777        synchronized (sb) {
12778            bufferWasEmpty = sb.length() == 0;
12779            appendDropBoxProcessHeaders(process, processName, sb);
12780            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12781            sb.append("System-App: ").append(isSystemApp).append("\n");
12782            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12783            if (info.violationNumThisLoop != 0) {
12784                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12785            }
12786            if (info.numAnimationsRunning != 0) {
12787                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12788            }
12789            if (info.broadcastIntentAction != null) {
12790                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12791            }
12792            if (info.durationMillis != -1) {
12793                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12794            }
12795            if (info.numInstances != -1) {
12796                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12797            }
12798            if (info.tags != null) {
12799                for (String tag : info.tags) {
12800                    sb.append("Span-Tag: ").append(tag).append("\n");
12801                }
12802            }
12803            sb.append("\n");
12804            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12805                sb.append(info.crashInfo.stackTrace);
12806                sb.append("\n");
12807            }
12808            if (info.message != null) {
12809                sb.append(info.message);
12810                sb.append("\n");
12811            }
12812
12813            // Only buffer up to ~64k.  Various logging bits truncate
12814            // things at 128k.
12815            needsFlush = (sb.length() > 64 * 1024);
12816        }
12817
12818        // Flush immediately if the buffer's grown too large, or this
12819        // is a non-system app.  Non-system apps are isolated with a
12820        // different tag & policy and not batched.
12821        //
12822        // Batching is useful during internal testing with
12823        // StrictMode settings turned up high.  Without batching,
12824        // thousands of separate files could be created on boot.
12825        if (!isSystemApp || needsFlush) {
12826            new Thread("Error dump: " + dropboxTag) {
12827                @Override
12828                public void run() {
12829                    String report;
12830                    synchronized (sb) {
12831                        report = sb.toString();
12832                        sb.delete(0, sb.length());
12833                        sb.trimToSize();
12834                    }
12835                    if (report.length() != 0) {
12836                        dbox.addText(dropboxTag, report);
12837                    }
12838                }
12839            }.start();
12840            return;
12841        }
12842
12843        // System app batching:
12844        if (!bufferWasEmpty) {
12845            // An existing dropbox-writing thread is outstanding, so
12846            // we don't need to start it up.  The existing thread will
12847            // catch the buffer appends we just did.
12848            return;
12849        }
12850
12851        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12852        // (After this point, we shouldn't access AMS internal data structures.)
12853        new Thread("Error dump: " + dropboxTag) {
12854            @Override
12855            public void run() {
12856                // 5 second sleep to let stacks arrive and be batched together
12857                try {
12858                    Thread.sleep(5000);  // 5 seconds
12859                } catch (InterruptedException e) {}
12860
12861                String errorReport;
12862                synchronized (mStrictModeBuffer) {
12863                    errorReport = mStrictModeBuffer.toString();
12864                    if (errorReport.length() == 0) {
12865                        return;
12866                    }
12867                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12868                    mStrictModeBuffer.trimToSize();
12869                }
12870                dbox.addText(dropboxTag, errorReport);
12871            }
12872        }.start();
12873    }
12874
12875    /**
12876     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12877     * @param app object of the crashing app, null for the system server
12878     * @param tag reported by the caller
12879     * @param system whether this wtf is coming from the system
12880     * @param crashInfo describing the context of the error
12881     * @return true if the process should exit immediately (WTF is fatal)
12882     */
12883    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12884            final ApplicationErrorReport.CrashInfo crashInfo) {
12885        final int callingUid = Binder.getCallingUid();
12886        final int callingPid = Binder.getCallingPid();
12887
12888        if (system) {
12889            // If this is coming from the system, we could very well have low-level
12890            // system locks held, so we want to do this all asynchronously.  And we
12891            // never want this to become fatal, so there is that too.
12892            mHandler.post(new Runnable() {
12893                @Override public void run() {
12894                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12895                }
12896            });
12897            return false;
12898        }
12899
12900        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12901                crashInfo);
12902
12903        if (r != null && r.pid != Process.myPid() &&
12904                Settings.Global.getInt(mContext.getContentResolver(),
12905                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
12906            mAppErrors.crashApplication(r, crashInfo);
12907            return true;
12908        } else {
12909            return false;
12910        }
12911    }
12912
12913    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12914            final ApplicationErrorReport.CrashInfo crashInfo) {
12915        final ProcessRecord r = findAppProcess(app, "WTF");
12916        final String processName = app == null ? "system_server"
12917                : (r == null ? "unknown" : r.processName);
12918
12919        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12920                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12921
12922        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12923
12924        return r;
12925    }
12926
12927    /**
12928     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12929     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12930     */
12931    private ProcessRecord findAppProcess(IBinder app, String reason) {
12932        if (app == null) {
12933            return null;
12934        }
12935
12936        synchronized (this) {
12937            final int NP = mProcessNames.getMap().size();
12938            for (int ip=0; ip<NP; ip++) {
12939                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12940                final int NA = apps.size();
12941                for (int ia=0; ia<NA; ia++) {
12942                    ProcessRecord p = apps.valueAt(ia);
12943                    if (p.thread != null && p.thread.asBinder() == app) {
12944                        return p;
12945                    }
12946                }
12947            }
12948
12949            Slog.w(TAG, "Can't find mystery application for " + reason
12950                    + " from pid=" + Binder.getCallingPid()
12951                    + " uid=" + Binder.getCallingUid() + ": " + app);
12952            return null;
12953        }
12954    }
12955
12956    /**
12957     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12958     * to append various headers to the dropbox log text.
12959     */
12960    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12961            StringBuilder sb) {
12962        // Watchdog thread ends up invoking this function (with
12963        // a null ProcessRecord) to add the stack file to dropbox.
12964        // Do not acquire a lock on this (am) in such cases, as it
12965        // could cause a potential deadlock, if and when watchdog
12966        // is invoked due to unavailability of lock on am and it
12967        // would prevent watchdog from killing system_server.
12968        if (process == null) {
12969            sb.append("Process: ").append(processName).append("\n");
12970            return;
12971        }
12972        // Note: ProcessRecord 'process' is guarded by the service
12973        // instance.  (notably process.pkgList, which could otherwise change
12974        // concurrently during execution of this method)
12975        synchronized (this) {
12976            sb.append("Process: ").append(processName).append("\n");
12977            int flags = process.info.flags;
12978            IPackageManager pm = AppGlobals.getPackageManager();
12979            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12980            for (int ip=0; ip<process.pkgList.size(); ip++) {
12981                String pkg = process.pkgList.keyAt(ip);
12982                sb.append("Package: ").append(pkg);
12983                try {
12984                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12985                    if (pi != null) {
12986                        sb.append(" v").append(pi.versionCode);
12987                        if (pi.versionName != null) {
12988                            sb.append(" (").append(pi.versionName).append(")");
12989                        }
12990                    }
12991                } catch (RemoteException e) {
12992                    Slog.e(TAG, "Error getting package info: " + pkg, e);
12993                }
12994                sb.append("\n");
12995            }
12996        }
12997    }
12998
12999    private static String processClass(ProcessRecord process) {
13000        if (process == null || process.pid == MY_PID) {
13001            return "system_server";
13002        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13003            return "system_app";
13004        } else {
13005            return "data_app";
13006        }
13007    }
13008
13009    /**
13010     * Write a description of an error (crash, WTF, ANR) to the drop box.
13011     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13012     * @param process which caused the error, null means the system server
13013     * @param activity which triggered the error, null if unknown
13014     * @param parent activity related to the error, null if unknown
13015     * @param subject line related to the error, null if absent
13016     * @param report in long form describing the error, null if absent
13017     * @param logFile to include in the report, null if none
13018     * @param crashInfo giving an application stack trace, null if absent
13019     */
13020    public void addErrorToDropBox(String eventType,
13021            ProcessRecord process, String processName, ActivityRecord activity,
13022            ActivityRecord parent, String subject,
13023            final String report, final File logFile,
13024            final ApplicationErrorReport.CrashInfo crashInfo) {
13025        // NOTE -- this must never acquire the ActivityManagerService lock,
13026        // otherwise the watchdog may be prevented from resetting the system.
13027
13028        final String dropboxTag = processClass(process) + "_" + eventType;
13029        final DropBoxManager dbox = (DropBoxManager)
13030                mContext.getSystemService(Context.DROPBOX_SERVICE);
13031
13032        // Exit early if the dropbox isn't configured to accept this report type.
13033        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13034
13035        final StringBuilder sb = new StringBuilder(1024);
13036        appendDropBoxProcessHeaders(process, processName, sb);
13037        if (process != null) {
13038            sb.append("Foreground: ")
13039                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13040                    .append("\n");
13041        }
13042        if (activity != null) {
13043            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13044        }
13045        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13046            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13047        }
13048        if (parent != null && parent != activity) {
13049            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13050        }
13051        if (subject != null) {
13052            sb.append("Subject: ").append(subject).append("\n");
13053        }
13054        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13055        if (Debug.isDebuggerConnected()) {
13056            sb.append("Debugger: Connected\n");
13057        }
13058        sb.append("\n");
13059
13060        // Do the rest in a worker thread to avoid blocking the caller on I/O
13061        // (After this point, we shouldn't access AMS internal data structures.)
13062        Thread worker = new Thread("Error dump: " + dropboxTag) {
13063            @Override
13064            public void run() {
13065                if (report != null) {
13066                    sb.append(report);
13067                }
13068                if (logFile != null) {
13069                    try {
13070                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13071                                    "\n\n[[TRUNCATED]]"));
13072                    } catch (IOException e) {
13073                        Slog.e(TAG, "Error reading " + logFile, e);
13074                    }
13075                }
13076                if (crashInfo != null && crashInfo.stackTrace != null) {
13077                    sb.append(crashInfo.stackTrace);
13078                }
13079
13080                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13081                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13082                if (lines > 0) {
13083                    sb.append("\n");
13084
13085                    // Merge several logcat streams, and take the last N lines
13086                    InputStreamReader input = null;
13087                    try {
13088                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13089                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13090                                "-b", "crash",
13091                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13092
13093                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13094                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13095                        input = new InputStreamReader(logcat.getInputStream());
13096
13097                        int num;
13098                        char[] buf = new char[8192];
13099                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13100                    } catch (IOException e) {
13101                        Slog.e(TAG, "Error running logcat", e);
13102                    } finally {
13103                        if (input != null) try { input.close(); } catch (IOException e) {}
13104                    }
13105                }
13106
13107                dbox.addText(dropboxTag, sb.toString());
13108            }
13109        };
13110
13111        if (process == null) {
13112            // If process is null, we are being called from some internal code
13113            // and may be about to die -- run this synchronously.
13114            worker.run();
13115        } else {
13116            worker.start();
13117        }
13118    }
13119
13120    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13121        enforceNotIsolatedCaller("getProcessesInErrorState");
13122        // assume our apps are happy - lazy create the list
13123        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13124
13125        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13126                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13127        int userId = UserHandle.getUserId(Binder.getCallingUid());
13128
13129        synchronized (this) {
13130
13131            // iterate across all processes
13132            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13133                ProcessRecord app = mLruProcesses.get(i);
13134                if (!allUsers && app.userId != userId) {
13135                    continue;
13136                }
13137                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13138                    // This one's in trouble, so we'll generate a report for it
13139                    // crashes are higher priority (in case there's a crash *and* an anr)
13140                    ActivityManager.ProcessErrorStateInfo report = null;
13141                    if (app.crashing) {
13142                        report = app.crashingReport;
13143                    } else if (app.notResponding) {
13144                        report = app.notRespondingReport;
13145                    }
13146
13147                    if (report != null) {
13148                        if (errList == null) {
13149                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13150                        }
13151                        errList.add(report);
13152                    } else {
13153                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13154                                " crashing = " + app.crashing +
13155                                " notResponding = " + app.notResponding);
13156                    }
13157                }
13158            }
13159        }
13160
13161        return errList;
13162    }
13163
13164    static int procStateToImportance(int procState, int memAdj,
13165            ActivityManager.RunningAppProcessInfo currApp) {
13166        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13167        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13168            currApp.lru = memAdj;
13169        } else {
13170            currApp.lru = 0;
13171        }
13172        return imp;
13173    }
13174
13175    private void fillInProcMemInfo(ProcessRecord app,
13176            ActivityManager.RunningAppProcessInfo outInfo) {
13177        outInfo.pid = app.pid;
13178        outInfo.uid = app.info.uid;
13179        if (mHeavyWeightProcess == app) {
13180            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13181        }
13182        if (app.persistent) {
13183            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13184        }
13185        if (app.activities.size() > 0) {
13186            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13187        }
13188        outInfo.lastTrimLevel = app.trimMemoryLevel;
13189        int adj = app.curAdj;
13190        int procState = app.curProcState;
13191        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13192        outInfo.importanceReasonCode = app.adjTypeCode;
13193        outInfo.processState = app.curProcState;
13194    }
13195
13196    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13197        enforceNotIsolatedCaller("getRunningAppProcesses");
13198
13199        final int callingUid = Binder.getCallingUid();
13200
13201        // Lazy instantiation of list
13202        List<ActivityManager.RunningAppProcessInfo> runList = null;
13203        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13204                callingUid) == PackageManager.PERMISSION_GRANTED;
13205        final int userId = UserHandle.getUserId(callingUid);
13206        final boolean allUids = isGetTasksAllowed(
13207                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13208
13209        synchronized (this) {
13210            // Iterate across all processes
13211            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13212                ProcessRecord app = mLruProcesses.get(i);
13213                if ((!allUsers && app.userId != userId)
13214                        || (!allUids && app.uid != callingUid)) {
13215                    continue;
13216                }
13217                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13218                    // Generate process state info for running application
13219                    ActivityManager.RunningAppProcessInfo currApp =
13220                        new ActivityManager.RunningAppProcessInfo(app.processName,
13221                                app.pid, app.getPackageList());
13222                    fillInProcMemInfo(app, currApp);
13223                    if (app.adjSource instanceof ProcessRecord) {
13224                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13225                        currApp.importanceReasonImportance =
13226                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13227                                        app.adjSourceProcState);
13228                    } else if (app.adjSource instanceof ActivityRecord) {
13229                        ActivityRecord r = (ActivityRecord)app.adjSource;
13230                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13231                    }
13232                    if (app.adjTarget instanceof ComponentName) {
13233                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13234                    }
13235                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13236                    //        + " lru=" + currApp.lru);
13237                    if (runList == null) {
13238                        runList = new ArrayList<>();
13239                    }
13240                    runList.add(currApp);
13241                }
13242            }
13243        }
13244        return runList;
13245    }
13246
13247    public List<ApplicationInfo> getRunningExternalApplications() {
13248        enforceNotIsolatedCaller("getRunningExternalApplications");
13249        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13250        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13251        if (runningApps != null && runningApps.size() > 0) {
13252            Set<String> extList = new HashSet<String>();
13253            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13254                if (app.pkgList != null) {
13255                    for (String pkg : app.pkgList) {
13256                        extList.add(pkg);
13257                    }
13258                }
13259            }
13260            IPackageManager pm = AppGlobals.getPackageManager();
13261            for (String pkg : extList) {
13262                try {
13263                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13264                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13265                        retList.add(info);
13266                    }
13267                } catch (RemoteException e) {
13268                }
13269            }
13270        }
13271        return retList;
13272    }
13273
13274    @Override
13275    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13276        enforceNotIsolatedCaller("getMyMemoryState");
13277        synchronized (this) {
13278            ProcessRecord proc;
13279            synchronized (mPidsSelfLocked) {
13280                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13281            }
13282            fillInProcMemInfo(proc, outInfo);
13283        }
13284    }
13285
13286    @Override
13287    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13288            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13289        (new ActivityManagerShellCommand(this, false)).exec(
13290                this, in, out, err, args, resultReceiver);
13291    }
13292
13293    @Override
13294    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13295        if (checkCallingPermission(android.Manifest.permission.DUMP)
13296                != PackageManager.PERMISSION_GRANTED) {
13297            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13298                    + Binder.getCallingPid()
13299                    + ", uid=" + Binder.getCallingUid()
13300                    + " without permission "
13301                    + android.Manifest.permission.DUMP);
13302            return;
13303        }
13304
13305        boolean dumpAll = false;
13306        boolean dumpClient = false;
13307        String dumpPackage = null;
13308
13309        int opti = 0;
13310        while (opti < args.length) {
13311            String opt = args[opti];
13312            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13313                break;
13314            }
13315            opti++;
13316            if ("-a".equals(opt)) {
13317                dumpAll = true;
13318            } else if ("-c".equals(opt)) {
13319                dumpClient = true;
13320            } else if ("-p".equals(opt)) {
13321                if (opti < args.length) {
13322                    dumpPackage = args[opti];
13323                    opti++;
13324                } else {
13325                    pw.println("Error: -p option requires package argument");
13326                    return;
13327                }
13328                dumpClient = true;
13329            } else if ("-h".equals(opt)) {
13330                ActivityManagerShellCommand.dumpHelp(pw, true);
13331                return;
13332            } else {
13333                pw.println("Unknown argument: " + opt + "; use -h for help");
13334            }
13335        }
13336
13337        long origId = Binder.clearCallingIdentity();
13338        boolean more = false;
13339        // Is the caller requesting to dump a particular piece of data?
13340        if (opti < args.length) {
13341            String cmd = args[opti];
13342            opti++;
13343            if ("activities".equals(cmd) || "a".equals(cmd)) {
13344                synchronized (this) {
13345                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13346                }
13347            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13348                synchronized (this) {
13349                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13350                }
13351            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13352                String[] newArgs;
13353                String name;
13354                if (opti >= args.length) {
13355                    name = null;
13356                    newArgs = EMPTY_STRING_ARRAY;
13357                } else {
13358                    dumpPackage = args[opti];
13359                    opti++;
13360                    newArgs = new String[args.length - opti];
13361                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13362                            args.length - opti);
13363                }
13364                synchronized (this) {
13365                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13366                }
13367            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13368                String[] newArgs;
13369                String name;
13370                if (opti >= args.length) {
13371                    name = null;
13372                    newArgs = EMPTY_STRING_ARRAY;
13373                } else {
13374                    dumpPackage = args[opti];
13375                    opti++;
13376                    newArgs = new String[args.length - opti];
13377                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13378                            args.length - opti);
13379                }
13380                synchronized (this) {
13381                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13382                }
13383            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13384                String[] newArgs;
13385                String name;
13386                if (opti >= args.length) {
13387                    name = null;
13388                    newArgs = EMPTY_STRING_ARRAY;
13389                } else {
13390                    dumpPackage = args[opti];
13391                    opti++;
13392                    newArgs = new String[args.length - opti];
13393                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13394                            args.length - opti);
13395                }
13396                synchronized (this) {
13397                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13398                }
13399            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13400                synchronized (this) {
13401                    dumpOomLocked(fd, pw, args, opti, true);
13402                }
13403            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13404                synchronized (this) {
13405                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13406                }
13407            } else if ("provider".equals(cmd)) {
13408                String[] newArgs;
13409                String name;
13410                if (opti >= args.length) {
13411                    name = null;
13412                    newArgs = EMPTY_STRING_ARRAY;
13413                } else {
13414                    name = args[opti];
13415                    opti++;
13416                    newArgs = new String[args.length - opti];
13417                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13418                }
13419                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13420                    pw.println("No providers match: " + name);
13421                    pw.println("Use -h for help.");
13422                }
13423            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13424                synchronized (this) {
13425                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13426                }
13427            } else if ("service".equals(cmd)) {
13428                String[] newArgs;
13429                String name;
13430                if (opti >= args.length) {
13431                    name = null;
13432                    newArgs = EMPTY_STRING_ARRAY;
13433                } else {
13434                    name = args[opti];
13435                    opti++;
13436                    newArgs = new String[args.length - opti];
13437                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13438                            args.length - opti);
13439                }
13440                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13441                    pw.println("No services match: " + name);
13442                    pw.println("Use -h for help.");
13443                }
13444            } else if ("package".equals(cmd)) {
13445                String[] newArgs;
13446                if (opti >= args.length) {
13447                    pw.println("package: no package name specified");
13448                    pw.println("Use -h for help.");
13449                } else {
13450                    dumpPackage = args[opti];
13451                    opti++;
13452                    newArgs = new String[args.length - opti];
13453                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13454                            args.length - opti);
13455                    args = newArgs;
13456                    opti = 0;
13457                    more = true;
13458                }
13459            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13460                synchronized (this) {
13461                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13462                }
13463            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13464                synchronized (this) {
13465                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13466                }
13467            } else {
13468                // Dumping a single activity?
13469                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13470                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13471                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13472                    if (res < 0) {
13473                        pw.println("Bad activity command, or no activities match: " + cmd);
13474                        pw.println("Use -h for help.");
13475                    }
13476                }
13477            }
13478            if (!more) {
13479                Binder.restoreCallingIdentity(origId);
13480                return;
13481            }
13482        }
13483
13484        // No piece of data specified, dump everything.
13485        synchronized (this) {
13486            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13487            pw.println();
13488            if (dumpAll) {
13489                pw.println("-------------------------------------------------------------------------------");
13490            }
13491            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13492            pw.println();
13493            if (dumpAll) {
13494                pw.println("-------------------------------------------------------------------------------");
13495            }
13496            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13497            pw.println();
13498            if (dumpAll) {
13499                pw.println("-------------------------------------------------------------------------------");
13500            }
13501            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13502            pw.println();
13503            if (dumpAll) {
13504                pw.println("-------------------------------------------------------------------------------");
13505            }
13506            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13507            pw.println();
13508            if (dumpAll) {
13509                pw.println("-------------------------------------------------------------------------------");
13510            }
13511            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13512            pw.println();
13513            if (dumpAll) {
13514                pw.println("-------------------------------------------------------------------------------");
13515            }
13516            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13517            if (mAssociations.size() > 0) {
13518                pw.println();
13519                if (dumpAll) {
13520                    pw.println("-------------------------------------------------------------------------------");
13521                }
13522                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13523            }
13524            pw.println();
13525            if (dumpAll) {
13526                pw.println("-------------------------------------------------------------------------------");
13527            }
13528            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13529        }
13530        Binder.restoreCallingIdentity(origId);
13531    }
13532
13533    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13534            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13535        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13536
13537        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13538                dumpPackage);
13539        boolean needSep = printedAnything;
13540
13541        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13542                dumpPackage, needSep, "  mFocusedActivity: ");
13543        if (printed) {
13544            printedAnything = true;
13545            needSep = false;
13546        }
13547
13548        if (dumpPackage == null) {
13549            if (needSep) {
13550                pw.println();
13551            }
13552            needSep = true;
13553            printedAnything = true;
13554            mStackSupervisor.dump(pw, "  ");
13555        }
13556
13557        if (!printedAnything) {
13558            pw.println("  (nothing)");
13559        }
13560    }
13561
13562    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13563            int opti, boolean dumpAll, String dumpPackage) {
13564        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13565
13566        boolean printedAnything = false;
13567
13568        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13569            boolean printedHeader = false;
13570
13571            final int N = mRecentTasks.size();
13572            for (int i=0; i<N; i++) {
13573                TaskRecord tr = mRecentTasks.get(i);
13574                if (dumpPackage != null) {
13575                    if (tr.realActivity == null ||
13576                            !dumpPackage.equals(tr.realActivity)) {
13577                        continue;
13578                    }
13579                }
13580                if (!printedHeader) {
13581                    pw.println("  Recent tasks:");
13582                    printedHeader = true;
13583                    printedAnything = true;
13584                }
13585                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13586                        pw.println(tr);
13587                if (dumpAll) {
13588                    mRecentTasks.get(i).dump(pw, "    ");
13589                }
13590            }
13591        }
13592
13593        if (!printedAnything) {
13594            pw.println("  (nothing)");
13595        }
13596    }
13597
13598    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13599            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13600        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13601
13602        int dumpUid = 0;
13603        if (dumpPackage != null) {
13604            IPackageManager pm = AppGlobals.getPackageManager();
13605            try {
13606                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13607            } catch (RemoteException e) {
13608            }
13609        }
13610
13611        boolean printedAnything = false;
13612
13613        final long now = SystemClock.uptimeMillis();
13614
13615        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13616            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13617                    = mAssociations.valueAt(i1);
13618            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13619                SparseArray<ArrayMap<String, Association>> sourceUids
13620                        = targetComponents.valueAt(i2);
13621                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13622                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13623                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13624                        Association ass = sourceProcesses.valueAt(i4);
13625                        if (dumpPackage != null) {
13626                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13627                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13628                                continue;
13629                            }
13630                        }
13631                        printedAnything = true;
13632                        pw.print("  ");
13633                        pw.print(ass.mTargetProcess);
13634                        pw.print("/");
13635                        UserHandle.formatUid(pw, ass.mTargetUid);
13636                        pw.print(" <- ");
13637                        pw.print(ass.mSourceProcess);
13638                        pw.print("/");
13639                        UserHandle.formatUid(pw, ass.mSourceUid);
13640                        pw.println();
13641                        pw.print("    via ");
13642                        pw.print(ass.mTargetComponent.flattenToShortString());
13643                        pw.println();
13644                        pw.print("    ");
13645                        long dur = ass.mTime;
13646                        if (ass.mNesting > 0) {
13647                            dur += now - ass.mStartTime;
13648                        }
13649                        TimeUtils.formatDuration(dur, pw);
13650                        pw.print(" (");
13651                        pw.print(ass.mCount);
13652                        pw.println(" times)");
13653                        if (ass.mNesting > 0) {
13654                            pw.print("    ");
13655                            pw.print(" Currently active: ");
13656                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13657                            pw.println();
13658                        }
13659                    }
13660                }
13661            }
13662
13663        }
13664
13665        if (!printedAnything) {
13666            pw.println("  (nothing)");
13667        }
13668    }
13669
13670    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13671            String header, boolean needSep) {
13672        boolean printed = false;
13673        int whichAppId = -1;
13674        if (dumpPackage != null) {
13675            try {
13676                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13677                        dumpPackage, 0);
13678                whichAppId = UserHandle.getAppId(info.uid);
13679            } catch (NameNotFoundException e) {
13680                e.printStackTrace();
13681            }
13682        }
13683        for (int i=0; i<uids.size(); i++) {
13684            UidRecord uidRec = uids.valueAt(i);
13685            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13686                continue;
13687            }
13688            if (!printed) {
13689                printed = true;
13690                if (needSep) {
13691                    pw.println();
13692                }
13693                pw.print("  ");
13694                pw.println(header);
13695                needSep = true;
13696            }
13697            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13698            pw.print(": "); pw.println(uidRec);
13699        }
13700        return printed;
13701    }
13702
13703    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13704            int opti, boolean dumpAll, String dumpPackage) {
13705        boolean needSep = false;
13706        boolean printedAnything = false;
13707        int numPers = 0;
13708
13709        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13710
13711        if (dumpAll) {
13712            final int NP = mProcessNames.getMap().size();
13713            for (int ip=0; ip<NP; ip++) {
13714                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13715                final int NA = procs.size();
13716                for (int ia=0; ia<NA; ia++) {
13717                    ProcessRecord r = procs.valueAt(ia);
13718                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13719                        continue;
13720                    }
13721                    if (!needSep) {
13722                        pw.println("  All known processes:");
13723                        needSep = true;
13724                        printedAnything = true;
13725                    }
13726                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13727                        pw.print(" UID "); pw.print(procs.keyAt(ia));
13728                        pw.print(" "); pw.println(r);
13729                    r.dump(pw, "    ");
13730                    if (r.persistent) {
13731                        numPers++;
13732                    }
13733                }
13734            }
13735        }
13736
13737        if (mIsolatedProcesses.size() > 0) {
13738            boolean printed = false;
13739            for (int i=0; i<mIsolatedProcesses.size(); i++) {
13740                ProcessRecord r = mIsolatedProcesses.valueAt(i);
13741                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13742                    continue;
13743                }
13744                if (!printed) {
13745                    if (needSep) {
13746                        pw.println();
13747                    }
13748                    pw.println("  Isolated process list (sorted by uid):");
13749                    printedAnything = true;
13750                    printed = true;
13751                    needSep = true;
13752                }
13753                pw.println(String.format("%sIsolated #%2d: %s",
13754                        "    ", i, r.toString()));
13755            }
13756        }
13757
13758        if (mActiveUids.size() > 0) {
13759            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13760                printedAnything = needSep = true;
13761            }
13762        }
13763        if (mValidateUids.size() > 0) {
13764            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13765                printedAnything = needSep = true;
13766            }
13767        }
13768
13769        if (mLruProcesses.size() > 0) {
13770            if (needSep) {
13771                pw.println();
13772            }
13773            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13774                    pw.print(" total, non-act at ");
13775                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13776                    pw.print(", non-svc at ");
13777                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13778                    pw.println("):");
13779            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
13780            needSep = true;
13781            printedAnything = true;
13782        }
13783
13784        if (dumpAll || dumpPackage != null) {
13785            synchronized (mPidsSelfLocked) {
13786                boolean printed = false;
13787                for (int i=0; i<mPidsSelfLocked.size(); i++) {
13788                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
13789                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13790                        continue;
13791                    }
13792                    if (!printed) {
13793                        if (needSep) pw.println();
13794                        needSep = true;
13795                        pw.println("  PID mappings:");
13796                        printed = true;
13797                        printedAnything = true;
13798                    }
13799                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13800                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13801                }
13802            }
13803        }
13804
13805        if (mForegroundProcesses.size() > 0) {
13806            synchronized (mPidsSelfLocked) {
13807                boolean printed = false;
13808                for (int i=0; i<mForegroundProcesses.size(); i++) {
13809                    ProcessRecord r = mPidsSelfLocked.get(
13810                            mForegroundProcesses.valueAt(i).pid);
13811                    if (dumpPackage != null && (r == null
13812                            || !r.pkgList.containsKey(dumpPackage))) {
13813                        continue;
13814                    }
13815                    if (!printed) {
13816                        if (needSep) pw.println();
13817                        needSep = true;
13818                        pw.println("  Foreground Processes:");
13819                        printed = true;
13820                        printedAnything = true;
13821                    }
13822                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
13823                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13824                }
13825            }
13826        }
13827
13828        if (mPersistentStartingProcesses.size() > 0) {
13829            if (needSep) pw.println();
13830            needSep = true;
13831            printedAnything = true;
13832            pw.println("  Persisent processes that are starting:");
13833            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
13834                    "Starting Norm", "Restarting PERS", dumpPackage);
13835        }
13836
13837        if (mRemovedProcesses.size() > 0) {
13838            if (needSep) pw.println();
13839            needSep = true;
13840            printedAnything = true;
13841            pw.println("  Processes that are being removed:");
13842            dumpProcessList(pw, this, mRemovedProcesses, "    ",
13843                    "Removed Norm", "Removed PERS", dumpPackage);
13844        }
13845
13846        if (mProcessesOnHold.size() > 0) {
13847            if (needSep) pw.println();
13848            needSep = true;
13849            printedAnything = true;
13850            pw.println("  Processes that are on old until the system is ready:");
13851            dumpProcessList(pw, this, mProcessesOnHold, "    ",
13852                    "OnHold Norm", "OnHold PERS", dumpPackage);
13853        }
13854
13855        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13856
13857        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
13858        if (needSep) {
13859            printedAnything = true;
13860        }
13861
13862        if (dumpPackage == null) {
13863            pw.println();
13864            needSep = false;
13865            mUserController.dump(pw, dumpAll);
13866        }
13867        if (mHomeProcess != null && (dumpPackage == null
13868                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13869            if (needSep) {
13870                pw.println();
13871                needSep = false;
13872            }
13873            pw.println("  mHomeProcess: " + mHomeProcess);
13874        }
13875        if (mPreviousProcess != null && (dumpPackage == null
13876                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13877            if (needSep) {
13878                pw.println();
13879                needSep = false;
13880            }
13881            pw.println("  mPreviousProcess: " + mPreviousProcess);
13882        }
13883        if (dumpAll) {
13884            StringBuilder sb = new StringBuilder(128);
13885            sb.append("  mPreviousProcessVisibleTime: ");
13886            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13887            pw.println(sb);
13888        }
13889        if (mHeavyWeightProcess != null && (dumpPackage == null
13890                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13891            if (needSep) {
13892                pw.println();
13893                needSep = false;
13894            }
13895            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13896        }
13897        if (dumpPackage == null) {
13898            pw.println("  mConfiguration: " + mConfiguration);
13899        }
13900        if (dumpAll) {
13901            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13902            if (mCompatModePackages.getPackages().size() > 0) {
13903                boolean printed = false;
13904                for (Map.Entry<String, Integer> entry
13905                        : mCompatModePackages.getPackages().entrySet()) {
13906                    String pkg = entry.getKey();
13907                    int mode = entry.getValue();
13908                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13909                        continue;
13910                    }
13911                    if (!printed) {
13912                        pw.println("  mScreenCompatPackages:");
13913                        printed = true;
13914                    }
13915                    pw.print("    "); pw.print(pkg); pw.print(": ");
13916                            pw.print(mode); pw.println();
13917                }
13918            }
13919        }
13920        if (dumpPackage == null) {
13921            pw.println("  mWakefulness="
13922                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
13923            pw.println("  mSleepTokens=" + mSleepTokens);
13924            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13925                    + lockScreenShownToString());
13926            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13927            if (mRunningVoice != null) {
13928                pw.println("  mRunningVoice=" + mRunningVoice);
13929                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
13930            }
13931        }
13932        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13933                || mOrigWaitForDebugger) {
13934            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13935                    || dumpPackage.equals(mOrigDebugApp)) {
13936                if (needSep) {
13937                    pw.println();
13938                    needSep = false;
13939                }
13940                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13941                        + " mDebugTransient=" + mDebugTransient
13942                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13943            }
13944        }
13945        if (mCurAppTimeTracker != null) {
13946            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
13947        }
13948        if (mMemWatchProcesses.getMap().size() > 0) {
13949            pw.println("  Mem watch processes:");
13950            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13951                    = mMemWatchProcesses.getMap();
13952            for (int i=0; i<procs.size(); i++) {
13953                final String proc = procs.keyAt(i);
13954                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13955                for (int j=0; j<uids.size(); j++) {
13956                    if (needSep) {
13957                        pw.println();
13958                        needSep = false;
13959                    }
13960                    StringBuilder sb = new StringBuilder();
13961                    sb.append("    ").append(proc).append('/');
13962                    UserHandle.formatUid(sb, uids.keyAt(j));
13963                    Pair<Long, String> val = uids.valueAt(j);
13964                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13965                    if (val.second != null) {
13966                        sb.append(", report to ").append(val.second);
13967                    }
13968                    pw.println(sb.toString());
13969                }
13970            }
13971            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13972            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13973            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13974                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13975        }
13976        if (mTrackAllocationApp != null) {
13977            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
13978                if (needSep) {
13979                    pw.println();
13980                    needSep = false;
13981                }
13982                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
13983            }
13984        }
13985        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13986                || mProfileFd != null) {
13987            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13988                if (needSep) {
13989                    pw.println();
13990                    needSep = false;
13991                }
13992                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13993                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13994                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13995                        + mAutoStopProfiler);
13996                pw.println("  mProfileType=" + mProfileType);
13997            }
13998        }
13999        if (mNativeDebuggingApp != null) {
14000            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14001                if (needSep) {
14002                    pw.println();
14003                    needSep = false;
14004                }
14005                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14006            }
14007        }
14008        if (dumpPackage == null) {
14009            if (mAlwaysFinishActivities || mController != null) {
14010                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14011                        + " mController=" + mController);
14012            }
14013            if (dumpAll) {
14014                pw.println("  Total persistent processes: " + numPers);
14015                pw.println("  mProcessesReady=" + mProcessesReady
14016                        + " mSystemReady=" + mSystemReady
14017                        + " mBooted=" + mBooted
14018                        + " mFactoryTest=" + mFactoryTest);
14019                pw.println("  mBooting=" + mBooting
14020                        + " mCallFinishBooting=" + mCallFinishBooting
14021                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14022                pw.print("  mLastPowerCheckRealtime=");
14023                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14024                        pw.println("");
14025                pw.print("  mLastPowerCheckUptime=");
14026                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14027                        pw.println("");
14028                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14029                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14030                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14031                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14032                        + " (" + mLruProcesses.size() + " total)"
14033                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14034                        + " mNumServiceProcs=" + mNumServiceProcs
14035                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14036                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14037                        + " mLastMemoryLevel" + mLastMemoryLevel
14038                        + " mLastNumProcesses" + mLastNumProcesses);
14039                long now = SystemClock.uptimeMillis();
14040                pw.print("  mLastIdleTime=");
14041                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14042                        pw.print(" mLowRamSinceLastIdle=");
14043                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14044                        pw.println();
14045            }
14046        }
14047
14048        if (!printedAnything) {
14049            pw.println("  (nothing)");
14050        }
14051    }
14052
14053    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14054            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14055        if (mProcessesToGc.size() > 0) {
14056            boolean printed = false;
14057            long now = SystemClock.uptimeMillis();
14058            for (int i=0; i<mProcessesToGc.size(); i++) {
14059                ProcessRecord proc = mProcessesToGc.get(i);
14060                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14061                    continue;
14062                }
14063                if (!printed) {
14064                    if (needSep) pw.println();
14065                    needSep = true;
14066                    pw.println("  Processes that are waiting to GC:");
14067                    printed = true;
14068                }
14069                pw.print("    Process "); pw.println(proc);
14070                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14071                        pw.print(", last gced=");
14072                        pw.print(now-proc.lastRequestedGc);
14073                        pw.print(" ms ago, last lowMem=");
14074                        pw.print(now-proc.lastLowMemory);
14075                        pw.println(" ms ago");
14076
14077            }
14078        }
14079        return needSep;
14080    }
14081
14082    void printOomLevel(PrintWriter pw, String name, int adj) {
14083        pw.print("    ");
14084        if (adj >= 0) {
14085            pw.print(' ');
14086            if (adj < 10) pw.print(' ');
14087        } else {
14088            if (adj > -10) pw.print(' ');
14089        }
14090        pw.print(adj);
14091        pw.print(": ");
14092        pw.print(name);
14093        pw.print(" (");
14094        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14095        pw.println(")");
14096    }
14097
14098    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14099            int opti, boolean dumpAll) {
14100        boolean needSep = false;
14101
14102        if (mLruProcesses.size() > 0) {
14103            if (needSep) pw.println();
14104            needSep = true;
14105            pw.println("  OOM levels:");
14106            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14107            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14108            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14109            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14110            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14111            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14112            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14113            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14114            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14115            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14116            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14117            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14118            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14119            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14120
14121            if (needSep) pw.println();
14122            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14123                    pw.print(" total, non-act at ");
14124                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14125                    pw.print(", non-svc at ");
14126                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14127                    pw.println("):");
14128            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14129            needSep = true;
14130        }
14131
14132        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14133
14134        pw.println();
14135        pw.println("  mHomeProcess: " + mHomeProcess);
14136        pw.println("  mPreviousProcess: " + mPreviousProcess);
14137        if (mHeavyWeightProcess != null) {
14138            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14139        }
14140
14141        return true;
14142    }
14143
14144    /**
14145     * There are three ways to call this:
14146     *  - no provider specified: dump all the providers
14147     *  - a flattened component name that matched an existing provider was specified as the
14148     *    first arg: dump that one provider
14149     *  - the first arg isn't the flattened component name of an existing provider:
14150     *    dump all providers whose component contains the first arg as a substring
14151     */
14152    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14153            int opti, boolean dumpAll) {
14154        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14155    }
14156
14157    static class ItemMatcher {
14158        ArrayList<ComponentName> components;
14159        ArrayList<String> strings;
14160        ArrayList<Integer> objects;
14161        boolean all;
14162
14163        ItemMatcher() {
14164            all = true;
14165        }
14166
14167        void build(String name) {
14168            ComponentName componentName = ComponentName.unflattenFromString(name);
14169            if (componentName != null) {
14170                if (components == null) {
14171                    components = new ArrayList<ComponentName>();
14172                }
14173                components.add(componentName);
14174                all = false;
14175            } else {
14176                int objectId = 0;
14177                // Not a '/' separated full component name; maybe an object ID?
14178                try {
14179                    objectId = Integer.parseInt(name, 16);
14180                    if (objects == null) {
14181                        objects = new ArrayList<Integer>();
14182                    }
14183                    objects.add(objectId);
14184                    all = false;
14185                } catch (RuntimeException e) {
14186                    // Not an integer; just do string match.
14187                    if (strings == null) {
14188                        strings = new ArrayList<String>();
14189                    }
14190                    strings.add(name);
14191                    all = false;
14192                }
14193            }
14194        }
14195
14196        int build(String[] args, int opti) {
14197            for (; opti<args.length; opti++) {
14198                String name = args[opti];
14199                if ("--".equals(name)) {
14200                    return opti+1;
14201                }
14202                build(name);
14203            }
14204            return opti;
14205        }
14206
14207        boolean match(Object object, ComponentName comp) {
14208            if (all) {
14209                return true;
14210            }
14211            if (components != null) {
14212                for (int i=0; i<components.size(); i++) {
14213                    if (components.get(i).equals(comp)) {
14214                        return true;
14215                    }
14216                }
14217            }
14218            if (objects != null) {
14219                for (int i=0; i<objects.size(); i++) {
14220                    if (System.identityHashCode(object) == objects.get(i)) {
14221                        return true;
14222                    }
14223                }
14224            }
14225            if (strings != null) {
14226                String flat = comp.flattenToString();
14227                for (int i=0; i<strings.size(); i++) {
14228                    if (flat.contains(strings.get(i))) {
14229                        return true;
14230                    }
14231                }
14232            }
14233            return false;
14234        }
14235    }
14236
14237    /**
14238     * There are three things that cmd can be:
14239     *  - a flattened component name that matches an existing activity
14240     *  - the cmd arg isn't the flattened component name of an existing activity:
14241     *    dump all activity whose component contains the cmd as a substring
14242     *  - A hex number of the ActivityRecord object instance.
14243     */
14244    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14245            int opti, boolean dumpAll) {
14246        ArrayList<ActivityRecord> activities;
14247
14248        synchronized (this) {
14249            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14250        }
14251
14252        if (activities.size() <= 0) {
14253            return false;
14254        }
14255
14256        String[] newArgs = new String[args.length - opti];
14257        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14258
14259        TaskRecord lastTask = null;
14260        boolean needSep = false;
14261        for (int i=activities.size()-1; i>=0; i--) {
14262            ActivityRecord r = activities.get(i);
14263            if (needSep) {
14264                pw.println();
14265            }
14266            needSep = true;
14267            synchronized (this) {
14268                if (lastTask != r.task) {
14269                    lastTask = r.task;
14270                    pw.print("TASK "); pw.print(lastTask.affinity);
14271                            pw.print(" id="); pw.println(lastTask.taskId);
14272                    if (dumpAll) {
14273                        lastTask.dump(pw, "  ");
14274                    }
14275                }
14276            }
14277            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14278        }
14279        return true;
14280    }
14281
14282    /**
14283     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14284     * there is a thread associated with the activity.
14285     */
14286    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14287            final ActivityRecord r, String[] args, boolean dumpAll) {
14288        String innerPrefix = prefix + "  ";
14289        synchronized (this) {
14290            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14291                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14292                    pw.print(" pid=");
14293                    if (r.app != null) pw.println(r.app.pid);
14294                    else pw.println("(not running)");
14295            if (dumpAll) {
14296                r.dump(pw, innerPrefix);
14297            }
14298        }
14299        if (r.app != null && r.app.thread != null) {
14300            // flush anything that is already in the PrintWriter since the thread is going
14301            // to write to the file descriptor directly
14302            pw.flush();
14303            try {
14304                TransferPipe tp = new TransferPipe();
14305                try {
14306                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14307                            r.appToken, innerPrefix, args);
14308                    tp.go(fd);
14309                } finally {
14310                    tp.kill();
14311                }
14312            } catch (IOException e) {
14313                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14314            } catch (RemoteException e) {
14315                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14316            }
14317        }
14318    }
14319
14320    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14321            int opti, boolean dumpAll, String dumpPackage) {
14322        boolean needSep = false;
14323        boolean onlyHistory = false;
14324        boolean printedAnything = false;
14325
14326        if ("history".equals(dumpPackage)) {
14327            if (opti < args.length && "-s".equals(args[opti])) {
14328                dumpAll = false;
14329            }
14330            onlyHistory = true;
14331            dumpPackage = null;
14332        }
14333
14334        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14335        if (!onlyHistory && dumpAll) {
14336            if (mRegisteredReceivers.size() > 0) {
14337                boolean printed = false;
14338                Iterator it = mRegisteredReceivers.values().iterator();
14339                while (it.hasNext()) {
14340                    ReceiverList r = (ReceiverList)it.next();
14341                    if (dumpPackage != null && (r.app == null ||
14342                            !dumpPackage.equals(r.app.info.packageName))) {
14343                        continue;
14344                    }
14345                    if (!printed) {
14346                        pw.println("  Registered Receivers:");
14347                        needSep = true;
14348                        printed = true;
14349                        printedAnything = true;
14350                    }
14351                    pw.print("  * "); pw.println(r);
14352                    r.dump(pw, "    ");
14353                }
14354            }
14355
14356            if (mReceiverResolver.dump(pw, needSep ?
14357                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14358                    "    ", dumpPackage, false, false)) {
14359                needSep = true;
14360                printedAnything = true;
14361            }
14362        }
14363
14364        for (BroadcastQueue q : mBroadcastQueues) {
14365            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14366            printedAnything |= needSep;
14367        }
14368
14369        needSep = true;
14370
14371        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14372            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14373                if (needSep) {
14374                    pw.println();
14375                }
14376                needSep = true;
14377                printedAnything = true;
14378                pw.print("  Sticky broadcasts for user ");
14379                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14380                StringBuilder sb = new StringBuilder(128);
14381                for (Map.Entry<String, ArrayList<Intent>> ent
14382                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14383                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14384                    if (dumpAll) {
14385                        pw.println(":");
14386                        ArrayList<Intent> intents = ent.getValue();
14387                        final int N = intents.size();
14388                        for (int i=0; i<N; i++) {
14389                            sb.setLength(0);
14390                            sb.append("    Intent: ");
14391                            intents.get(i).toShortString(sb, false, true, false, false);
14392                            pw.println(sb.toString());
14393                            Bundle bundle = intents.get(i).getExtras();
14394                            if (bundle != null) {
14395                                pw.print("      ");
14396                                pw.println(bundle.toString());
14397                            }
14398                        }
14399                    } else {
14400                        pw.println("");
14401                    }
14402                }
14403            }
14404        }
14405
14406        if (!onlyHistory && dumpAll) {
14407            pw.println();
14408            for (BroadcastQueue queue : mBroadcastQueues) {
14409                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14410                        + queue.mBroadcastsScheduled);
14411            }
14412            pw.println("  mHandler:");
14413            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14414            needSep = true;
14415            printedAnything = true;
14416        }
14417
14418        if (!printedAnything) {
14419            pw.println("  (nothing)");
14420        }
14421    }
14422
14423    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14424            int opti, boolean dumpAll, String dumpPackage) {
14425        boolean needSep;
14426        boolean printedAnything = false;
14427
14428        ItemMatcher matcher = new ItemMatcher();
14429        matcher.build(args, opti);
14430
14431        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14432
14433        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14434        printedAnything |= needSep;
14435
14436        if (mLaunchingProviders.size() > 0) {
14437            boolean printed = false;
14438            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14439                ContentProviderRecord r = mLaunchingProviders.get(i);
14440                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14441                    continue;
14442                }
14443                if (!printed) {
14444                    if (needSep) pw.println();
14445                    needSep = true;
14446                    pw.println("  Launching content providers:");
14447                    printed = true;
14448                    printedAnything = true;
14449                }
14450                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14451                        pw.println(r);
14452            }
14453        }
14454
14455        if (!printedAnything) {
14456            pw.println("  (nothing)");
14457        }
14458    }
14459
14460    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14461            int opti, boolean dumpAll, String dumpPackage) {
14462        boolean needSep = false;
14463        boolean printedAnything = false;
14464
14465        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14466
14467        if (mGrantedUriPermissions.size() > 0) {
14468            boolean printed = false;
14469            int dumpUid = -2;
14470            if (dumpPackage != null) {
14471                try {
14472                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14473                            MATCH_UNINSTALLED_PACKAGES, 0);
14474                } catch (NameNotFoundException e) {
14475                    dumpUid = -1;
14476                }
14477            }
14478            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14479                int uid = mGrantedUriPermissions.keyAt(i);
14480                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14481                    continue;
14482                }
14483                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14484                if (!printed) {
14485                    if (needSep) pw.println();
14486                    needSep = true;
14487                    pw.println("  Granted Uri Permissions:");
14488                    printed = true;
14489                    printedAnything = true;
14490                }
14491                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14492                for (UriPermission perm : perms.values()) {
14493                    pw.print("    "); pw.println(perm);
14494                    if (dumpAll) {
14495                        perm.dump(pw, "      ");
14496                    }
14497                }
14498            }
14499        }
14500
14501        if (!printedAnything) {
14502            pw.println("  (nothing)");
14503        }
14504    }
14505
14506    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14507            int opti, boolean dumpAll, String dumpPackage) {
14508        boolean printed = false;
14509
14510        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14511
14512        if (mIntentSenderRecords.size() > 0) {
14513            Iterator<WeakReference<PendingIntentRecord>> it
14514                    = mIntentSenderRecords.values().iterator();
14515            while (it.hasNext()) {
14516                WeakReference<PendingIntentRecord> ref = it.next();
14517                PendingIntentRecord rec = ref != null ? ref.get(): null;
14518                if (dumpPackage != null && (rec == null
14519                        || !dumpPackage.equals(rec.key.packageName))) {
14520                    continue;
14521                }
14522                printed = true;
14523                if (rec != null) {
14524                    pw.print("  * "); pw.println(rec);
14525                    if (dumpAll) {
14526                        rec.dump(pw, "    ");
14527                    }
14528                } else {
14529                    pw.print("  * "); pw.println(ref);
14530                }
14531            }
14532        }
14533
14534        if (!printed) {
14535            pw.println("  (nothing)");
14536        }
14537    }
14538
14539    private static final int dumpProcessList(PrintWriter pw,
14540            ActivityManagerService service, List list,
14541            String prefix, String normalLabel, String persistentLabel,
14542            String dumpPackage) {
14543        int numPers = 0;
14544        final int N = list.size()-1;
14545        for (int i=N; i>=0; i--) {
14546            ProcessRecord r = (ProcessRecord)list.get(i);
14547            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14548                continue;
14549            }
14550            pw.println(String.format("%s%s #%2d: %s",
14551                    prefix, (r.persistent ? persistentLabel : normalLabel),
14552                    i, r.toString()));
14553            if (r.persistent) {
14554                numPers++;
14555            }
14556        }
14557        return numPers;
14558    }
14559
14560    private static final boolean dumpProcessOomList(PrintWriter pw,
14561            ActivityManagerService service, List<ProcessRecord> origList,
14562            String prefix, String normalLabel, String persistentLabel,
14563            boolean inclDetails, String dumpPackage) {
14564
14565        ArrayList<Pair<ProcessRecord, Integer>> list
14566                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14567        for (int i=0; i<origList.size(); i++) {
14568            ProcessRecord r = origList.get(i);
14569            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14570                continue;
14571            }
14572            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14573        }
14574
14575        if (list.size() <= 0) {
14576            return false;
14577        }
14578
14579        Comparator<Pair<ProcessRecord, Integer>> comparator
14580                = new Comparator<Pair<ProcessRecord, Integer>>() {
14581            @Override
14582            public int compare(Pair<ProcessRecord, Integer> object1,
14583                    Pair<ProcessRecord, Integer> object2) {
14584                if (object1.first.setAdj != object2.first.setAdj) {
14585                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14586                }
14587                if (object1.first.setProcState != object2.first.setProcState) {
14588                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14589                }
14590                if (object1.second.intValue() != object2.second.intValue()) {
14591                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14592                }
14593                return 0;
14594            }
14595        };
14596
14597        Collections.sort(list, comparator);
14598
14599        final long curRealtime = SystemClock.elapsedRealtime();
14600        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14601        final long curUptime = SystemClock.uptimeMillis();
14602        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14603
14604        for (int i=list.size()-1; i>=0; i--) {
14605            ProcessRecord r = list.get(i).first;
14606            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14607            char schedGroup;
14608            switch (r.setSchedGroup) {
14609                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14610                    schedGroup = 'B';
14611                    break;
14612                case Process.THREAD_GROUP_DEFAULT:
14613                    schedGroup = 'F';
14614                    break;
14615                default:
14616                    schedGroup = '?';
14617                    break;
14618            }
14619            char foreground;
14620            if (r.foregroundActivities) {
14621                foreground = 'A';
14622            } else if (r.foregroundServices) {
14623                foreground = 'S';
14624            } else {
14625                foreground = ' ';
14626            }
14627            String procState = ProcessList.makeProcStateString(r.curProcState);
14628            pw.print(prefix);
14629            pw.print(r.persistent ? persistentLabel : normalLabel);
14630            pw.print(" #");
14631            int num = (origList.size()-1)-list.get(i).second;
14632            if (num < 10) pw.print(' ');
14633            pw.print(num);
14634            pw.print(": ");
14635            pw.print(oomAdj);
14636            pw.print(' ');
14637            pw.print(schedGroup);
14638            pw.print('/');
14639            pw.print(foreground);
14640            pw.print('/');
14641            pw.print(procState);
14642            pw.print(" trm:");
14643            if (r.trimMemoryLevel < 10) pw.print(' ');
14644            pw.print(r.trimMemoryLevel);
14645            pw.print(' ');
14646            pw.print(r.toShortString());
14647            pw.print(" (");
14648            pw.print(r.adjType);
14649            pw.println(')');
14650            if (r.adjSource != null || r.adjTarget != null) {
14651                pw.print(prefix);
14652                pw.print("    ");
14653                if (r.adjTarget instanceof ComponentName) {
14654                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14655                } else if (r.adjTarget != null) {
14656                    pw.print(r.adjTarget.toString());
14657                } else {
14658                    pw.print("{null}");
14659                }
14660                pw.print("<=");
14661                if (r.adjSource instanceof ProcessRecord) {
14662                    pw.print("Proc{");
14663                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14664                    pw.println("}");
14665                } else if (r.adjSource != null) {
14666                    pw.println(r.adjSource.toString());
14667                } else {
14668                    pw.println("{null}");
14669                }
14670            }
14671            if (inclDetails) {
14672                pw.print(prefix);
14673                pw.print("    ");
14674                pw.print("oom: max="); pw.print(r.maxAdj);
14675                pw.print(" curRaw="); pw.print(r.curRawAdj);
14676                pw.print(" setRaw="); pw.print(r.setRawAdj);
14677                pw.print(" cur="); pw.print(r.curAdj);
14678                pw.print(" set="); pw.println(r.setAdj);
14679                pw.print(prefix);
14680                pw.print("    ");
14681                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14682                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14683                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14684                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14685                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14686                pw.println();
14687                pw.print(prefix);
14688                pw.print("    ");
14689                pw.print("cached="); pw.print(r.cached);
14690                pw.print(" empty="); pw.print(r.empty);
14691                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14692
14693                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14694                    if (r.lastWakeTime != 0) {
14695                        long wtime;
14696                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14697                        synchronized (stats) {
14698                            wtime = stats.getProcessWakeTime(r.info.uid,
14699                                    r.pid, curRealtime);
14700                        }
14701                        long timeUsed = wtime - r.lastWakeTime;
14702                        pw.print(prefix);
14703                        pw.print("    ");
14704                        pw.print("keep awake over ");
14705                        TimeUtils.formatDuration(realtimeSince, pw);
14706                        pw.print(" used ");
14707                        TimeUtils.formatDuration(timeUsed, pw);
14708                        pw.print(" (");
14709                        pw.print((timeUsed*100)/realtimeSince);
14710                        pw.println("%)");
14711                    }
14712                    if (r.lastCpuTime != 0) {
14713                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14714                        pw.print(prefix);
14715                        pw.print("    ");
14716                        pw.print("run cpu over ");
14717                        TimeUtils.formatDuration(uptimeSince, pw);
14718                        pw.print(" used ");
14719                        TimeUtils.formatDuration(timeUsed, pw);
14720                        pw.print(" (");
14721                        pw.print((timeUsed*100)/uptimeSince);
14722                        pw.println("%)");
14723                    }
14724                }
14725            }
14726        }
14727        return true;
14728    }
14729
14730    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14731            String[] args) {
14732        ArrayList<ProcessRecord> procs;
14733        synchronized (this) {
14734            if (args != null && args.length > start
14735                    && args[start].charAt(0) != '-') {
14736                procs = new ArrayList<ProcessRecord>();
14737                int pid = -1;
14738                try {
14739                    pid = Integer.parseInt(args[start]);
14740                } catch (NumberFormatException e) {
14741                }
14742                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14743                    ProcessRecord proc = mLruProcesses.get(i);
14744                    if (proc.pid == pid) {
14745                        procs.add(proc);
14746                    } else if (allPkgs && proc.pkgList != null
14747                            && proc.pkgList.containsKey(args[start])) {
14748                        procs.add(proc);
14749                    } else if (proc.processName.equals(args[start])) {
14750                        procs.add(proc);
14751                    }
14752                }
14753                if (procs.size() <= 0) {
14754                    return null;
14755                }
14756            } else {
14757                procs = new ArrayList<ProcessRecord>(mLruProcesses);
14758            }
14759        }
14760        return procs;
14761    }
14762
14763    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14764            PrintWriter pw, String[] args) {
14765        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14766        if (procs == null) {
14767            pw.println("No process found for: " + args[0]);
14768            return;
14769        }
14770
14771        long uptime = SystemClock.uptimeMillis();
14772        long realtime = SystemClock.elapsedRealtime();
14773        pw.println("Applications Graphics Acceleration Info:");
14774        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14775
14776        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14777            ProcessRecord r = procs.get(i);
14778            if (r.thread != null) {
14779                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14780                pw.flush();
14781                try {
14782                    TransferPipe tp = new TransferPipe();
14783                    try {
14784                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14785                        tp.go(fd);
14786                    } finally {
14787                        tp.kill();
14788                    }
14789                } catch (IOException e) {
14790                    pw.println("Failure while dumping the app: " + r);
14791                    pw.flush();
14792                } catch (RemoteException e) {
14793                    pw.println("Got a RemoteException while dumping the app " + r);
14794                    pw.flush();
14795                }
14796            }
14797        }
14798    }
14799
14800    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14801        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14802        if (procs == null) {
14803            pw.println("No process found for: " + args[0]);
14804            return;
14805        }
14806
14807        pw.println("Applications Database Info:");
14808
14809        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14810            ProcessRecord r = procs.get(i);
14811            if (r.thread != null) {
14812                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14813                pw.flush();
14814                try {
14815                    TransferPipe tp = new TransferPipe();
14816                    try {
14817                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14818                        tp.go(fd);
14819                    } finally {
14820                        tp.kill();
14821                    }
14822                } catch (IOException e) {
14823                    pw.println("Failure while dumping the app: " + r);
14824                    pw.flush();
14825                } catch (RemoteException e) {
14826                    pw.println("Got a RemoteException while dumping the app " + r);
14827                    pw.flush();
14828                }
14829            }
14830        }
14831    }
14832
14833    final static class MemItem {
14834        final boolean isProc;
14835        final String label;
14836        final String shortLabel;
14837        final long pss;
14838        final long swapPss;
14839        final int id;
14840        final boolean hasActivities;
14841        ArrayList<MemItem> subitems;
14842
14843        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
14844                boolean _hasActivities) {
14845            isProc = true;
14846            label = _label;
14847            shortLabel = _shortLabel;
14848            pss = _pss;
14849            swapPss = _swapPss;
14850            id = _id;
14851            hasActivities = _hasActivities;
14852        }
14853
14854        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
14855            isProc = false;
14856            label = _label;
14857            shortLabel = _shortLabel;
14858            pss = _pss;
14859            swapPss = _swapPss;
14860            id = _id;
14861            hasActivities = false;
14862        }
14863    }
14864
14865    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14866            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
14867        if (sort && !isCompact) {
14868            Collections.sort(items, new Comparator<MemItem>() {
14869                @Override
14870                public int compare(MemItem lhs, MemItem rhs) {
14871                    if (lhs.pss < rhs.pss) {
14872                        return 1;
14873                    } else if (lhs.pss > rhs.pss) {
14874                        return -1;
14875                    }
14876                    return 0;
14877                }
14878            });
14879        }
14880
14881        for (int i=0; i<items.size(); i++) {
14882            MemItem mi = items.get(i);
14883            if (!isCompact) {
14884                if (dumpSwapPss) {
14885                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
14886                            mi.label, stringifyKBSize(mi.swapPss));
14887                } else {
14888                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
14889                }
14890            } else if (mi.isProc) {
14891                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14892                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
14893                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
14894                pw.println(mi.hasActivities ? ",a" : ",e");
14895            } else {
14896                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14897                pw.println(mi.pss); pw.print(dumpSwapPss ? mi.swapPss : "N/A");
14898            }
14899            if (mi.subitems != null) {
14900                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
14901                        true, isCompact, dumpSwapPss);
14902            }
14903        }
14904    }
14905
14906    // These are in KB.
14907    static final long[] DUMP_MEM_BUCKETS = new long[] {
14908        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14909        120*1024, 160*1024, 200*1024,
14910        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14911        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14912    };
14913
14914    static final void appendMemBucket(StringBuilder out, long memKB, String label,
14915            boolean stackLike) {
14916        int start = label.lastIndexOf('.');
14917        if (start >= 0) start++;
14918        else start = 0;
14919        int end = label.length();
14920        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14921            if (DUMP_MEM_BUCKETS[i] >= memKB) {
14922                long bucket = DUMP_MEM_BUCKETS[i]/1024;
14923                out.append(bucket);
14924                out.append(stackLike ? "MB." : "MB ");
14925                out.append(label, start, end);
14926                return;
14927            }
14928        }
14929        out.append(memKB/1024);
14930        out.append(stackLike ? "MB." : "MB ");
14931        out.append(label, start, end);
14932    }
14933
14934    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14935            ProcessList.NATIVE_ADJ,
14936            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14937            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14938            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14939            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14940            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14941            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14942    };
14943    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14944            "Native",
14945            "System", "Persistent", "Persistent Service", "Foreground",
14946            "Visible", "Perceptible",
14947            "Heavy Weight", "Backup",
14948            "A Services", "Home",
14949            "Previous", "B Services", "Cached"
14950    };
14951    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14952            "native",
14953            "sys", "pers", "persvc", "fore",
14954            "vis", "percept",
14955            "heavy", "backup",
14956            "servicea", "home",
14957            "prev", "serviceb", "cached"
14958    };
14959
14960    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14961            long realtime, boolean isCheckinRequest, boolean isCompact) {
14962        if (isCheckinRequest || isCompact) {
14963            // short checkin version
14964            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14965        } else {
14966            pw.println("Applications Memory Usage (in Kilobytes):");
14967            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14968        }
14969    }
14970
14971    private static final int KSM_SHARED = 0;
14972    private static final int KSM_SHARING = 1;
14973    private static final int KSM_UNSHARED = 2;
14974    private static final int KSM_VOLATILE = 3;
14975
14976    private final long[] getKsmInfo() {
14977        long[] longOut = new long[4];
14978        final int[] SINGLE_LONG_FORMAT = new int[] {
14979            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14980        };
14981        long[] longTmp = new long[1];
14982        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14983                SINGLE_LONG_FORMAT, null, longTmp, null);
14984        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14985        longTmp[0] = 0;
14986        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14987                SINGLE_LONG_FORMAT, null, longTmp, null);
14988        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14989        longTmp[0] = 0;
14990        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14991                SINGLE_LONG_FORMAT, null, longTmp, null);
14992        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14993        longTmp[0] = 0;
14994        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14995                SINGLE_LONG_FORMAT, null, longTmp, null);
14996        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14997        return longOut;
14998    }
14999
15000    private static String stringifySize(long size, int order) {
15001        Locale locale = Locale.US;
15002        switch (order) {
15003            case 1:
15004                return String.format(locale, "%,13d", size);
15005            case 1024:
15006                return String.format(locale, "%,9dK", size / 1024);
15007            case 1024 * 1024:
15008                return String.format(locale, "%,5dM", size / 1024 / 1024);
15009            case 1024 * 1024 * 1024:
15010                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15011            default:
15012                throw new IllegalArgumentException("Invalid size order");
15013        }
15014    }
15015
15016    private static String stringifyKBSize(long size) {
15017        return stringifySize(size * 1024, 1024);
15018    }
15019
15020    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15021            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15022        boolean dumpDetails = false;
15023        boolean dumpFullDetails = false;
15024        boolean dumpDalvik = false;
15025        boolean dumpSummaryOnly = false;
15026        boolean oomOnly = false;
15027        boolean isCompact = false;
15028        boolean localOnly = false;
15029        boolean packages = false;
15030        boolean isCheckinRequest = false;
15031        boolean dumpSwapPss = false;
15032
15033        int opti = 0;
15034        while (opti < args.length) {
15035            String opt = args[opti];
15036            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15037                break;
15038            }
15039            opti++;
15040            if ("-a".equals(opt)) {
15041                dumpDetails = true;
15042                dumpFullDetails = true;
15043                dumpDalvik = true;
15044                dumpSwapPss = true;
15045            } else if ("-d".equals(opt)) {
15046                dumpDalvik = true;
15047            } else if ("-c".equals(opt)) {
15048                isCompact = true;
15049            } else if ("-s".equals(opt)) {
15050                dumpDetails = true;
15051                dumpSummaryOnly = true;
15052            } else if ("-S".equals(opt)) {
15053                dumpSwapPss = true;
15054            } else if ("--oom".equals(opt)) {
15055                oomOnly = true;
15056            } else if ("--local".equals(opt)) {
15057                localOnly = true;
15058            } else if ("--package".equals(opt)) {
15059                packages = true;
15060            } else if ("--checkin".equals(opt)) {
15061                isCheckinRequest = true;
15062
15063            } else if ("-h".equals(opt)) {
15064                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15065                pw.println("  -a: include all available information for each process.");
15066                pw.println("  -d: include dalvik details.");
15067                pw.println("  -c: dump in a compact machine-parseable representation.");
15068                pw.println("  -s: dump only summary of application memory usage.");
15069                pw.println("  -S: dump also SwapPss.");
15070                pw.println("  --oom: only show processes organized by oom adj.");
15071                pw.println("  --local: only collect details locally, don't call process.");
15072                pw.println("  --package: interpret process arg as package, dumping all");
15073                pw.println("             processes that have loaded that package.");
15074                pw.println("  --checkin: dump data for a checkin");
15075                pw.println("If [process] is specified it can be the name or ");
15076                pw.println("pid of a specific process to dump.");
15077                return;
15078            } else {
15079                pw.println("Unknown argument: " + opt + "; use -h for help");
15080            }
15081        }
15082
15083        long uptime = SystemClock.uptimeMillis();
15084        long realtime = SystemClock.elapsedRealtime();
15085        final long[] tmpLong = new long[1];
15086
15087        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15088        if (procs == null) {
15089            // No Java processes.  Maybe they want to print a native process.
15090            if (args != null && args.length > opti
15091                    && args[opti].charAt(0) != '-') {
15092                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15093                        = new ArrayList<ProcessCpuTracker.Stats>();
15094                updateCpuStatsNow();
15095                int findPid = -1;
15096                try {
15097                    findPid = Integer.parseInt(args[opti]);
15098                } catch (NumberFormatException e) {
15099                }
15100                synchronized (mProcessCpuTracker) {
15101                    final int N = mProcessCpuTracker.countStats();
15102                    for (int i=0; i<N; i++) {
15103                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15104                        if (st.pid == findPid || (st.baseName != null
15105                                && st.baseName.equals(args[opti]))) {
15106                            nativeProcs.add(st);
15107                        }
15108                    }
15109                }
15110                if (nativeProcs.size() > 0) {
15111                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15112                            isCompact);
15113                    Debug.MemoryInfo mi = null;
15114                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15115                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15116                        final int pid = r.pid;
15117                        if (!isCheckinRequest && dumpDetails) {
15118                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15119                        }
15120                        if (mi == null) {
15121                            mi = new Debug.MemoryInfo();
15122                        }
15123                        if (dumpDetails || (!brief && !oomOnly)) {
15124                            Debug.getMemoryInfo(pid, mi);
15125                        } else {
15126                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15127                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15128                        }
15129                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15130                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15131                        if (isCheckinRequest) {
15132                            pw.println();
15133                        }
15134                    }
15135                    return;
15136                }
15137            }
15138            pw.println("No process found for: " + args[opti]);
15139            return;
15140        }
15141
15142        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15143            dumpDetails = true;
15144        }
15145
15146        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15147
15148        String[] innerArgs = new String[args.length-opti];
15149        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15150
15151        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15152        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15153        long nativePss = 0;
15154        long nativeSwapPss = 0;
15155        long dalvikPss = 0;
15156        long dalvikSwapPss = 0;
15157        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15158                EmptyArray.LONG;
15159        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15160                EmptyArray.LONG;
15161        long otherPss = 0;
15162        long otherSwapPss = 0;
15163        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15164        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15165
15166        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15167        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15168        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15169                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15170
15171        long totalPss = 0;
15172        long totalSwapPss = 0;
15173        long cachedPss = 0;
15174        long cachedSwapPss = 0;
15175        boolean hasSwapPss = false;
15176
15177        Debug.MemoryInfo mi = null;
15178        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15179            final ProcessRecord r = procs.get(i);
15180            final IApplicationThread thread;
15181            final int pid;
15182            final int oomAdj;
15183            final boolean hasActivities;
15184            synchronized (this) {
15185                thread = r.thread;
15186                pid = r.pid;
15187                oomAdj = r.getSetAdjWithServices();
15188                hasActivities = r.activities.size() > 0;
15189            }
15190            if (thread != null) {
15191                if (!isCheckinRequest && dumpDetails) {
15192                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15193                }
15194                if (mi == null) {
15195                    mi = new Debug.MemoryInfo();
15196                }
15197                if (dumpDetails || (!brief && !oomOnly)) {
15198                    Debug.getMemoryInfo(pid, mi);
15199                    hasSwapPss = mi.hasSwappedOutPss;
15200                } else {
15201                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15202                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15203                }
15204                if (dumpDetails) {
15205                    if (localOnly) {
15206                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15207                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15208                        if (isCheckinRequest) {
15209                            pw.println();
15210                        }
15211                    } else {
15212                        try {
15213                            pw.flush();
15214                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15215                                    dumpDalvik, dumpSummaryOnly, innerArgs);
15216                        } catch (RemoteException e) {
15217                            if (!isCheckinRequest) {
15218                                pw.println("Got RemoteException!");
15219                                pw.flush();
15220                            }
15221                        }
15222                    }
15223                }
15224
15225                final long myTotalPss = mi.getTotalPss();
15226                final long myTotalUss = mi.getTotalUss();
15227                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15228
15229                synchronized (this) {
15230                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15231                        // Record this for posterity if the process has been stable.
15232                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15233                    }
15234                }
15235
15236                if (!isCheckinRequest && mi != null) {
15237                    totalPss += myTotalPss;
15238                    totalSwapPss += myTotalSwapPss;
15239                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15240                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15241                            myTotalSwapPss, pid, hasActivities);
15242                    procMems.add(pssItem);
15243                    procMemsMap.put(pid, pssItem);
15244
15245                    nativePss += mi.nativePss;
15246                    nativeSwapPss += mi.nativeSwappedOutPss;
15247                    dalvikPss += mi.dalvikPss;
15248                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15249                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15250                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15251                        dalvikSubitemSwapPss[j] +=
15252                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15253                    }
15254                    otherPss += mi.otherPss;
15255                    otherSwapPss += mi.otherSwappedOutPss;
15256                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15257                        long mem = mi.getOtherPss(j);
15258                        miscPss[j] += mem;
15259                        otherPss -= mem;
15260                        mem = mi.getOtherSwappedOutPss(j);
15261                        miscSwapPss[j] += mem;
15262                        otherSwapPss -= mem;
15263                    }
15264
15265                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15266                        cachedPss += myTotalPss;
15267                        cachedSwapPss += myTotalSwapPss;
15268                    }
15269
15270                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15271                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15272                                || oomIndex == (oomPss.length-1)) {
15273                            oomPss[oomIndex] += myTotalPss;
15274                            oomSwapPss[oomIndex] += myTotalSwapPss;
15275                            if (oomProcs[oomIndex] == null) {
15276                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15277                            }
15278                            oomProcs[oomIndex].add(pssItem);
15279                            break;
15280                        }
15281                    }
15282                }
15283            }
15284        }
15285
15286        long nativeProcTotalPss = 0;
15287
15288        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15289            // If we are showing aggregations, also look for native processes to
15290            // include so that our aggregations are more accurate.
15291            updateCpuStatsNow();
15292            mi = null;
15293            synchronized (mProcessCpuTracker) {
15294                final int N = mProcessCpuTracker.countStats();
15295                for (int i=0; i<N; i++) {
15296                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15297                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15298                        if (mi == null) {
15299                            mi = new Debug.MemoryInfo();
15300                        }
15301                        if (!brief && !oomOnly) {
15302                            Debug.getMemoryInfo(st.pid, mi);
15303                        } else {
15304                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15305                            mi.nativePrivateDirty = (int)tmpLong[0];
15306                        }
15307
15308                        final long myTotalPss = mi.getTotalPss();
15309                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15310                        totalPss += myTotalPss;
15311                        nativeProcTotalPss += myTotalPss;
15312
15313                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15314                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15315                        procMems.add(pssItem);
15316
15317                        nativePss += mi.nativePss;
15318                        nativeSwapPss += mi.nativeSwappedOutPss;
15319                        dalvikPss += mi.dalvikPss;
15320                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15321                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15322                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15323                            dalvikSubitemSwapPss[j] +=
15324                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15325                        }
15326                        otherPss += mi.otherPss;
15327                        otherSwapPss += mi.otherSwappedOutPss;
15328                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15329                            long mem = mi.getOtherPss(j);
15330                            miscPss[j] += mem;
15331                            otherPss -= mem;
15332                            mem = mi.getOtherSwappedOutPss(j);
15333                            miscSwapPss[j] += mem;
15334                            otherSwapPss -= mem;
15335                        }
15336                        oomPss[0] += myTotalPss;
15337                        oomSwapPss[0] += myTotalSwapPss;
15338                        if (oomProcs[0] == null) {
15339                            oomProcs[0] = new ArrayList<MemItem>();
15340                        }
15341                        oomProcs[0].add(pssItem);
15342                    }
15343                }
15344            }
15345
15346            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15347
15348            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15349            final MemItem dalvikItem =
15350                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15351            if (dalvikSubitemPss.length > 0) {
15352                dalvikItem.subitems = new ArrayList<MemItem>();
15353                for (int j=0; j<dalvikSubitemPss.length; j++) {
15354                    final String name = Debug.MemoryInfo.getOtherLabel(
15355                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15356                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15357                                    dalvikSubitemSwapPss[j], j));
15358                }
15359            }
15360            catMems.add(dalvikItem);
15361            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15362            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15363                String label = Debug.MemoryInfo.getOtherLabel(j);
15364                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15365            }
15366
15367            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15368            for (int j=0; j<oomPss.length; j++) {
15369                if (oomPss[j] != 0) {
15370                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15371                            : DUMP_MEM_OOM_LABEL[j];
15372                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15373                            DUMP_MEM_OOM_ADJ[j]);
15374                    item.subitems = oomProcs[j];
15375                    oomMems.add(item);
15376                }
15377            }
15378
15379            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15380            if (!brief && !oomOnly && !isCompact) {
15381                pw.println();
15382                pw.println("Total PSS by process:");
15383                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15384                pw.println();
15385            }
15386            if (!isCompact) {
15387                pw.println("Total PSS by OOM adjustment:");
15388            }
15389            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15390            if (!brief && !oomOnly) {
15391                PrintWriter out = categoryPw != null ? categoryPw : pw;
15392                if (!isCompact) {
15393                    out.println();
15394                    out.println("Total PSS by category:");
15395                }
15396                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15397            }
15398            if (!isCompact) {
15399                pw.println();
15400            }
15401            MemInfoReader memInfo = new MemInfoReader();
15402            memInfo.readMemInfo();
15403            if (nativeProcTotalPss > 0) {
15404                synchronized (this) {
15405                    final long cachedKb = memInfo.getCachedSizeKb();
15406                    final long freeKb = memInfo.getFreeSizeKb();
15407                    final long zramKb = memInfo.getZramTotalSizeKb();
15408                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15409                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15410                            kernelKb*1024, nativeProcTotalPss*1024);
15411                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15412                            nativeProcTotalPss);
15413                }
15414            }
15415            if (!brief) {
15416                if (!isCompact) {
15417                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15418                    pw.print(" (status ");
15419                    switch (mLastMemoryLevel) {
15420                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15421                            pw.println("normal)");
15422                            break;
15423                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15424                            pw.println("moderate)");
15425                            break;
15426                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15427                            pw.println("low)");
15428                            break;
15429                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15430                            pw.println("critical)");
15431                            break;
15432                        default:
15433                            pw.print(mLastMemoryLevel);
15434                            pw.println(")");
15435                            break;
15436                    }
15437                    pw.print(" Free RAM: ");
15438                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15439                            + memInfo.getFreeSizeKb()));
15440                    pw.print(" (");
15441                    pw.print(stringifyKBSize(cachedPss));
15442                    pw.print(" cached pss + ");
15443                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15444                    pw.print(" cached kernel + ");
15445                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15446                    pw.println(" free)");
15447                } else {
15448                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15449                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15450                            + memInfo.getFreeSizeKb()); pw.print(",");
15451                    pw.println(totalPss - cachedPss);
15452                }
15453            }
15454            long lostRAM = memInfo.getTotalSizeKb()
15455                    - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15456                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15457            if (!isCompact) {
15458                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15459                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15460                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15461                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15462                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15463            } else {
15464                pw.print("lostram,"); pw.println(lostRAM);
15465            }
15466            if (!brief) {
15467                if (memInfo.getZramTotalSizeKb() != 0) {
15468                    if (!isCompact) {
15469                        pw.print("     ZRAM: ");
15470                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15471                                pw.print(" physical used for ");
15472                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15473                                        - memInfo.getSwapFreeSizeKb()));
15474                                pw.print(" in swap (");
15475                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15476                                pw.println(" total swap)");
15477                    } else {
15478                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15479                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15480                                pw.println(memInfo.getSwapFreeSizeKb());
15481                    }
15482                }
15483                final long[] ksm = getKsmInfo();
15484                if (!isCompact) {
15485                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15486                            || ksm[KSM_VOLATILE] != 0) {
15487                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15488                                pw.print(" saved from shared ");
15489                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15490                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15491                                pw.print(" unshared; ");
15492                                pw.print(stringifyKBSize(
15493                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15494                    }
15495                    pw.print("   Tuning: ");
15496                    pw.print(ActivityManager.staticGetMemoryClass());
15497                    pw.print(" (large ");
15498                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15499                    pw.print("), oom ");
15500                    pw.print(stringifySize(
15501                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15502                    pw.print(", restore limit ");
15503                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15504                    if (ActivityManager.isLowRamDeviceStatic()) {
15505                        pw.print(" (low-ram)");
15506                    }
15507                    if (ActivityManager.isHighEndGfx()) {
15508                        pw.print(" (high-end-gfx)");
15509                    }
15510                    pw.println();
15511                } else {
15512                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15513                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15514                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15515                    pw.print("tuning,");
15516                    pw.print(ActivityManager.staticGetMemoryClass());
15517                    pw.print(',');
15518                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15519                    pw.print(',');
15520                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15521                    if (ActivityManager.isLowRamDeviceStatic()) {
15522                        pw.print(",low-ram");
15523                    }
15524                    if (ActivityManager.isHighEndGfx()) {
15525                        pw.print(",high-end-gfx");
15526                    }
15527                    pw.println();
15528                }
15529            }
15530        }
15531    }
15532
15533    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15534            long memtrack, String name) {
15535        sb.append("  ");
15536        sb.append(ProcessList.makeOomAdjString(oomAdj));
15537        sb.append(' ');
15538        sb.append(ProcessList.makeProcStateString(procState));
15539        sb.append(' ');
15540        ProcessList.appendRamKb(sb, pss);
15541        sb.append(": ");
15542        sb.append(name);
15543        if (memtrack > 0) {
15544            sb.append(" (");
15545            sb.append(stringifyKBSize(memtrack));
15546            sb.append(" memtrack)");
15547        }
15548    }
15549
15550    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15551        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15552        sb.append(" (pid ");
15553        sb.append(mi.pid);
15554        sb.append(") ");
15555        sb.append(mi.adjType);
15556        sb.append('\n');
15557        if (mi.adjReason != null) {
15558            sb.append("                      ");
15559            sb.append(mi.adjReason);
15560            sb.append('\n');
15561        }
15562    }
15563
15564    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15565        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15566        for (int i=0, N=memInfos.size(); i<N; i++) {
15567            ProcessMemInfo mi = memInfos.get(i);
15568            infoMap.put(mi.pid, mi);
15569        }
15570        updateCpuStatsNow();
15571        long[] memtrackTmp = new long[1];
15572        synchronized (mProcessCpuTracker) {
15573            final int N = mProcessCpuTracker.countStats();
15574            for (int i=0; i<N; i++) {
15575                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15576                if (st.vsize > 0) {
15577                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15578                    if (pss > 0) {
15579                        if (infoMap.indexOfKey(st.pid) < 0) {
15580                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15581                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15582                            mi.pss = pss;
15583                            mi.memtrack = memtrackTmp[0];
15584                            memInfos.add(mi);
15585                        }
15586                    }
15587                }
15588            }
15589        }
15590
15591        long totalPss = 0;
15592        long totalMemtrack = 0;
15593        for (int i=0, N=memInfos.size(); i<N; i++) {
15594            ProcessMemInfo mi = memInfos.get(i);
15595            if (mi.pss == 0) {
15596                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15597                mi.memtrack = memtrackTmp[0];
15598            }
15599            totalPss += mi.pss;
15600            totalMemtrack += mi.memtrack;
15601        }
15602        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15603            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15604                if (lhs.oomAdj != rhs.oomAdj) {
15605                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15606                }
15607                if (lhs.pss != rhs.pss) {
15608                    return lhs.pss < rhs.pss ? 1 : -1;
15609                }
15610                return 0;
15611            }
15612        });
15613
15614        StringBuilder tag = new StringBuilder(128);
15615        StringBuilder stack = new StringBuilder(128);
15616        tag.append("Low on memory -- ");
15617        appendMemBucket(tag, totalPss, "total", false);
15618        appendMemBucket(stack, totalPss, "total", true);
15619
15620        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15621        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15622        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15623
15624        boolean firstLine = true;
15625        int lastOomAdj = Integer.MIN_VALUE;
15626        long extraNativeRam = 0;
15627        long extraNativeMemtrack = 0;
15628        long cachedPss = 0;
15629        for (int i=0, N=memInfos.size(); i<N; i++) {
15630            ProcessMemInfo mi = memInfos.get(i);
15631
15632            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15633                cachedPss += mi.pss;
15634            }
15635
15636            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15637                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15638                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15639                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15640                if (lastOomAdj != mi.oomAdj) {
15641                    lastOomAdj = mi.oomAdj;
15642                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15643                        tag.append(" / ");
15644                    }
15645                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15646                        if (firstLine) {
15647                            stack.append(":");
15648                            firstLine = false;
15649                        }
15650                        stack.append("\n\t at ");
15651                    } else {
15652                        stack.append("$");
15653                    }
15654                } else {
15655                    tag.append(" ");
15656                    stack.append("$");
15657                }
15658                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15659                    appendMemBucket(tag, mi.pss, mi.name, false);
15660                }
15661                appendMemBucket(stack, mi.pss, mi.name, true);
15662                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15663                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15664                    stack.append("(");
15665                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15666                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15667                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15668                            stack.append(":");
15669                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15670                        }
15671                    }
15672                    stack.append(")");
15673                }
15674            }
15675
15676            appendMemInfo(fullNativeBuilder, mi);
15677            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15678                // The short form only has native processes that are >= 512K.
15679                if (mi.pss >= 512) {
15680                    appendMemInfo(shortNativeBuilder, mi);
15681                } else {
15682                    extraNativeRam += mi.pss;
15683                    extraNativeMemtrack += mi.memtrack;
15684                }
15685            } else {
15686                // Short form has all other details, but if we have collected RAM
15687                // from smaller native processes let's dump a summary of that.
15688                if (extraNativeRam > 0) {
15689                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15690                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15691                    shortNativeBuilder.append('\n');
15692                    extraNativeRam = 0;
15693                }
15694                appendMemInfo(fullJavaBuilder, mi);
15695            }
15696        }
15697
15698        fullJavaBuilder.append("           ");
15699        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15700        fullJavaBuilder.append(": TOTAL");
15701        if (totalMemtrack > 0) {
15702            fullJavaBuilder.append(" (");
15703            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15704            fullJavaBuilder.append(" memtrack)");
15705        } else {
15706        }
15707        fullJavaBuilder.append("\n");
15708
15709        MemInfoReader memInfo = new MemInfoReader();
15710        memInfo.readMemInfo();
15711        final long[] infos = memInfo.getRawInfo();
15712
15713        StringBuilder memInfoBuilder = new StringBuilder(1024);
15714        Debug.getMemInfo(infos);
15715        memInfoBuilder.append("  MemInfo: ");
15716        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15717        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15718        memInfoBuilder.append(stringifyKBSize(
15719                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15720        memInfoBuilder.append(stringifyKBSize(
15721                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15722        memInfoBuilder.append(stringifyKBSize(
15723                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15724        memInfoBuilder.append("           ");
15725        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15726        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15727        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15728        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15729        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15730            memInfoBuilder.append("  ZRAM: ");
15731            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15732            memInfoBuilder.append(" RAM, ");
15733            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15734            memInfoBuilder.append(" swap total, ");
15735            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15736            memInfoBuilder.append(" swap free\n");
15737        }
15738        final long[] ksm = getKsmInfo();
15739        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15740                || ksm[KSM_VOLATILE] != 0) {
15741            memInfoBuilder.append("  KSM: ");
15742            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15743            memInfoBuilder.append(" saved from shared ");
15744            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15745            memInfoBuilder.append("\n       ");
15746            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15747            memInfoBuilder.append(" unshared; ");
15748            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15749            memInfoBuilder.append(" volatile\n");
15750        }
15751        memInfoBuilder.append("  Free RAM: ");
15752        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15753                + memInfo.getFreeSizeKb()));
15754        memInfoBuilder.append("\n");
15755        memInfoBuilder.append("  Used RAM: ");
15756        memInfoBuilder.append(stringifyKBSize(
15757                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15758        memInfoBuilder.append("\n");
15759        memInfoBuilder.append("  Lost RAM: ");
15760        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15761                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15762                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
15763        memInfoBuilder.append("\n");
15764        Slog.i(TAG, "Low on memory:");
15765        Slog.i(TAG, shortNativeBuilder.toString());
15766        Slog.i(TAG, fullJavaBuilder.toString());
15767        Slog.i(TAG, memInfoBuilder.toString());
15768
15769        StringBuilder dropBuilder = new StringBuilder(1024);
15770        /*
15771        StringWriter oomSw = new StringWriter();
15772        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15773        StringWriter catSw = new StringWriter();
15774        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15775        String[] emptyArgs = new String[] { };
15776        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
15777        oomPw.flush();
15778        String oomString = oomSw.toString();
15779        */
15780        dropBuilder.append("Low on memory:");
15781        dropBuilder.append(stack);
15782        dropBuilder.append('\n');
15783        dropBuilder.append(fullNativeBuilder);
15784        dropBuilder.append(fullJavaBuilder);
15785        dropBuilder.append('\n');
15786        dropBuilder.append(memInfoBuilder);
15787        dropBuilder.append('\n');
15788        /*
15789        dropBuilder.append(oomString);
15790        dropBuilder.append('\n');
15791        */
15792        StringWriter catSw = new StringWriter();
15793        synchronized (ActivityManagerService.this) {
15794            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15795            String[] emptyArgs = new String[] { };
15796            catPw.println();
15797            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15798            catPw.println();
15799            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15800                    false, false, null);
15801            catPw.println();
15802            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15803            catPw.flush();
15804        }
15805        dropBuilder.append(catSw.toString());
15806        addErrorToDropBox("lowmem", null, "system_server", null,
15807                null, tag.toString(), dropBuilder.toString(), null, null);
15808        //Slog.i(TAG, "Sent to dropbox:");
15809        //Slog.i(TAG, dropBuilder.toString());
15810        synchronized (ActivityManagerService.this) {
15811            long now = SystemClock.uptimeMillis();
15812            if (mLastMemUsageReportTime < now) {
15813                mLastMemUsageReportTime = now;
15814            }
15815        }
15816    }
15817
15818    /**
15819     * Searches array of arguments for the specified string
15820     * @param args array of argument strings
15821     * @param value value to search for
15822     * @return true if the value is contained in the array
15823     */
15824    private static boolean scanArgs(String[] args, String value) {
15825        if (args != null) {
15826            for (String arg : args) {
15827                if (value.equals(arg)) {
15828                    return true;
15829                }
15830            }
15831        }
15832        return false;
15833    }
15834
15835    private final boolean removeDyingProviderLocked(ProcessRecord proc,
15836            ContentProviderRecord cpr, boolean always) {
15837        final boolean inLaunching = mLaunchingProviders.contains(cpr);
15838
15839        if (!inLaunching || always) {
15840            synchronized (cpr) {
15841                cpr.launchingApp = null;
15842                cpr.notifyAll();
15843            }
15844            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15845            String names[] = cpr.info.authority.split(";");
15846            for (int j = 0; j < names.length; j++) {
15847                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15848            }
15849        }
15850
15851        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15852            ContentProviderConnection conn = cpr.connections.get(i);
15853            if (conn.waiting) {
15854                // If this connection is waiting for the provider, then we don't
15855                // need to mess with its process unless we are always removing
15856                // or for some reason the provider is not currently launching.
15857                if (inLaunching && !always) {
15858                    continue;
15859                }
15860            }
15861            ProcessRecord capp = conn.client;
15862            conn.dead = true;
15863            if (conn.stableCount > 0) {
15864                if (!capp.persistent && capp.thread != null
15865                        && capp.pid != 0
15866                        && capp.pid != MY_PID) {
15867                    capp.kill("depends on provider "
15868                            + cpr.name.flattenToShortString()
15869                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15870                }
15871            } else if (capp.thread != null && conn.provider.provider != null) {
15872                try {
15873                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15874                } catch (RemoteException e) {
15875                }
15876                // In the protocol here, we don't expect the client to correctly
15877                // clean up this connection, we'll just remove it.
15878                cpr.connections.remove(i);
15879                if (conn.client.conProviders.remove(conn)) {
15880                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15881                }
15882            }
15883        }
15884
15885        if (inLaunching && always) {
15886            mLaunchingProviders.remove(cpr);
15887        }
15888        return inLaunching;
15889    }
15890
15891    /**
15892     * Main code for cleaning up a process when it has gone away.  This is
15893     * called both as a result of the process dying, or directly when stopping
15894     * a process when running in single process mode.
15895     *
15896     * @return Returns true if the given process has been restarted, so the
15897     * app that was passed in must remain on the process lists.
15898     */
15899    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15900            boolean restarting, boolean allowRestart, int index) {
15901        if (index >= 0) {
15902            removeLruProcessLocked(app);
15903            ProcessList.remove(app.pid);
15904        }
15905
15906        mProcessesToGc.remove(app);
15907        mPendingPssProcesses.remove(app);
15908
15909        // Dismiss any open dialogs.
15910        if (app.crashDialog != null && !app.forceCrashReport) {
15911            app.crashDialog.dismiss();
15912            app.crashDialog = null;
15913        }
15914        if (app.anrDialog != null) {
15915            app.anrDialog.dismiss();
15916            app.anrDialog = null;
15917        }
15918        if (app.waitDialog != null) {
15919            app.waitDialog.dismiss();
15920            app.waitDialog = null;
15921        }
15922
15923        app.crashing = false;
15924        app.notResponding = false;
15925
15926        app.resetPackageList(mProcessStats);
15927        app.unlinkDeathRecipient();
15928        app.makeInactive(mProcessStats);
15929        app.waitingToKill = null;
15930        app.forcingToForeground = null;
15931        updateProcessForegroundLocked(app, false, false);
15932        app.foregroundActivities = false;
15933        app.hasShownUi = false;
15934        app.treatLikeActivity = false;
15935        app.hasAboveClient = false;
15936        app.hasClientActivities = false;
15937
15938        mServices.killServicesLocked(app, allowRestart);
15939
15940        boolean restart = false;
15941
15942        // Remove published content providers.
15943        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15944            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15945            final boolean always = app.bad || !allowRestart;
15946            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15947            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15948                // We left the provider in the launching list, need to
15949                // restart it.
15950                restart = true;
15951            }
15952
15953            cpr.provider = null;
15954            cpr.proc = null;
15955        }
15956        app.pubProviders.clear();
15957
15958        // Take care of any launching providers waiting for this process.
15959        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
15960            restart = true;
15961        }
15962
15963        // Unregister from connected content providers.
15964        if (!app.conProviders.isEmpty()) {
15965            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15966                ContentProviderConnection conn = app.conProviders.get(i);
15967                conn.provider.connections.remove(conn);
15968                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15969                        conn.provider.name);
15970            }
15971            app.conProviders.clear();
15972        }
15973
15974        // At this point there may be remaining entries in mLaunchingProviders
15975        // where we were the only one waiting, so they are no longer of use.
15976        // Look for these and clean up if found.
15977        // XXX Commented out for now.  Trying to figure out a way to reproduce
15978        // the actual situation to identify what is actually going on.
15979        if (false) {
15980            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15981                ContentProviderRecord cpr = mLaunchingProviders.get(i);
15982                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15983                    synchronized (cpr) {
15984                        cpr.launchingApp = null;
15985                        cpr.notifyAll();
15986                    }
15987                }
15988            }
15989        }
15990
15991        skipCurrentReceiverLocked(app);
15992
15993        // Unregister any receivers.
15994        for (int i = app.receivers.size() - 1; i >= 0; i--) {
15995            removeReceiverLocked(app.receivers.valueAt(i));
15996        }
15997        app.receivers.clear();
15998
15999        // If the app is undergoing backup, tell the backup manager about it
16000        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16001            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16002                    + mBackupTarget.appInfo + " died during backup");
16003            try {
16004                IBackupManager bm = IBackupManager.Stub.asInterface(
16005                        ServiceManager.getService(Context.BACKUP_SERVICE));
16006                bm.agentDisconnected(app.info.packageName);
16007            } catch (RemoteException e) {
16008                // can't happen; backup manager is local
16009            }
16010        }
16011
16012        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16013            ProcessChangeItem item = mPendingProcessChanges.get(i);
16014            if (item.pid == app.pid) {
16015                mPendingProcessChanges.remove(i);
16016                mAvailProcessChanges.add(item);
16017            }
16018        }
16019        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16020                null).sendToTarget();
16021
16022        // If the caller is restarting this app, then leave it in its
16023        // current lists and let the caller take care of it.
16024        if (restarting) {
16025            return false;
16026        }
16027
16028        if (!app.persistent || app.isolated) {
16029            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16030                    "Removing non-persistent process during cleanup: " + app);
16031            removeProcessNameLocked(app.processName, app.uid);
16032            if (mHeavyWeightProcess == app) {
16033                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16034                        mHeavyWeightProcess.userId, 0));
16035                mHeavyWeightProcess = null;
16036            }
16037        } else if (!app.removed) {
16038            // This app is persistent, so we need to keep its record around.
16039            // If it is not already on the pending app list, add it there
16040            // and start a new process for it.
16041            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16042                mPersistentStartingProcesses.add(app);
16043                restart = true;
16044            }
16045        }
16046        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16047                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16048        mProcessesOnHold.remove(app);
16049
16050        if (app == mHomeProcess) {
16051            mHomeProcess = null;
16052        }
16053        if (app == mPreviousProcess) {
16054            mPreviousProcess = null;
16055        }
16056
16057        if (restart && !app.isolated) {
16058            // We have components that still need to be running in the
16059            // process, so re-launch it.
16060            if (index < 0) {
16061                ProcessList.remove(app.pid);
16062            }
16063            addProcessNameLocked(app);
16064            startProcessLocked(app, "restart", app.processName);
16065            return true;
16066        } else if (app.pid > 0 && app.pid != MY_PID) {
16067            // Goodbye!
16068            boolean removed;
16069            synchronized (mPidsSelfLocked) {
16070                mPidsSelfLocked.remove(app.pid);
16071                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16072            }
16073            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16074            if (app.isolated) {
16075                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16076            }
16077            app.setPid(0);
16078        }
16079        return false;
16080    }
16081
16082    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16083        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16084            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16085            if (cpr.launchingApp == app) {
16086                return true;
16087            }
16088        }
16089        return false;
16090    }
16091
16092    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16093        // Look through the content providers we are waiting to have launched,
16094        // and if any run in this process then either schedule a restart of
16095        // the process or kill the client waiting for it if this process has
16096        // gone bad.
16097        boolean restart = false;
16098        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16099            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16100            if (cpr.launchingApp == app) {
16101                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16102                    restart = true;
16103                } else {
16104                    removeDyingProviderLocked(app, cpr, true);
16105                }
16106            }
16107        }
16108        return restart;
16109    }
16110
16111    // =========================================================
16112    // SERVICES
16113    // =========================================================
16114
16115    @Override
16116    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16117            int flags) {
16118        enforceNotIsolatedCaller("getServices");
16119        synchronized (this) {
16120            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16121        }
16122    }
16123
16124    @Override
16125    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16126        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16127        synchronized (this) {
16128            return mServices.getRunningServiceControlPanelLocked(name);
16129        }
16130    }
16131
16132    @Override
16133    public ComponentName startService(IApplicationThread caller, Intent service,
16134            String resolvedType, String callingPackage, int userId)
16135            throws TransactionTooLargeException {
16136        enforceNotIsolatedCaller("startService");
16137        // Refuse possible leaked file descriptors
16138        if (service != null && service.hasFileDescriptors() == true) {
16139            throw new IllegalArgumentException("File descriptors passed in Intent");
16140        }
16141
16142        if (callingPackage == null) {
16143            throw new IllegalArgumentException("callingPackage cannot be null");
16144        }
16145
16146        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16147                "startService: " + service + " type=" + resolvedType);
16148        synchronized(this) {
16149            final int callingPid = Binder.getCallingPid();
16150            final int callingUid = Binder.getCallingUid();
16151            final long origId = Binder.clearCallingIdentity();
16152            ComponentName res = mServices.startServiceLocked(caller, service,
16153                    resolvedType, callingPid, callingUid, callingPackage, userId);
16154            Binder.restoreCallingIdentity(origId);
16155            return res;
16156        }
16157    }
16158
16159    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16160            String callingPackage, int userId)
16161            throws TransactionTooLargeException {
16162        synchronized(this) {
16163            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16164                    "startServiceInPackage: " + service + " type=" + resolvedType);
16165            final long origId = Binder.clearCallingIdentity();
16166            ComponentName res = mServices.startServiceLocked(null, service,
16167                    resolvedType, -1, uid, callingPackage, userId);
16168            Binder.restoreCallingIdentity(origId);
16169            return res;
16170        }
16171    }
16172
16173    @Override
16174    public int stopService(IApplicationThread caller, Intent service,
16175            String resolvedType, int userId) {
16176        enforceNotIsolatedCaller("stopService");
16177        // Refuse possible leaked file descriptors
16178        if (service != null && service.hasFileDescriptors() == true) {
16179            throw new IllegalArgumentException("File descriptors passed in Intent");
16180        }
16181
16182        synchronized(this) {
16183            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16184        }
16185    }
16186
16187    @Override
16188    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16189        enforceNotIsolatedCaller("peekService");
16190        // Refuse possible leaked file descriptors
16191        if (service != null && service.hasFileDescriptors() == true) {
16192            throw new IllegalArgumentException("File descriptors passed in Intent");
16193        }
16194
16195        if (callingPackage == null) {
16196            throw new IllegalArgumentException("callingPackage cannot be null");
16197        }
16198
16199        synchronized(this) {
16200            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16201        }
16202    }
16203
16204    @Override
16205    public boolean stopServiceToken(ComponentName className, IBinder token,
16206            int startId) {
16207        synchronized(this) {
16208            return mServices.stopServiceTokenLocked(className, token, startId);
16209        }
16210    }
16211
16212    @Override
16213    public void setServiceForeground(ComponentName className, IBinder token,
16214            int id, Notification notification, boolean removeNotification) {
16215        synchronized(this) {
16216            mServices.setServiceForegroundLocked(className, token, id, notification,
16217                    removeNotification);
16218        }
16219    }
16220
16221    @Override
16222    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16223            boolean requireFull, String name, String callerPackage) {
16224        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16225                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16226    }
16227
16228    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16229            String className, int flags) {
16230        boolean result = false;
16231        // For apps that don't have pre-defined UIDs, check for permission
16232        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16233            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16234                if (ActivityManager.checkUidPermission(
16235                        INTERACT_ACROSS_USERS,
16236                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16237                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16238                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16239                            + " requests FLAG_SINGLE_USER, but app does not hold "
16240                            + INTERACT_ACROSS_USERS;
16241                    Slog.w(TAG, msg);
16242                    throw new SecurityException(msg);
16243                }
16244                // Permission passed
16245                result = true;
16246            }
16247        } else if ("system".equals(componentProcessName)) {
16248            result = true;
16249        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16250            // Phone app and persistent apps are allowed to export singleuser providers.
16251            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16252                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16253        }
16254        if (DEBUG_MU) Slog.v(TAG_MU,
16255                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16256                + Integer.toHexString(flags) + ") = " + result);
16257        return result;
16258    }
16259
16260    /**
16261     * Checks to see if the caller is in the same app as the singleton
16262     * component, or the component is in a special app. It allows special apps
16263     * to export singleton components but prevents exporting singleton
16264     * components for regular apps.
16265     */
16266    boolean isValidSingletonCall(int callingUid, int componentUid) {
16267        int componentAppId = UserHandle.getAppId(componentUid);
16268        return UserHandle.isSameApp(callingUid, componentUid)
16269                || componentAppId == Process.SYSTEM_UID
16270                || componentAppId == Process.PHONE_UID
16271                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16272                        == PackageManager.PERMISSION_GRANTED;
16273    }
16274
16275    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16276            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16277            int userId) throws TransactionTooLargeException {
16278        enforceNotIsolatedCaller("bindService");
16279
16280        // Refuse possible leaked file descriptors
16281        if (service != null && service.hasFileDescriptors() == true) {
16282            throw new IllegalArgumentException("File descriptors passed in Intent");
16283        }
16284
16285        if (callingPackage == null) {
16286            throw new IllegalArgumentException("callingPackage cannot be null");
16287        }
16288
16289        synchronized(this) {
16290            return mServices.bindServiceLocked(caller, token, service,
16291                    resolvedType, connection, flags, callingPackage, userId);
16292        }
16293    }
16294
16295    public boolean unbindService(IServiceConnection connection) {
16296        synchronized (this) {
16297            return mServices.unbindServiceLocked(connection);
16298        }
16299    }
16300
16301    public void publishService(IBinder token, Intent intent, IBinder service) {
16302        // Refuse possible leaked file descriptors
16303        if (intent != null && intent.hasFileDescriptors() == true) {
16304            throw new IllegalArgumentException("File descriptors passed in Intent");
16305        }
16306
16307        synchronized(this) {
16308            if (!(token instanceof ServiceRecord)) {
16309                throw new IllegalArgumentException("Invalid service token");
16310            }
16311            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16312        }
16313    }
16314
16315    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16316        // Refuse possible leaked file descriptors
16317        if (intent != null && intent.hasFileDescriptors() == true) {
16318            throw new IllegalArgumentException("File descriptors passed in Intent");
16319        }
16320
16321        synchronized(this) {
16322            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16323        }
16324    }
16325
16326    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16327        synchronized(this) {
16328            if (!(token instanceof ServiceRecord)) {
16329                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16330                throw new IllegalArgumentException("Invalid service token");
16331            }
16332            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16333        }
16334    }
16335
16336    // =========================================================
16337    // BACKUP AND RESTORE
16338    // =========================================================
16339
16340    // Cause the target app to be launched if necessary and its backup agent
16341    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16342    // activity manager to announce its creation.
16343    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16344        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16345                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16346        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16347
16348        synchronized(this) {
16349            // !!! TODO: currently no check here that we're already bound
16350            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16351            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16352            synchronized (stats) {
16353                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16354            }
16355
16356            // Backup agent is now in use, its package can't be stopped.
16357            try {
16358                AppGlobals.getPackageManager().setPackageStoppedState(
16359                        app.packageName, false, UserHandle.getUserId(app.uid));
16360            } catch (RemoteException e) {
16361            } catch (IllegalArgumentException e) {
16362                Slog.w(TAG, "Failed trying to unstop package "
16363                        + app.packageName + ": " + e);
16364            }
16365
16366            BackupRecord r = new BackupRecord(ss, app, backupMode);
16367            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16368                    ? new ComponentName(app.packageName, app.backupAgentName)
16369                    : new ComponentName("android", "FullBackupAgent");
16370            // startProcessLocked() returns existing proc's record if it's already running
16371            ProcessRecord proc = startProcessLocked(app.processName, app,
16372                    false, 0, "backup", hostingName, false, false, false);
16373            if (proc == null) {
16374                Slog.e(TAG, "Unable to start backup agent process " + r);
16375                return false;
16376            }
16377
16378            r.app = proc;
16379            mBackupTarget = r;
16380            mBackupAppName = app.packageName;
16381
16382            // Try not to kill the process during backup
16383            updateOomAdjLocked(proc);
16384
16385            // If the process is already attached, schedule the creation of the backup agent now.
16386            // If it is not yet live, this will be done when it attaches to the framework.
16387            if (proc.thread != null) {
16388                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16389                try {
16390                    proc.thread.scheduleCreateBackupAgent(app,
16391                            compatibilityInfoForPackageLocked(app), backupMode);
16392                } catch (RemoteException e) {
16393                    // Will time out on the backup manager side
16394                }
16395            } else {
16396                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16397            }
16398            // Invariants: at this point, the target app process exists and the application
16399            // is either already running or in the process of coming up.  mBackupTarget and
16400            // mBackupAppName describe the app, so that when it binds back to the AM we
16401            // know that it's scheduled for a backup-agent operation.
16402        }
16403
16404        return true;
16405    }
16406
16407    @Override
16408    public void clearPendingBackup() {
16409        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16410        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16411
16412        synchronized (this) {
16413            mBackupTarget = null;
16414            mBackupAppName = null;
16415        }
16416    }
16417
16418    // A backup agent has just come up
16419    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16420        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16421                + " = " + agent);
16422
16423        synchronized(this) {
16424            if (!agentPackageName.equals(mBackupAppName)) {
16425                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16426                return;
16427            }
16428        }
16429
16430        long oldIdent = Binder.clearCallingIdentity();
16431        try {
16432            IBackupManager bm = IBackupManager.Stub.asInterface(
16433                    ServiceManager.getService(Context.BACKUP_SERVICE));
16434            bm.agentConnected(agentPackageName, agent);
16435        } catch (RemoteException e) {
16436            // can't happen; the backup manager service is local
16437        } catch (Exception e) {
16438            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16439            e.printStackTrace();
16440        } finally {
16441            Binder.restoreCallingIdentity(oldIdent);
16442        }
16443    }
16444
16445    // done with this agent
16446    public void unbindBackupAgent(ApplicationInfo appInfo) {
16447        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16448        if (appInfo == null) {
16449            Slog.w(TAG, "unbind backup agent for null app");
16450            return;
16451        }
16452
16453        synchronized(this) {
16454            try {
16455                if (mBackupAppName == null) {
16456                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16457                    return;
16458                }
16459
16460                if (!mBackupAppName.equals(appInfo.packageName)) {
16461                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16462                    return;
16463                }
16464
16465                // Not backing this app up any more; reset its OOM adjustment
16466                final ProcessRecord proc = mBackupTarget.app;
16467                updateOomAdjLocked(proc);
16468
16469                // If the app crashed during backup, 'thread' will be null here
16470                if (proc.thread != null) {
16471                    try {
16472                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16473                                compatibilityInfoForPackageLocked(appInfo));
16474                    } catch (Exception e) {
16475                        Slog.e(TAG, "Exception when unbinding backup agent:");
16476                        e.printStackTrace();
16477                    }
16478                }
16479            } finally {
16480                mBackupTarget = null;
16481                mBackupAppName = null;
16482            }
16483        }
16484    }
16485    // =========================================================
16486    // BROADCASTS
16487    // =========================================================
16488
16489    boolean isPendingBroadcastProcessLocked(int pid) {
16490        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16491                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16492    }
16493
16494    void skipPendingBroadcastLocked(int pid) {
16495            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16496            for (BroadcastQueue queue : mBroadcastQueues) {
16497                queue.skipPendingBroadcastLocked(pid);
16498            }
16499    }
16500
16501    // The app just attached; send any pending broadcasts that it should receive
16502    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16503        boolean didSomething = false;
16504        for (BroadcastQueue queue : mBroadcastQueues) {
16505            didSomething |= queue.sendPendingBroadcastsLocked(app);
16506        }
16507        return didSomething;
16508    }
16509
16510    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16511            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16512        enforceNotIsolatedCaller("registerReceiver");
16513        ArrayList<Intent> stickyIntents = null;
16514        ProcessRecord callerApp = null;
16515        int callingUid;
16516        int callingPid;
16517        synchronized(this) {
16518            if (caller != null) {
16519                callerApp = getRecordForAppLocked(caller);
16520                if (callerApp == null) {
16521                    throw new SecurityException(
16522                            "Unable to find app for caller " + caller
16523                            + " (pid=" + Binder.getCallingPid()
16524                            + ") when registering receiver " + receiver);
16525                }
16526                if (callerApp.info.uid != Process.SYSTEM_UID &&
16527                        !callerApp.pkgList.containsKey(callerPackage) &&
16528                        !"android".equals(callerPackage)) {
16529                    throw new SecurityException("Given caller package " + callerPackage
16530                            + " is not running in process " + callerApp);
16531                }
16532                callingUid = callerApp.info.uid;
16533                callingPid = callerApp.pid;
16534            } else {
16535                callerPackage = null;
16536                callingUid = Binder.getCallingUid();
16537                callingPid = Binder.getCallingPid();
16538            }
16539
16540            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16541                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16542
16543            Iterator<String> actions = filter.actionsIterator();
16544            if (actions == null) {
16545                ArrayList<String> noAction = new ArrayList<String>(1);
16546                noAction.add(null);
16547                actions = noAction.iterator();
16548            }
16549
16550            // Collect stickies of users
16551            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16552            while (actions.hasNext()) {
16553                String action = actions.next();
16554                for (int id : userIds) {
16555                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16556                    if (stickies != null) {
16557                        ArrayList<Intent> intents = stickies.get(action);
16558                        if (intents != null) {
16559                            if (stickyIntents == null) {
16560                                stickyIntents = new ArrayList<Intent>();
16561                            }
16562                            stickyIntents.addAll(intents);
16563                        }
16564                    }
16565                }
16566            }
16567        }
16568
16569        ArrayList<Intent> allSticky = null;
16570        if (stickyIntents != null) {
16571            final ContentResolver resolver = mContext.getContentResolver();
16572            // Look for any matching sticky broadcasts...
16573            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16574                Intent intent = stickyIntents.get(i);
16575                // If intent has scheme "content", it will need to acccess
16576                // provider that needs to lock mProviderMap in ActivityThread
16577                // and also it may need to wait application response, so we
16578                // cannot lock ActivityManagerService here.
16579                if (filter.match(resolver, intent, true, TAG) >= 0) {
16580                    if (allSticky == null) {
16581                        allSticky = new ArrayList<Intent>();
16582                    }
16583                    allSticky.add(intent);
16584                }
16585            }
16586        }
16587
16588        // The first sticky in the list is returned directly back to the client.
16589        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16590        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16591        if (receiver == null) {
16592            return sticky;
16593        }
16594
16595        synchronized (this) {
16596            if (callerApp != null && (callerApp.thread == null
16597                    || callerApp.thread.asBinder() != caller.asBinder())) {
16598                // Original caller already died
16599                return null;
16600            }
16601            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16602            if (rl == null) {
16603                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16604                        userId, receiver);
16605                if (rl.app != null) {
16606                    rl.app.receivers.add(rl);
16607                } else {
16608                    try {
16609                        receiver.asBinder().linkToDeath(rl, 0);
16610                    } catch (RemoteException e) {
16611                        return sticky;
16612                    }
16613                    rl.linkedToDeath = true;
16614                }
16615                mRegisteredReceivers.put(receiver.asBinder(), rl);
16616            } else if (rl.uid != callingUid) {
16617                throw new IllegalArgumentException(
16618                        "Receiver requested to register for uid " + callingUid
16619                        + " was previously registered for uid " + rl.uid);
16620            } else if (rl.pid != callingPid) {
16621                throw new IllegalArgumentException(
16622                        "Receiver requested to register for pid " + callingPid
16623                        + " was previously registered for pid " + rl.pid);
16624            } else if (rl.userId != userId) {
16625                throw new IllegalArgumentException(
16626                        "Receiver requested to register for user " + userId
16627                        + " was previously registered for user " + rl.userId);
16628            }
16629            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16630                    permission, callingUid, userId);
16631            rl.add(bf);
16632            if (!bf.debugCheck()) {
16633                Slog.w(TAG, "==> For Dynamic broadcast");
16634            }
16635            mReceiverResolver.addFilter(bf);
16636
16637            // Enqueue broadcasts for all existing stickies that match
16638            // this filter.
16639            if (allSticky != null) {
16640                ArrayList receivers = new ArrayList();
16641                receivers.add(bf);
16642
16643                final int stickyCount = allSticky.size();
16644                for (int i = 0; i < stickyCount; i++) {
16645                    Intent intent = allSticky.get(i);
16646                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16647                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16648                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16649                            null, 0, null, null, false, true, true, -1);
16650                    queue.enqueueParallelBroadcastLocked(r);
16651                    queue.scheduleBroadcastsLocked();
16652                }
16653            }
16654
16655            return sticky;
16656        }
16657    }
16658
16659    public void unregisterReceiver(IIntentReceiver receiver) {
16660        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16661
16662        final long origId = Binder.clearCallingIdentity();
16663        try {
16664            boolean doTrim = false;
16665
16666            synchronized(this) {
16667                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16668                if (rl != null) {
16669                    final BroadcastRecord r = rl.curBroadcast;
16670                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16671                        final boolean doNext = r.queue.finishReceiverLocked(
16672                                r, r.resultCode, r.resultData, r.resultExtras,
16673                                r.resultAbort, false);
16674                        if (doNext) {
16675                            doTrim = true;
16676                            r.queue.processNextBroadcast(false);
16677                        }
16678                    }
16679
16680                    if (rl.app != null) {
16681                        rl.app.receivers.remove(rl);
16682                    }
16683                    removeReceiverLocked(rl);
16684                    if (rl.linkedToDeath) {
16685                        rl.linkedToDeath = false;
16686                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16687                    }
16688                }
16689            }
16690
16691            // If we actually concluded any broadcasts, we might now be able
16692            // to trim the recipients' apps from our working set
16693            if (doTrim) {
16694                trimApplications();
16695                return;
16696            }
16697
16698        } finally {
16699            Binder.restoreCallingIdentity(origId);
16700        }
16701    }
16702
16703    void removeReceiverLocked(ReceiverList rl) {
16704        mRegisteredReceivers.remove(rl.receiver.asBinder());
16705        for (int i = rl.size() - 1; i >= 0; i--) {
16706            mReceiverResolver.removeFilter(rl.get(i));
16707        }
16708    }
16709
16710    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16711        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16712            ProcessRecord r = mLruProcesses.get(i);
16713            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16714                try {
16715                    r.thread.dispatchPackageBroadcast(cmd, packages);
16716                } catch (RemoteException ex) {
16717                }
16718            }
16719        }
16720    }
16721
16722    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16723            int callingUid, int[] users) {
16724        // TODO: come back and remove this assumption to triage all broadcasts
16725        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
16726
16727        List<ResolveInfo> receivers = null;
16728        try {
16729            HashSet<ComponentName> singleUserReceivers = null;
16730            boolean scannedFirstReceivers = false;
16731            for (int user : users) {
16732                // Skip users that have Shell restrictions
16733                if (callingUid == Process.SHELL_UID
16734                        && mUserController.hasUserRestriction(
16735                        UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16736                    continue;
16737                }
16738                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16739                        .queryIntentReceivers(intent, resolvedType, pmFlags, user);
16740                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16741                    // If this is not the system user, we need to check for
16742                    // any receivers that should be filtered out.
16743                    for (int i=0; i<newReceivers.size(); i++) {
16744                        ResolveInfo ri = newReceivers.get(i);
16745                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16746                            newReceivers.remove(i);
16747                            i--;
16748                        }
16749                    }
16750                }
16751                if (newReceivers != null && newReceivers.size() == 0) {
16752                    newReceivers = null;
16753                }
16754                if (receivers == null) {
16755                    receivers = newReceivers;
16756                } else if (newReceivers != null) {
16757                    // We need to concatenate the additional receivers
16758                    // found with what we have do far.  This would be easy,
16759                    // but we also need to de-dup any receivers that are
16760                    // singleUser.
16761                    if (!scannedFirstReceivers) {
16762                        // Collect any single user receivers we had already retrieved.
16763                        scannedFirstReceivers = true;
16764                        for (int i=0; i<receivers.size(); i++) {
16765                            ResolveInfo ri = receivers.get(i);
16766                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16767                                ComponentName cn = new ComponentName(
16768                                        ri.activityInfo.packageName, ri.activityInfo.name);
16769                                if (singleUserReceivers == null) {
16770                                    singleUserReceivers = new HashSet<ComponentName>();
16771                                }
16772                                singleUserReceivers.add(cn);
16773                            }
16774                        }
16775                    }
16776                    // Add the new results to the existing results, tracking
16777                    // and de-dupping single user receivers.
16778                    for (int i=0; i<newReceivers.size(); i++) {
16779                        ResolveInfo ri = newReceivers.get(i);
16780                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16781                            ComponentName cn = new ComponentName(
16782                                    ri.activityInfo.packageName, ri.activityInfo.name);
16783                            if (singleUserReceivers == null) {
16784                                singleUserReceivers = new HashSet<ComponentName>();
16785                            }
16786                            if (!singleUserReceivers.contains(cn)) {
16787                                singleUserReceivers.add(cn);
16788                                receivers.add(ri);
16789                            }
16790                        } else {
16791                            receivers.add(ri);
16792                        }
16793                    }
16794                }
16795            }
16796        } catch (RemoteException ex) {
16797            // pm is in same process, this will never happen.
16798        }
16799        return receivers;
16800    }
16801
16802    final int broadcastIntentLocked(ProcessRecord callerApp,
16803            String callerPackage, Intent intent, String resolvedType,
16804            IIntentReceiver resultTo, int resultCode, String resultData,
16805            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
16806            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16807        intent = new Intent(intent);
16808
16809        // By default broadcasts do not go to stopped apps.
16810        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16811
16812        // If we have not finished booting, don't allow this to launch new processes.
16813        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16814            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16815        }
16816
16817        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16818                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16819                + " ordered=" + ordered + " userid=" + userId);
16820        if ((resultTo != null) && !ordered) {
16821            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16822        }
16823
16824        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16825                ALLOW_NON_FULL, "broadcast", callerPackage);
16826
16827        // Make sure that the user who is receiving this broadcast is running.
16828        // If not, we will just skip it. Make an exception for shutdown broadcasts
16829        // and upgrade steps.
16830
16831        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
16832            if ((callingUid != Process.SYSTEM_UID
16833                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16834                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16835                Slog.w(TAG, "Skipping broadcast of " + intent
16836                        + ": user " + userId + " is stopped");
16837                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16838            }
16839        }
16840
16841        BroadcastOptions brOptions = null;
16842        if (bOptions != null) {
16843            brOptions = new BroadcastOptions(bOptions);
16844            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16845                // See if the caller is allowed to do this.  Note we are checking against
16846                // the actual real caller (not whoever provided the operation as say a
16847                // PendingIntent), because that who is actually supplied the arguments.
16848                if (checkComponentPermission(
16849                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16850                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16851                        != PackageManager.PERMISSION_GRANTED) {
16852                    String msg = "Permission Denial: " + intent.getAction()
16853                            + " broadcast from " + callerPackage + " (pid=" + callingPid
16854                            + ", uid=" + callingUid + ")"
16855                            + " requires "
16856                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16857                    Slog.w(TAG, msg);
16858                    throw new SecurityException(msg);
16859                }
16860            }
16861        }
16862
16863        // Verify that protected broadcasts are only being sent by system code,
16864        // and that system code is only sending protected broadcasts.
16865        final String action = intent.getAction();
16866        final boolean isProtectedBroadcast;
16867        try {
16868            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
16869        } catch (RemoteException e) {
16870            Slog.w(TAG, "Remote exception", e);
16871            return ActivityManager.BROADCAST_SUCCESS;
16872        }
16873
16874        final boolean isCallerSystem;
16875        switch (UserHandle.getAppId(callingUid)) {
16876            case Process.ROOT_UID:
16877            case Process.SYSTEM_UID:
16878            case Process.PHONE_UID:
16879            case Process.SHELL_UID:
16880            case Process.BLUETOOTH_UID:
16881            case Process.NFC_UID:
16882                isCallerSystem = true;
16883                break;
16884            default:
16885                isCallerSystem = (callerApp != null) && callerApp.persistent;
16886                break;
16887        }
16888
16889        if (isCallerSystem) {
16890            if (isProtectedBroadcast
16891                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
16892                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
16893                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
16894                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
16895                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
16896                // Broadcast is either protected, or it's a public action that
16897                // we've relaxed, so it's fine for system internals to send.
16898            } else {
16899                // The vast majority of broadcasts sent from system internals
16900                // should be protected to avoid security holes, so yell loudly
16901                // to ensure we examine these cases.
16902                Log.wtf(TAG, "Sending non-protected broadcast " + action
16903                        + " from system", new Throwable());
16904            }
16905
16906        } else {
16907            if (isProtectedBroadcast) {
16908                String msg = "Permission Denial: not allowed to send broadcast "
16909                        + action + " from pid="
16910                        + callingPid + ", uid=" + callingUid;
16911                Slog.w(TAG, msg);
16912                throw new SecurityException(msg);
16913
16914            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
16915                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
16916                // Special case for compatibility: we don't want apps to send this,
16917                // but historically it has not been protected and apps may be using it
16918                // to poke their own app widget.  So, instead of making it protected,
16919                // just limit it to the caller.
16920                if (callerApp == null) {
16921                    String msg = "Permission Denial: not allowed to send broadcast "
16922                            + action + " from unknown caller.";
16923                    Slog.w(TAG, msg);
16924                    throw new SecurityException(msg);
16925                } else if (intent.getComponent() != null) {
16926                    // They are good enough to send to an explicit component...  verify
16927                    // it is being sent to the calling app.
16928                    if (!intent.getComponent().getPackageName().equals(
16929                            callerApp.info.packageName)) {
16930                        String msg = "Permission Denial: not allowed to send broadcast "
16931                                + action + " to "
16932                                + intent.getComponent().getPackageName() + " from "
16933                                + callerApp.info.packageName;
16934                        Slog.w(TAG, msg);
16935                        throw new SecurityException(msg);
16936                    }
16937                } else {
16938                    // Limit broadcast to their own package.
16939                    intent.setPackage(callerApp.info.packageName);
16940                }
16941            }
16942        }
16943
16944        if (action != null) {
16945            switch (action) {
16946                case Intent.ACTION_UID_REMOVED:
16947                case Intent.ACTION_PACKAGE_REMOVED:
16948                case Intent.ACTION_PACKAGE_CHANGED:
16949                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16950                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16951                case Intent.ACTION_PACKAGES_SUSPENDED:
16952                case Intent.ACTION_PACKAGES_UNSUSPENDED:
16953                    // Handle special intents: if this broadcast is from the package
16954                    // manager about a package being removed, we need to remove all of
16955                    // its activities from the history stack.
16956                    if (checkComponentPermission(
16957                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16958                            callingPid, callingUid, -1, true)
16959                            != PackageManager.PERMISSION_GRANTED) {
16960                        String msg = "Permission Denial: " + intent.getAction()
16961                                + " broadcast from " + callerPackage + " (pid=" + callingPid
16962                                + ", uid=" + callingUid + ")"
16963                                + " requires "
16964                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16965                        Slog.w(TAG, msg);
16966                        throw new SecurityException(msg);
16967                    }
16968                    switch (action) {
16969                        case Intent.ACTION_UID_REMOVED:
16970                            final Bundle intentExtras = intent.getExtras();
16971                            final int uid = intentExtras != null
16972                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16973                            if (uid >= 0) {
16974                                mBatteryStatsService.removeUid(uid);
16975                                mAppOpsService.uidRemoved(uid);
16976                            }
16977                            break;
16978                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16979                            // If resources are unavailable just force stop all those packages
16980                            // and flush the attribute cache as well.
16981                            String list[] =
16982                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16983                            if (list != null && list.length > 0) {
16984                                for (int i = 0; i < list.length; i++) {
16985                                    forceStopPackageLocked(list[i], -1, false, true, true,
16986                                            false, false, userId, "storage unmount");
16987                                }
16988                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16989                                sendPackageBroadcastLocked(
16990                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16991                                        userId);
16992                            }
16993                            break;
16994                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16995                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16996                            break;
16997                        case Intent.ACTION_PACKAGE_REMOVED:
16998                        case Intent.ACTION_PACKAGE_CHANGED:
16999                            Uri data = intent.getData();
17000                            String ssp;
17001                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17002                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17003                                boolean fullUninstall = removed &&
17004                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17005                                final boolean killProcess =
17006                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17007                                if (killProcess) {
17008                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17009                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17010                                            false, true, true, false, fullUninstall, userId,
17011                                            removed ? "pkg removed" : "pkg changed");
17012                                }
17013                                if (removed) {
17014                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
17015                                            new String[] {ssp}, userId);
17016                                    if (fullUninstall) {
17017                                        mAppOpsService.packageRemoved(
17018                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17019
17020                                        // Remove all permissions granted from/to this package
17021                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17022
17023                                        removeTasksByPackageNameLocked(ssp, userId);
17024                                        mBatteryStatsService.notePackageUninstalled(ssp);
17025                                    }
17026                                } else {
17027                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17028                                            intent.getStringArrayExtra(
17029                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17030                                }
17031                            }
17032                            break;
17033                        case Intent.ACTION_PACKAGES_SUSPENDED:
17034                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17035                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17036                                    intent.getAction());
17037                            final String[] packageNames = intent.getStringArrayExtra(
17038                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17039                            final int userHandle = intent.getIntExtra(
17040                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17041
17042                            synchronized(ActivityManagerService.this) {
17043                                mRecentTasks.onPackagesSuspendedChanged(
17044                                        packageNames, suspended, userHandle);
17045                            }
17046                            break;
17047                    }
17048                    break;
17049                case Intent.ACTION_PACKAGE_ADDED:
17050                    // Special case for adding a package: by default turn on compatibility mode.
17051                    Uri data = intent.getData();
17052                    String ssp;
17053                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17054                        final boolean replacing =
17055                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17056                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17057
17058                        try {
17059                            ApplicationInfo ai = AppGlobals.getPackageManager().
17060                                    getApplicationInfo(ssp, 0, 0);
17061                            mBatteryStatsService.notePackageInstalled(ssp,
17062                                    ai != null ? ai.versionCode : 0);
17063                        } catch (RemoteException e) {
17064                        }
17065                    }
17066                    break;
17067                case Intent.ACTION_TIMEZONE_CHANGED:
17068                    // If this is the time zone changed action, queue up a message that will reset
17069                    // the timezone of all currently running processes. This message will get
17070                    // queued up before the broadcast happens.
17071                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17072                    break;
17073                case Intent.ACTION_TIME_CHANGED:
17074                    // If the user set the time, let all running processes know.
17075                    final int is24Hour =
17076                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17077                                    : 0;
17078                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17079                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17080                    synchronized (stats) {
17081                        stats.noteCurrentTimeChangedLocked();
17082                    }
17083                    break;
17084                case Intent.ACTION_CLEAR_DNS_CACHE:
17085                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17086                    break;
17087                case Proxy.PROXY_CHANGE_ACTION:
17088                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17089                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17090                    break;
17091            }
17092        }
17093
17094        // Add to the sticky list if requested.
17095        if (sticky) {
17096            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17097                    callingPid, callingUid)
17098                    != PackageManager.PERMISSION_GRANTED) {
17099                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17100                        + callingPid + ", uid=" + callingUid
17101                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17102                Slog.w(TAG, msg);
17103                throw new SecurityException(msg);
17104            }
17105            if (requiredPermissions != null && requiredPermissions.length > 0) {
17106                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17107                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17108                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17109            }
17110            if (intent.getComponent() != null) {
17111                throw new SecurityException(
17112                        "Sticky broadcasts can't target a specific component");
17113            }
17114            // We use userId directly here, since the "all" target is maintained
17115            // as a separate set of sticky broadcasts.
17116            if (userId != UserHandle.USER_ALL) {
17117                // But first, if this is not a broadcast to all users, then
17118                // make sure it doesn't conflict with an existing broadcast to
17119                // all users.
17120                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17121                        UserHandle.USER_ALL);
17122                if (stickies != null) {
17123                    ArrayList<Intent> list = stickies.get(intent.getAction());
17124                    if (list != null) {
17125                        int N = list.size();
17126                        int i;
17127                        for (i=0; i<N; i++) {
17128                            if (intent.filterEquals(list.get(i))) {
17129                                throw new IllegalArgumentException(
17130                                        "Sticky broadcast " + intent + " for user "
17131                                        + userId + " conflicts with existing global broadcast");
17132                            }
17133                        }
17134                    }
17135                }
17136            }
17137            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17138            if (stickies == null) {
17139                stickies = new ArrayMap<>();
17140                mStickyBroadcasts.put(userId, stickies);
17141            }
17142            ArrayList<Intent> list = stickies.get(intent.getAction());
17143            if (list == null) {
17144                list = new ArrayList<>();
17145                stickies.put(intent.getAction(), list);
17146            }
17147            final int stickiesCount = list.size();
17148            int i;
17149            for (i = 0; i < stickiesCount; i++) {
17150                if (intent.filterEquals(list.get(i))) {
17151                    // This sticky already exists, replace it.
17152                    list.set(i, new Intent(intent));
17153                    break;
17154                }
17155            }
17156            if (i >= stickiesCount) {
17157                list.add(new Intent(intent));
17158            }
17159        }
17160
17161        int[] users;
17162        if (userId == UserHandle.USER_ALL) {
17163            // Caller wants broadcast to go to all started users.
17164            users = mUserController.getStartedUserArrayLocked();
17165        } else {
17166            // Caller wants broadcast to go to one specific user.
17167            users = new int[] {userId};
17168        }
17169
17170        // Figure out who all will receive this broadcast.
17171        List receivers = null;
17172        List<BroadcastFilter> registeredReceivers = null;
17173        // Need to resolve the intent to interested receivers...
17174        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17175                 == 0) {
17176            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17177        }
17178        if (intent.getComponent() == null) {
17179            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17180                // Query one target user at a time, excluding shell-restricted users
17181                for (int i = 0; i < users.length; i++) {
17182                    if (mUserController.hasUserRestriction(
17183                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17184                        continue;
17185                    }
17186                    List<BroadcastFilter> registeredReceiversForUser =
17187                            mReceiverResolver.queryIntent(intent,
17188                                    resolvedType, false, users[i]);
17189                    if (registeredReceivers == null) {
17190                        registeredReceivers = registeredReceiversForUser;
17191                    } else if (registeredReceiversForUser != null) {
17192                        registeredReceivers.addAll(registeredReceiversForUser);
17193                    }
17194                }
17195            } else {
17196                registeredReceivers = mReceiverResolver.queryIntent(intent,
17197                        resolvedType, false, userId);
17198            }
17199        }
17200
17201        final boolean replacePending =
17202                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17203
17204        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17205                + " replacePending=" + replacePending);
17206
17207        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17208        if (!ordered && NR > 0) {
17209            // If we are not serializing this broadcast, then send the
17210            // registered receivers separately so they don't wait for the
17211            // components to be launched.
17212            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17213            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17214                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17215                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17216                    resultExtras, ordered, sticky, false, userId);
17217            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17218            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17219            if (!replaced) {
17220                queue.enqueueParallelBroadcastLocked(r);
17221                queue.scheduleBroadcastsLocked();
17222            }
17223            registeredReceivers = null;
17224            NR = 0;
17225        }
17226
17227        // Merge into one list.
17228        int ir = 0;
17229        if (receivers != null) {
17230            // A special case for PACKAGE_ADDED: do not allow the package
17231            // being added to see this broadcast.  This prevents them from
17232            // using this as a back door to get run as soon as they are
17233            // installed.  Maybe in the future we want to have a special install
17234            // broadcast or such for apps, but we'd like to deliberately make
17235            // this decision.
17236            String skipPackages[] = null;
17237            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17238                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17239                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17240                Uri data = intent.getData();
17241                if (data != null) {
17242                    String pkgName = data.getSchemeSpecificPart();
17243                    if (pkgName != null) {
17244                        skipPackages = new String[] { pkgName };
17245                    }
17246                }
17247            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17248                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17249            }
17250            if (skipPackages != null && (skipPackages.length > 0)) {
17251                for (String skipPackage : skipPackages) {
17252                    if (skipPackage != null) {
17253                        int NT = receivers.size();
17254                        for (int it=0; it<NT; it++) {
17255                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17256                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17257                                receivers.remove(it);
17258                                it--;
17259                                NT--;
17260                            }
17261                        }
17262                    }
17263                }
17264            }
17265
17266            int NT = receivers != null ? receivers.size() : 0;
17267            int it = 0;
17268            ResolveInfo curt = null;
17269            BroadcastFilter curr = null;
17270            while (it < NT && ir < NR) {
17271                if (curt == null) {
17272                    curt = (ResolveInfo)receivers.get(it);
17273                }
17274                if (curr == null) {
17275                    curr = registeredReceivers.get(ir);
17276                }
17277                if (curr.getPriority() >= curt.priority) {
17278                    // Insert this broadcast record into the final list.
17279                    receivers.add(it, curr);
17280                    ir++;
17281                    curr = null;
17282                    it++;
17283                    NT++;
17284                } else {
17285                    // Skip to the next ResolveInfo in the final list.
17286                    it++;
17287                    curt = null;
17288                }
17289            }
17290        }
17291        while (ir < NR) {
17292            if (receivers == null) {
17293                receivers = new ArrayList();
17294            }
17295            receivers.add(registeredReceivers.get(ir));
17296            ir++;
17297        }
17298
17299        if ((receivers != null && receivers.size() > 0)
17300                || resultTo != null) {
17301            BroadcastQueue queue = broadcastQueueForIntent(intent);
17302            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17303                    callerPackage, callingPid, callingUid, resolvedType,
17304                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17305                    resultData, resultExtras, ordered, sticky, false, userId);
17306
17307            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17308                    + ": prev had " + queue.mOrderedBroadcasts.size());
17309            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17310                    "Enqueueing broadcast " + r.intent.getAction());
17311
17312            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17313            if (!replaced) {
17314                queue.enqueueOrderedBroadcastLocked(r);
17315                queue.scheduleBroadcastsLocked();
17316            }
17317        }
17318
17319        return ActivityManager.BROADCAST_SUCCESS;
17320    }
17321
17322    final Intent verifyBroadcastLocked(Intent intent) {
17323        // Refuse possible leaked file descriptors
17324        if (intent != null && intent.hasFileDescriptors() == true) {
17325            throw new IllegalArgumentException("File descriptors passed in Intent");
17326        }
17327
17328        int flags = intent.getFlags();
17329
17330        if (!mProcessesReady) {
17331            // if the caller really truly claims to know what they're doing, go
17332            // ahead and allow the broadcast without launching any receivers
17333            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17334                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17335            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17336                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17337                        + " before boot completion");
17338                throw new IllegalStateException("Cannot broadcast before boot completed");
17339            }
17340        }
17341
17342        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17343            throw new IllegalArgumentException(
17344                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17345        }
17346
17347        return intent;
17348    }
17349
17350    public final int broadcastIntent(IApplicationThread caller,
17351            Intent intent, String resolvedType, IIntentReceiver resultTo,
17352            int resultCode, String resultData, Bundle resultExtras,
17353            String[] requiredPermissions, int appOp, Bundle bOptions,
17354            boolean serialized, boolean sticky, int userId) {
17355        enforceNotIsolatedCaller("broadcastIntent");
17356        synchronized(this) {
17357            intent = verifyBroadcastLocked(intent);
17358
17359            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17360            final int callingPid = Binder.getCallingPid();
17361            final int callingUid = Binder.getCallingUid();
17362            final long origId = Binder.clearCallingIdentity();
17363            int res = broadcastIntentLocked(callerApp,
17364                    callerApp != null ? callerApp.info.packageName : null,
17365                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17366                    requiredPermissions, appOp, null, serialized, sticky,
17367                    callingPid, callingUid, userId);
17368            Binder.restoreCallingIdentity(origId);
17369            return res;
17370        }
17371    }
17372
17373
17374    int broadcastIntentInPackage(String packageName, int uid,
17375            Intent intent, String resolvedType, IIntentReceiver resultTo,
17376            int resultCode, String resultData, Bundle resultExtras,
17377            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17378            int userId) {
17379        synchronized(this) {
17380            intent = verifyBroadcastLocked(intent);
17381
17382            final long origId = Binder.clearCallingIdentity();
17383            String[] requiredPermissions = requiredPermission == null ? null
17384                    : new String[] {requiredPermission};
17385            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17386                    resultTo, resultCode, resultData, resultExtras,
17387                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17388                    sticky, -1, uid, userId);
17389            Binder.restoreCallingIdentity(origId);
17390            return res;
17391        }
17392    }
17393
17394    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17395        // Refuse possible leaked file descriptors
17396        if (intent != null && intent.hasFileDescriptors() == true) {
17397            throw new IllegalArgumentException("File descriptors passed in Intent");
17398        }
17399
17400        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17401                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17402
17403        synchronized(this) {
17404            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17405                    != PackageManager.PERMISSION_GRANTED) {
17406                String msg = "Permission Denial: unbroadcastIntent() from pid="
17407                        + Binder.getCallingPid()
17408                        + ", uid=" + Binder.getCallingUid()
17409                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17410                Slog.w(TAG, msg);
17411                throw new SecurityException(msg);
17412            }
17413            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17414            if (stickies != null) {
17415                ArrayList<Intent> list = stickies.get(intent.getAction());
17416                if (list != null) {
17417                    int N = list.size();
17418                    int i;
17419                    for (i=0; i<N; i++) {
17420                        if (intent.filterEquals(list.get(i))) {
17421                            list.remove(i);
17422                            break;
17423                        }
17424                    }
17425                    if (list.size() <= 0) {
17426                        stickies.remove(intent.getAction());
17427                    }
17428                }
17429                if (stickies.size() <= 0) {
17430                    mStickyBroadcasts.remove(userId);
17431                }
17432            }
17433        }
17434    }
17435
17436    void backgroundServicesFinishedLocked(int userId) {
17437        for (BroadcastQueue queue : mBroadcastQueues) {
17438            queue.backgroundServicesFinishedLocked(userId);
17439        }
17440    }
17441
17442    public void finishReceiver(IBinder who, int resultCode, String resultData,
17443            Bundle resultExtras, boolean resultAbort, int flags) {
17444        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17445
17446        // Refuse possible leaked file descriptors
17447        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17448            throw new IllegalArgumentException("File descriptors passed in Bundle");
17449        }
17450
17451        final long origId = Binder.clearCallingIdentity();
17452        try {
17453            boolean doNext = false;
17454            BroadcastRecord r;
17455
17456            synchronized(this) {
17457                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17458                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17459                r = queue.getMatchingOrderedReceiver(who);
17460                if (r != null) {
17461                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17462                        resultData, resultExtras, resultAbort, true);
17463                }
17464            }
17465
17466            if (doNext) {
17467                r.queue.processNextBroadcast(false);
17468            }
17469            trimApplications();
17470        } finally {
17471            Binder.restoreCallingIdentity(origId);
17472        }
17473    }
17474
17475    // =========================================================
17476    // INSTRUMENTATION
17477    // =========================================================
17478
17479    public boolean startInstrumentation(ComponentName className,
17480            String profileFile, int flags, Bundle arguments,
17481            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17482            int userId, String abiOverride) {
17483        enforceNotIsolatedCaller("startInstrumentation");
17484        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17485                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17486        // Refuse possible leaked file descriptors
17487        if (arguments != null && arguments.hasFileDescriptors()) {
17488            throw new IllegalArgumentException("File descriptors passed in Bundle");
17489        }
17490
17491        synchronized(this) {
17492            InstrumentationInfo ii = null;
17493            ApplicationInfo ai = null;
17494            try {
17495                ii = mContext.getPackageManager().getInstrumentationInfo(
17496                    className, STOCK_PM_FLAGS);
17497                ai = AppGlobals.getPackageManager().getApplicationInfo(
17498                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17499            } catch (PackageManager.NameNotFoundException e) {
17500            } catch (RemoteException e) {
17501            }
17502            if (ii == null) {
17503                reportStartInstrumentationFailure(watcher, className,
17504                        "Unable to find instrumentation info for: " + className);
17505                return false;
17506            }
17507            if (ai == null) {
17508                reportStartInstrumentationFailure(watcher, className,
17509                        "Unable to find instrumentation target package: " + ii.targetPackage);
17510                return false;
17511            }
17512            if (!ai.hasCode()) {
17513                reportStartInstrumentationFailure(watcher, className,
17514                        "Instrumentation target has no code: " + ii.targetPackage);
17515                return false;
17516            }
17517
17518            int match = mContext.getPackageManager().checkSignatures(
17519                    ii.targetPackage, ii.packageName);
17520            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17521                String msg = "Permission Denial: starting instrumentation "
17522                        + className + " from pid="
17523                        + Binder.getCallingPid()
17524                        + ", uid=" + Binder.getCallingPid()
17525                        + " not allowed because package " + ii.packageName
17526                        + " does not have a signature matching the target "
17527                        + ii.targetPackage;
17528                reportStartInstrumentationFailure(watcher, className, msg);
17529                throw new SecurityException(msg);
17530            }
17531
17532            final long origId = Binder.clearCallingIdentity();
17533            // Instrumentation can kill and relaunch even persistent processes
17534            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17535                    "start instr");
17536            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17537            app.instrumentationClass = className;
17538            app.instrumentationInfo = ai;
17539            app.instrumentationProfileFile = profileFile;
17540            app.instrumentationArguments = arguments;
17541            app.instrumentationWatcher = watcher;
17542            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17543            app.instrumentationResultClass = className;
17544            Binder.restoreCallingIdentity(origId);
17545        }
17546
17547        return true;
17548    }
17549
17550    /**
17551     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17552     * error to the logs, but if somebody is watching, send the report there too.  This enables
17553     * the "am" command to report errors with more information.
17554     *
17555     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17556     * @param cn The component name of the instrumentation.
17557     * @param report The error report.
17558     */
17559    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17560            ComponentName cn, String report) {
17561        Slog.w(TAG, report);
17562        try {
17563            if (watcher != null) {
17564                Bundle results = new Bundle();
17565                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17566                results.putString("Error", report);
17567                watcher.instrumentationStatus(cn, -1, results);
17568            }
17569        } catch (RemoteException e) {
17570            Slog.w(TAG, e);
17571        }
17572    }
17573
17574    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17575        if (app.instrumentationWatcher != null) {
17576            try {
17577                // NOTE:  IInstrumentationWatcher *must* be oneway here
17578                app.instrumentationWatcher.instrumentationFinished(
17579                    app.instrumentationClass,
17580                    resultCode,
17581                    results);
17582            } catch (RemoteException e) {
17583            }
17584        }
17585
17586        // Can't call out of the system process with a lock held, so post a message.
17587        if (app.instrumentationUiAutomationConnection != null) {
17588            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17589                    app.instrumentationUiAutomationConnection).sendToTarget();
17590        }
17591
17592        app.instrumentationWatcher = null;
17593        app.instrumentationUiAutomationConnection = null;
17594        app.instrumentationClass = null;
17595        app.instrumentationInfo = null;
17596        app.instrumentationProfileFile = null;
17597        app.instrumentationArguments = null;
17598
17599        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17600                "finished inst");
17601    }
17602
17603    public void finishInstrumentation(IApplicationThread target,
17604            int resultCode, Bundle results) {
17605        int userId = UserHandle.getCallingUserId();
17606        // Refuse possible leaked file descriptors
17607        if (results != null && results.hasFileDescriptors()) {
17608            throw new IllegalArgumentException("File descriptors passed in Intent");
17609        }
17610
17611        synchronized(this) {
17612            ProcessRecord app = getRecordForAppLocked(target);
17613            if (app == null) {
17614                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17615                return;
17616            }
17617            final long origId = Binder.clearCallingIdentity();
17618            finishInstrumentationLocked(app, resultCode, results);
17619            Binder.restoreCallingIdentity(origId);
17620        }
17621    }
17622
17623    // =========================================================
17624    // CONFIGURATION
17625    // =========================================================
17626
17627    public ConfigurationInfo getDeviceConfigurationInfo() {
17628        ConfigurationInfo config = new ConfigurationInfo();
17629        synchronized (this) {
17630            config.reqTouchScreen = mConfiguration.touchscreen;
17631            config.reqKeyboardType = mConfiguration.keyboard;
17632            config.reqNavigation = mConfiguration.navigation;
17633            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17634                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17635                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17636            }
17637            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17638                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17639                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17640            }
17641            config.reqGlEsVersion = GL_ES_VERSION;
17642        }
17643        return config;
17644    }
17645
17646    ActivityStack getFocusedStack() {
17647        return mStackSupervisor.getFocusedStack();
17648    }
17649
17650    @Override
17651    public int getFocusedStackId() throws RemoteException {
17652        ActivityStack focusedStack = getFocusedStack();
17653        if (focusedStack != null) {
17654            return focusedStack.getStackId();
17655        }
17656        return -1;
17657    }
17658
17659    public Configuration getConfiguration() {
17660        Configuration ci;
17661        synchronized(this) {
17662            ci = new Configuration(mConfiguration);
17663            ci.userSetLocale = false;
17664        }
17665        return ci;
17666    }
17667
17668    @Override
17669    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17670        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17671        synchronized (this) {
17672            mSuppressResizeConfigChanges = suppress;
17673        }
17674    }
17675
17676    @Override
17677    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17678        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17679        if (fromStackId == HOME_STACK_ID) {
17680            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17681        }
17682        synchronized (this) {
17683            final long origId = Binder.clearCallingIdentity();
17684            final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
17685            if (stack != null) {
17686                if (fromStackId == DOCKED_STACK_ID) {
17687
17688                    // We are moving all tasks from the docked stack to the fullscreen stack, which
17689                    // is dismissing the docked stack, so resize all other stacks to fullscreen here
17690                    // already so we don't end up with resize trashing.
17691                    for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
17692                        if (StackId.isResizeableByDockedStack(i)) {
17693                            ActivityStack otherStack = mStackSupervisor.getStack(i);
17694                            if (otherStack != null) {
17695                                mStackSupervisor.resizeStackLocked(i,
17696                                        null, null, null, PRESERVE_WINDOWS,
17697                                        true /* allowResizeInDockedMode */);
17698                            }
17699                        }
17700                    }
17701                }
17702                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
17703                final int size = tasks.size();
17704                if (onTop) {
17705                    for (int i = 0; i < size; i++) {
17706                        mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
17707                                FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, !FORCE_FOCUS,
17708                                "moveTasksToFullscreenStack", ANIMATE);
17709                    }
17710                } else {
17711                    for (int i = size - 1; i >= 0; i--) {
17712                        mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
17713                                FULLSCREEN_WORKSPACE_STACK_ID, 0);
17714                    }
17715                }
17716            }
17717            Binder.restoreCallingIdentity(origId);
17718        }
17719    }
17720
17721    @Override
17722    public void updatePersistentConfiguration(Configuration values) {
17723        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17724                "updateConfiguration()");
17725        enforceWriteSettingsPermission("updateConfiguration()");
17726        if (values == null) {
17727            throw new NullPointerException("Configuration must not be null");
17728        }
17729
17730        int userId = UserHandle.getCallingUserId();
17731
17732        synchronized(this) {
17733            final long origId = Binder.clearCallingIdentity();
17734            updateConfigurationLocked(values, null, false, true, userId);
17735            Binder.restoreCallingIdentity(origId);
17736        }
17737    }
17738
17739    private void updateFontScaleIfNeeded() {
17740        final int currentUserId;
17741        synchronized(this) {
17742            currentUserId = mUserController.getCurrentUserIdLocked();
17743        }
17744        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
17745                FONT_SCALE, 1.0f, currentUserId);
17746        if (mConfiguration.fontScale != scaleFactor) {
17747            final Configuration configuration = mWindowManager.computeNewConfiguration();
17748            configuration.fontScale = scaleFactor;
17749            updatePersistentConfiguration(configuration);
17750        }
17751    }
17752
17753    private void enforceWriteSettingsPermission(String func) {
17754        int uid = Binder.getCallingUid();
17755        if (uid == Process.ROOT_UID) {
17756            return;
17757        }
17758
17759        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17760                Settings.getPackageNameForUid(mContext, uid), false)) {
17761            return;
17762        }
17763
17764        String msg = "Permission Denial: " + func + " from pid="
17765                + Binder.getCallingPid()
17766                + ", uid=" + uid
17767                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17768        Slog.w(TAG, msg);
17769        throw new SecurityException(msg);
17770    }
17771
17772    public void updateConfiguration(Configuration values) {
17773        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17774                "updateConfiguration()");
17775
17776        synchronized(this) {
17777            if (values == null && mWindowManager != null) {
17778                // sentinel: fetch the current configuration from the window manager
17779                values = mWindowManager.computeNewConfiguration();
17780            }
17781
17782            if (mWindowManager != null) {
17783                mProcessList.applyDisplaySize(mWindowManager);
17784            }
17785
17786            final long origId = Binder.clearCallingIdentity();
17787            if (values != null) {
17788                Settings.System.clearConfiguration(values);
17789            }
17790            updateConfigurationLocked(values, null, false);
17791            Binder.restoreCallingIdentity(origId);
17792        }
17793    }
17794
17795    void updateUserConfigurationLocked() {
17796        Configuration configuration = new Configuration(mConfiguration);
17797        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
17798                mUserController.getCurrentUserIdLocked());
17799        updateConfigurationLocked(configuration, null, false);
17800    }
17801
17802    boolean updateConfigurationLocked(Configuration values,
17803            ActivityRecord starting, boolean initLocale) {
17804        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17805        return updateConfigurationLocked(values, starting, initLocale, false,
17806                UserHandle.USER_NULL);
17807    }
17808
17809    // To cache the list of supported system locales
17810    private String[] mSupportedSystemLocales = null;
17811
17812    /**
17813     * Do either or both things: (1) change the current configuration, and (2)
17814     * make sure the given activity is running with the (now) current
17815     * configuration.  Returns true if the activity has been left running, or
17816     * false if <var>starting</var> is being destroyed to match the new
17817     * configuration.
17818     *
17819     * @param userId is only used when persistent parameter is set to true to persist configuration
17820     *               for that particular user
17821     */
17822    private boolean updateConfigurationLocked(Configuration values,
17823            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17824        int changes = 0;
17825
17826        if (values != null) {
17827            Configuration newConfig = new Configuration(mConfiguration);
17828            changes = newConfig.updateFrom(values);
17829            if (changes != 0) {
17830                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17831                        "Updating configuration to: " + values);
17832
17833                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17834
17835                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
17836                    final Locale locale;
17837                    if (values.getLocales().size() == 1) {
17838                        // This is an optimization to avoid the JNI call when the result of
17839                        // getFirstMatch() does not depend on the supported locales.
17840                        locale = values.getLocales().get(0);
17841                    } else {
17842                        if (mSupportedSystemLocales == null) {
17843                            mSupportedSystemLocales =
17844                                    Resources.getSystem().getAssets().getLocales();
17845                        }
17846                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
17847                    }
17848                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
17849                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17850                            locale));
17851                }
17852
17853                mConfigurationSeq++;
17854                if (mConfigurationSeq <= 0) {
17855                    mConfigurationSeq = 1;
17856                }
17857                newConfig.seq = mConfigurationSeq;
17858                mConfiguration = newConfig;
17859                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17860                mUsageStatsService.reportConfigurationChange(newConfig,
17861                        mUserController.getCurrentUserIdLocked());
17862                //mUsageStatsService.noteStartConfig(newConfig);
17863
17864                final Configuration configCopy = new Configuration(mConfiguration);
17865
17866                // TODO: If our config changes, should we auto dismiss any currently
17867                // showing dialogs?
17868                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
17869
17870                AttributeCache ac = AttributeCache.instance();
17871                if (ac != null) {
17872                    ac.updateConfiguration(configCopy);
17873                }
17874
17875                // Make sure all resources in our process are updated
17876                // right now, so that anyone who is going to retrieve
17877                // resource values after we return will be sure to get
17878                // the new ones.  This is especially important during
17879                // boot, where the first config change needs to guarantee
17880                // all resources have that config before following boot
17881                // code is executed.
17882                mSystemThread.applyConfigurationToResources(configCopy);
17883
17884                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17885                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17886                    msg.obj = new Configuration(configCopy);
17887                    msg.arg1 = userId;
17888                    mHandler.sendMessage(msg);
17889                }
17890
17891                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
17892                if (isDensityChange) {
17893                    killAllBackgroundProcesses(Build.VERSION_CODES.N);
17894                }
17895
17896                for (int i=mLruProcesses.size()-1; i>=0; i--) {
17897                    ProcessRecord app = mLruProcesses.get(i);
17898                    try {
17899                        if (app.thread != null) {
17900                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17901                                    + app.processName + " new config " + mConfiguration);
17902                            app.thread.scheduleConfigurationChanged(configCopy);
17903                        }
17904                    } catch (Exception e) {
17905                    }
17906                }
17907                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17908                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17909                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
17910                        | Intent.FLAG_RECEIVER_FOREGROUND);
17911                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17912                        null, AppOpsManager.OP_NONE, null, false, false,
17913                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17914                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17915                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17916                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17917                    if (!mProcessesReady) {
17918                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17919                    }
17920                    broadcastIntentLocked(null, null, intent,
17921                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17922                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17923                }
17924            }
17925        }
17926
17927        boolean kept = true;
17928        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17929        // mainStack is null during startup.
17930        if (mainStack != null) {
17931            if (changes != 0 && starting == null) {
17932                // If the configuration changed, and the caller is not already
17933                // in the process of starting an activity, then find the top
17934                // activity to check if its configuration needs to change.
17935                starting = mainStack.topRunningActivityLocked();
17936            }
17937
17938            if (starting != null) {
17939                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
17940                // And we need to make sure at this point that all other activities
17941                // are made visible with the correct configuration.
17942                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
17943                        !PRESERVE_WINDOWS);
17944            }
17945        }
17946
17947        if (values != null && mWindowManager != null) {
17948            mWindowManager.setNewConfiguration(mConfiguration);
17949        }
17950
17951        return kept;
17952    }
17953
17954    /**
17955     * Decide based on the configuration whether we should shouw the ANR,
17956     * crash, etc dialogs.  The idea is that if there is no affordnace to
17957     * press the on-screen buttons, we shouldn't show the dialog.
17958     *
17959     * A thought: SystemUI might also want to get told about this, the Power
17960     * dialog / global actions also might want different behaviors.
17961     */
17962    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
17963        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17964                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17965                                   && config.navigation == Configuration.NAVIGATION_NONAV);
17966        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
17967                                    == Configuration.UI_MODE_TYPE_CAR);
17968        return inputMethodExists && uiIsNotCarType && !inVrMode;
17969    }
17970
17971    @Override
17972    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17973        synchronized (this) {
17974            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17975            if (srec != null) {
17976                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17977            }
17978        }
17979        return false;
17980    }
17981
17982    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17983            Intent resultData) {
17984
17985        synchronized (this) {
17986            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17987            if (r != null) {
17988                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17989            }
17990            return false;
17991        }
17992    }
17993
17994    public int getLaunchedFromUid(IBinder activityToken) {
17995        ActivityRecord srec;
17996        synchronized (this) {
17997            srec = ActivityRecord.forTokenLocked(activityToken);
17998        }
17999        if (srec == null) {
18000            return -1;
18001        }
18002        return srec.launchedFromUid;
18003    }
18004
18005    public String getLaunchedFromPackage(IBinder activityToken) {
18006        ActivityRecord srec;
18007        synchronized (this) {
18008            srec = ActivityRecord.forTokenLocked(activityToken);
18009        }
18010        if (srec == null) {
18011            return null;
18012        }
18013        return srec.launchedFromPackage;
18014    }
18015
18016    // =========================================================
18017    // LIFETIME MANAGEMENT
18018    // =========================================================
18019
18020    // Returns which broadcast queue the app is the current [or imminent] receiver
18021    // on, or 'null' if the app is not an active broadcast recipient.
18022    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18023        BroadcastRecord r = app.curReceiver;
18024        if (r != null) {
18025            return r.queue;
18026        }
18027
18028        // It's not the current receiver, but it might be starting up to become one
18029        synchronized (this) {
18030            for (BroadcastQueue queue : mBroadcastQueues) {
18031                r = queue.mPendingBroadcast;
18032                if (r != null && r.curApp == app) {
18033                    // found it; report which queue it's in
18034                    return queue;
18035                }
18036            }
18037        }
18038
18039        return null;
18040    }
18041
18042    Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18043            ComponentName targetComponent, String targetProcess) {
18044        if (!mTrackingAssociations) {
18045            return null;
18046        }
18047        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18048                = mAssociations.get(targetUid);
18049        if (components == null) {
18050            components = new ArrayMap<>();
18051            mAssociations.put(targetUid, components);
18052        }
18053        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18054        if (sourceUids == null) {
18055            sourceUids = new SparseArray<>();
18056            components.put(targetComponent, sourceUids);
18057        }
18058        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18059        if (sourceProcesses == null) {
18060            sourceProcesses = new ArrayMap<>();
18061            sourceUids.put(sourceUid, sourceProcesses);
18062        }
18063        Association ass = sourceProcesses.get(sourceProcess);
18064        if (ass == null) {
18065            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18066                    targetProcess);
18067            sourceProcesses.put(sourceProcess, ass);
18068        }
18069        ass.mCount++;
18070        ass.mNesting++;
18071        if (ass.mNesting == 1) {
18072            ass.mStartTime = SystemClock.uptimeMillis();
18073        }
18074        return ass;
18075    }
18076
18077    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18078            ComponentName targetComponent) {
18079        if (!mTrackingAssociations) {
18080            return;
18081        }
18082        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18083                = mAssociations.get(targetUid);
18084        if (components == null) {
18085            return;
18086        }
18087        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18088        if (sourceUids == null) {
18089            return;
18090        }
18091        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18092        if (sourceProcesses == null) {
18093            return;
18094        }
18095        Association ass = sourceProcesses.get(sourceProcess);
18096        if (ass == null || ass.mNesting <= 0) {
18097            return;
18098        }
18099        ass.mNesting--;
18100        if (ass.mNesting == 0) {
18101            ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18102        }
18103    }
18104
18105    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18106            boolean doingAll, long now) {
18107        if (mAdjSeq == app.adjSeq) {
18108            // This adjustment has already been computed.
18109            return app.curRawAdj;
18110        }
18111
18112        if (app.thread == null) {
18113            app.adjSeq = mAdjSeq;
18114            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18115            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18116            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18117        }
18118
18119        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18120        app.adjSource = null;
18121        app.adjTarget = null;
18122        app.empty = false;
18123        app.cached = false;
18124
18125        final int activitiesSize = app.activities.size();
18126
18127        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18128            // The max adjustment doesn't allow this app to be anything
18129            // below foreground, so it is not worth doing work for it.
18130            app.adjType = "fixed";
18131            app.adjSeq = mAdjSeq;
18132            app.curRawAdj = app.maxAdj;
18133            app.foregroundActivities = false;
18134            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18135            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18136            // System processes can do UI, and when they do we want to have
18137            // them trim their memory after the user leaves the UI.  To
18138            // facilitate this, here we need to determine whether or not it
18139            // is currently showing UI.
18140            app.systemNoUi = true;
18141            if (app == TOP_APP) {
18142                app.systemNoUi = false;
18143            } else if (activitiesSize > 0) {
18144                for (int j = 0; j < activitiesSize; j++) {
18145                    final ActivityRecord r = app.activities.get(j);
18146                    if (r.visible) {
18147                        app.systemNoUi = false;
18148                    }
18149                }
18150            }
18151            if (!app.systemNoUi) {
18152                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18153            }
18154            return (app.curAdj=app.maxAdj);
18155        }
18156
18157        app.systemNoUi = false;
18158
18159        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18160
18161        // Determine the importance of the process, starting with most
18162        // important to least, and assign an appropriate OOM adjustment.
18163        int adj;
18164        int schedGroup;
18165        int procState;
18166        boolean foregroundActivities = false;
18167        BroadcastQueue queue;
18168        if (app == TOP_APP) {
18169            // The last app on the list is the foreground app.
18170            adj = ProcessList.FOREGROUND_APP_ADJ;
18171            schedGroup = Process.THREAD_GROUP_TOP_APP;
18172            app.adjType = "top-activity";
18173            foregroundActivities = true;
18174            procState = PROCESS_STATE_CUR_TOP;
18175        } else if (app.instrumentationClass != null) {
18176            // Don't want to kill running instrumentation.
18177            adj = ProcessList.FOREGROUND_APP_ADJ;
18178            schedGroup = Process.THREAD_GROUP_DEFAULT;
18179            app.adjType = "instrumentation";
18180            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18181        } else if ((queue = isReceivingBroadcast(app)) != null) {
18182            // An app that is currently receiving a broadcast also
18183            // counts as being in the foreground for OOM killer purposes.
18184            // It's placed in a sched group based on the nature of the
18185            // broadcast as reflected by which queue it's active in.
18186            adj = ProcessList.FOREGROUND_APP_ADJ;
18187            schedGroup = (queue == mFgBroadcastQueue)
18188                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18189            app.adjType = "broadcast";
18190            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18191        } else if (app.executingServices.size() > 0) {
18192            // An app that is currently executing a service callback also
18193            // counts as being in the foreground.
18194            adj = ProcessList.FOREGROUND_APP_ADJ;
18195            schedGroup = app.execServicesFg ?
18196                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18197            app.adjType = "exec-service";
18198            procState = ActivityManager.PROCESS_STATE_SERVICE;
18199            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18200        } else {
18201            // As far as we know the process is empty.  We may change our mind later.
18202            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18203            // At this point we don't actually know the adjustment.  Use the cached adj
18204            // value that the caller wants us to.
18205            adj = cachedAdj;
18206            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18207            app.cached = true;
18208            app.empty = true;
18209            app.adjType = "cch-empty";
18210        }
18211
18212        // Examine all activities if not already foreground.
18213        if (!foregroundActivities && activitiesSize > 0) {
18214            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18215            for (int j = 0; j < activitiesSize; j++) {
18216                final ActivityRecord r = app.activities.get(j);
18217                if (r.app != app) {
18218                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18219                            + app + "?!? Using " + r.app + " instead.");
18220                    continue;
18221                }
18222                if (r.visible) {
18223                    // App has a visible activity; only upgrade adjustment.
18224                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18225                        adj = ProcessList.VISIBLE_APP_ADJ;
18226                        app.adjType = "visible";
18227                    }
18228                    if (procState > PROCESS_STATE_CUR_TOP) {
18229                        procState = PROCESS_STATE_CUR_TOP;
18230                    }
18231                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18232                    app.cached = false;
18233                    app.empty = false;
18234                    foregroundActivities = true;
18235                    if (r.task != null && minLayer > 0) {
18236                        final int layer = r.task.mLayerRank;
18237                        if (layer >= 0 && minLayer > layer) {
18238                            minLayer = layer;
18239                        }
18240                    }
18241                    break;
18242                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18243                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18244                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18245                        app.adjType = "pausing";
18246                    }
18247                    if (procState > PROCESS_STATE_CUR_TOP) {
18248                        procState = PROCESS_STATE_CUR_TOP;
18249                    }
18250                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18251                    app.cached = false;
18252                    app.empty = false;
18253                    foregroundActivities = true;
18254                } else if (r.state == ActivityState.STOPPING) {
18255                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18256                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18257                        app.adjType = "stopping";
18258                    }
18259                    // For the process state, we will at this point consider the
18260                    // process to be cached.  It will be cached either as an activity
18261                    // or empty depending on whether the activity is finishing.  We do
18262                    // this so that we can treat the process as cached for purposes of
18263                    // memory trimming (determing current memory level, trim command to
18264                    // send to process) since there can be an arbitrary number of stopping
18265                    // processes and they should soon all go into the cached state.
18266                    if (!r.finishing) {
18267                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18268                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18269                        }
18270                    }
18271                    app.cached = false;
18272                    app.empty = false;
18273                    foregroundActivities = true;
18274                } else {
18275                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18276                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18277                        app.adjType = "cch-act";
18278                    }
18279                }
18280            }
18281            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18282                adj += minLayer;
18283            }
18284        }
18285
18286        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18287                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18288            if (app.foregroundServices) {
18289                // The user is aware of this app, so make it visible.
18290                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18291                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18292                app.cached = false;
18293                app.adjType = "fg-service";
18294                schedGroup = Process.THREAD_GROUP_DEFAULT;
18295            } else if (app.forcingToForeground != null) {
18296                // The user is aware of this app, so make it visible.
18297                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18298                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18299                app.cached = false;
18300                app.adjType = "force-fg";
18301                app.adjSource = app.forcingToForeground;
18302                schedGroup = Process.THREAD_GROUP_DEFAULT;
18303            }
18304        }
18305
18306        if (app == mHeavyWeightProcess) {
18307            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18308                // We don't want to kill the current heavy-weight process.
18309                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18310                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18311                app.cached = false;
18312                app.adjType = "heavy";
18313            }
18314            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18315                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18316            }
18317        }
18318
18319        if (app == mHomeProcess) {
18320            if (adj > ProcessList.HOME_APP_ADJ) {
18321                // This process is hosting what we currently consider to be the
18322                // home app, so we don't want to let it go into the background.
18323                adj = ProcessList.HOME_APP_ADJ;
18324                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18325                app.cached = false;
18326                app.adjType = "home";
18327            }
18328            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18329                procState = ActivityManager.PROCESS_STATE_HOME;
18330            }
18331        }
18332
18333        if (app == mPreviousProcess && app.activities.size() > 0) {
18334            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18335                // This was the previous process that showed UI to the user.
18336                // We want to try to keep it around more aggressively, to give
18337                // a good experience around switching between two apps.
18338                adj = ProcessList.PREVIOUS_APP_ADJ;
18339                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18340                app.cached = false;
18341                app.adjType = "previous";
18342            }
18343            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18344                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18345            }
18346        }
18347
18348        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18349                + " reason=" + app.adjType);
18350
18351        // By default, we use the computed adjustment.  It may be changed if
18352        // there are applications dependent on our services or providers, but
18353        // this gives us a baseline and makes sure we don't get into an
18354        // infinite recursion.
18355        app.adjSeq = mAdjSeq;
18356        app.curRawAdj = adj;
18357        app.hasStartedServices = false;
18358
18359        if (mBackupTarget != null && app == mBackupTarget.app) {
18360            // If possible we want to avoid killing apps while they're being backed up
18361            if (adj > ProcessList.BACKUP_APP_ADJ) {
18362                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18363                adj = ProcessList.BACKUP_APP_ADJ;
18364                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18365                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18366                }
18367                app.adjType = "backup";
18368                app.cached = false;
18369            }
18370            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18371                procState = ActivityManager.PROCESS_STATE_BACKUP;
18372            }
18373        }
18374
18375        boolean mayBeTop = false;
18376
18377        for (int is = app.services.size()-1;
18378                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18379                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18380                        || procState > ActivityManager.PROCESS_STATE_TOP);
18381                is--) {
18382            ServiceRecord s = app.services.valueAt(is);
18383            if (s.startRequested) {
18384                app.hasStartedServices = true;
18385                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18386                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18387                }
18388                if (app.hasShownUi && app != mHomeProcess) {
18389                    // If this process has shown some UI, let it immediately
18390                    // go to the LRU list because it may be pretty heavy with
18391                    // UI stuff.  We'll tag it with a label just to help
18392                    // debug and understand what is going on.
18393                    if (adj > ProcessList.SERVICE_ADJ) {
18394                        app.adjType = "cch-started-ui-services";
18395                    }
18396                } else {
18397                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18398                        // This service has seen some activity within
18399                        // recent memory, so we will keep its process ahead
18400                        // of the background processes.
18401                        if (adj > ProcessList.SERVICE_ADJ) {
18402                            adj = ProcessList.SERVICE_ADJ;
18403                            app.adjType = "started-services";
18404                            app.cached = false;
18405                        }
18406                    }
18407                    // If we have let the service slide into the background
18408                    // state, still have some text describing what it is doing
18409                    // even though the service no longer has an impact.
18410                    if (adj > ProcessList.SERVICE_ADJ) {
18411                        app.adjType = "cch-started-services";
18412                    }
18413                }
18414            }
18415            for (int conni = s.connections.size()-1;
18416                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18417                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18418                            || procState > ActivityManager.PROCESS_STATE_TOP);
18419                    conni--) {
18420                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18421                for (int i = 0;
18422                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18423                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18424                                || procState > ActivityManager.PROCESS_STATE_TOP);
18425                        i++) {
18426                    // XXX should compute this based on the max of
18427                    // all connected clients.
18428                    ConnectionRecord cr = clist.get(i);
18429                    if (cr.binding.client == app) {
18430                        // Binding to ourself is not interesting.
18431                        continue;
18432                    }
18433                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18434                        ProcessRecord client = cr.binding.client;
18435                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18436                                TOP_APP, doingAll, now);
18437                        int clientProcState = client.curProcState;
18438                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18439                            // If the other app is cached for any reason, for purposes here
18440                            // we are going to consider it empty.  The specific cached state
18441                            // doesn't propagate except under certain conditions.
18442                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18443                        }
18444                        String adjType = null;
18445                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18446                            // Not doing bind OOM management, so treat
18447                            // this guy more like a started service.
18448                            if (app.hasShownUi && app != mHomeProcess) {
18449                                // If this process has shown some UI, let it immediately
18450                                // go to the LRU list because it may be pretty heavy with
18451                                // UI stuff.  We'll tag it with a label just to help
18452                                // debug and understand what is going on.
18453                                if (adj > clientAdj) {
18454                                    adjType = "cch-bound-ui-services";
18455                                }
18456                                app.cached = false;
18457                                clientAdj = adj;
18458                                clientProcState = procState;
18459                            } else {
18460                                if (now >= (s.lastActivity
18461                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18462                                    // This service has not seen activity within
18463                                    // recent memory, so allow it to drop to the
18464                                    // LRU list if there is no other reason to keep
18465                                    // it around.  We'll also tag it with a label just
18466                                    // to help debug and undertand what is going on.
18467                                    if (adj > clientAdj) {
18468                                        adjType = "cch-bound-services";
18469                                    }
18470                                    clientAdj = adj;
18471                                }
18472                            }
18473                        }
18474                        if (adj > clientAdj) {
18475                            // If this process has recently shown UI, and
18476                            // the process that is binding to it is less
18477                            // important than being visible, then we don't
18478                            // care about the binding as much as we care
18479                            // about letting this process get into the LRU
18480                            // list to be killed and restarted if needed for
18481                            // memory.
18482                            if (app.hasShownUi && app != mHomeProcess
18483                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18484                                adjType = "cch-bound-ui-services";
18485                            } else {
18486                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18487                                        |Context.BIND_IMPORTANT)) != 0) {
18488                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18489                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18490                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18491                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18492                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18493                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18494                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18495                                    adj = clientAdj;
18496                                } else {
18497                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18498                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18499                                    }
18500                                }
18501                                if (!client.cached) {
18502                                    app.cached = false;
18503                                }
18504                                adjType = "service";
18505                            }
18506                        }
18507                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18508                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18509                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18510                            }
18511                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18512                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18513                                    // Special handling of clients who are in the top state.
18514                                    // We *may* want to consider this process to be in the
18515                                    // top state as well, but only if there is not another
18516                                    // reason for it to be running.  Being on the top is a
18517                                    // special state, meaning you are specifically running
18518                                    // for the current top app.  If the process is already
18519                                    // running in the background for some other reason, it
18520                                    // is more important to continue considering it to be
18521                                    // in the background state.
18522                                    mayBeTop = true;
18523                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18524                                } else {
18525                                    // Special handling for above-top states (persistent
18526                                    // processes).  These should not bring the current process
18527                                    // into the top state, since they are not on top.  Instead
18528                                    // give them the best state after that.
18529                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18530                                        clientProcState =
18531                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18532                                    } else if (mWakefulness
18533                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18534                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18535                                                    != 0) {
18536                                        clientProcState =
18537                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18538                                    } else {
18539                                        clientProcState =
18540                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18541                                    }
18542                                }
18543                            }
18544                        } else {
18545                            if (clientProcState <
18546                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18547                                clientProcState =
18548                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18549                            }
18550                        }
18551                        if (procState > clientProcState) {
18552                            procState = clientProcState;
18553                        }
18554                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18555                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18556                            app.pendingUiClean = true;
18557                        }
18558                        if (adjType != null) {
18559                            app.adjType = adjType;
18560                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18561                                    .REASON_SERVICE_IN_USE;
18562                            app.adjSource = cr.binding.client;
18563                            app.adjSourceProcState = clientProcState;
18564                            app.adjTarget = s.name;
18565                        }
18566                    }
18567                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18568                        app.treatLikeActivity = true;
18569                    }
18570                    final ActivityRecord a = cr.activity;
18571                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18572                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18573                                (a.visible || a.state == ActivityState.RESUMED
18574                                 || a.state == ActivityState.PAUSING)) {
18575                            adj = ProcessList.FOREGROUND_APP_ADJ;
18576                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18577                                schedGroup = Process.THREAD_GROUP_DEFAULT;
18578                            }
18579                            app.cached = false;
18580                            app.adjType = "service";
18581                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18582                                    .REASON_SERVICE_IN_USE;
18583                            app.adjSource = a;
18584                            app.adjSourceProcState = procState;
18585                            app.adjTarget = s.name;
18586                        }
18587                    }
18588                }
18589            }
18590        }
18591
18592        for (int provi = app.pubProviders.size()-1;
18593                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18594                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18595                        || procState > ActivityManager.PROCESS_STATE_TOP);
18596                provi--) {
18597            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18598            for (int i = cpr.connections.size()-1;
18599                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18600                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18601                            || procState > ActivityManager.PROCESS_STATE_TOP);
18602                    i--) {
18603                ContentProviderConnection conn = cpr.connections.get(i);
18604                ProcessRecord client = conn.client;
18605                if (client == app) {
18606                    // Being our own client is not interesting.
18607                    continue;
18608                }
18609                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18610                int clientProcState = client.curProcState;
18611                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18612                    // If the other app is cached for any reason, for purposes here
18613                    // we are going to consider it empty.
18614                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18615                }
18616                if (adj > clientAdj) {
18617                    if (app.hasShownUi && app != mHomeProcess
18618                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18619                        app.adjType = "cch-ui-provider";
18620                    } else {
18621                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18622                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18623                        app.adjType = "provider";
18624                    }
18625                    app.cached &= client.cached;
18626                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18627                            .REASON_PROVIDER_IN_USE;
18628                    app.adjSource = client;
18629                    app.adjSourceProcState = clientProcState;
18630                    app.adjTarget = cpr.name;
18631                }
18632                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18633                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18634                        // Special handling of clients who are in the top state.
18635                        // We *may* want to consider this process to be in the
18636                        // top state as well, but only if there is not another
18637                        // reason for it to be running.  Being on the top is a
18638                        // special state, meaning you are specifically running
18639                        // for the current top app.  If the process is already
18640                        // running in the background for some other reason, it
18641                        // is more important to continue considering it to be
18642                        // in the background state.
18643                        mayBeTop = true;
18644                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18645                    } else {
18646                        // Special handling for above-top states (persistent
18647                        // processes).  These should not bring the current process
18648                        // into the top state, since they are not on top.  Instead
18649                        // give them the best state after that.
18650                        clientProcState =
18651                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18652                    }
18653                }
18654                if (procState > clientProcState) {
18655                    procState = clientProcState;
18656                }
18657                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18658                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18659                }
18660            }
18661            // If the provider has external (non-framework) process
18662            // dependencies, ensure that its adjustment is at least
18663            // FOREGROUND_APP_ADJ.
18664            if (cpr.hasExternalProcessHandles()) {
18665                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18666                    adj = ProcessList.FOREGROUND_APP_ADJ;
18667                    schedGroup = Process.THREAD_GROUP_DEFAULT;
18668                    app.cached = false;
18669                    app.adjType = "provider";
18670                    app.adjTarget = cpr.name;
18671                }
18672                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18673                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18674                }
18675            }
18676        }
18677
18678        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18679            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18680                adj = ProcessList.PREVIOUS_APP_ADJ;
18681                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18682                app.cached = false;
18683                app.adjType = "provider";
18684            }
18685            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18686                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18687            }
18688        }
18689
18690        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18691            // A client of one of our services or providers is in the top state.  We
18692            // *may* want to be in the top state, but not if we are already running in
18693            // the background for some other reason.  For the decision here, we are going
18694            // to pick out a few specific states that we want to remain in when a client
18695            // is top (states that tend to be longer-term) and otherwise allow it to go
18696            // to the top state.
18697            switch (procState) {
18698                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18699                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18700                case ActivityManager.PROCESS_STATE_SERVICE:
18701                    // These all are longer-term states, so pull them up to the top
18702                    // of the background states, but not all the way to the top state.
18703                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18704                    break;
18705                default:
18706                    // Otherwise, top is a better choice, so take it.
18707                    procState = ActivityManager.PROCESS_STATE_TOP;
18708                    break;
18709            }
18710        }
18711
18712        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18713            if (app.hasClientActivities) {
18714                // This is a cached process, but with client activities.  Mark it so.
18715                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18716                app.adjType = "cch-client-act";
18717            } else if (app.treatLikeActivity) {
18718                // This is a cached process, but somebody wants us to treat it like it has
18719                // an activity, okay!
18720                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18721                app.adjType = "cch-as-act";
18722            }
18723        }
18724
18725        if (adj == ProcessList.SERVICE_ADJ) {
18726            if (doingAll) {
18727                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18728                mNewNumServiceProcs++;
18729                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18730                if (!app.serviceb) {
18731                    // This service isn't far enough down on the LRU list to
18732                    // normally be a B service, but if we are low on RAM and it
18733                    // is large we want to force it down since we would prefer to
18734                    // keep launcher over it.
18735                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18736                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18737                        app.serviceHighRam = true;
18738                        app.serviceb = true;
18739                        //Slog.i(TAG, "ADJ " + app + " high ram!");
18740                    } else {
18741                        mNewNumAServiceProcs++;
18742                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
18743                    }
18744                } else {
18745                    app.serviceHighRam = false;
18746                }
18747            }
18748            if (app.serviceb) {
18749                adj = ProcessList.SERVICE_B_ADJ;
18750            }
18751        }
18752
18753        app.curRawAdj = adj;
18754
18755        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18756        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18757        if (adj > app.maxAdj) {
18758            adj = app.maxAdj;
18759            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18760                schedGroup = Process.THREAD_GROUP_DEFAULT;
18761            }
18762        }
18763
18764        // Do final modification to adj.  Everything we do between here and applying
18765        // the final setAdj must be done in this function, because we will also use
18766        // it when computing the final cached adj later.  Note that we don't need to
18767        // worry about this for max adj above, since max adj will always be used to
18768        // keep it out of the cached vaues.
18769        app.curAdj = app.modifyRawOomAdj(adj);
18770        app.curSchedGroup = schedGroup;
18771        app.curProcState = procState;
18772        app.foregroundActivities = foregroundActivities;
18773
18774        return app.curRawAdj;
18775    }
18776
18777    /**
18778     * Record new PSS sample for a process.
18779     */
18780    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
18781            long now) {
18782        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
18783                swapPss * 1024);
18784        proc.lastPssTime = now;
18785        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18786        if (DEBUG_PSS) Slog.d(TAG_PSS,
18787                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18788                + " state=" + ProcessList.makeProcStateString(procState));
18789        if (proc.initialIdlePss == 0) {
18790            proc.initialIdlePss = pss;
18791        }
18792        proc.lastPss = pss;
18793        proc.lastSwapPss = swapPss;
18794        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18795            proc.lastCachedPss = pss;
18796            proc.lastCachedSwapPss = swapPss;
18797        }
18798
18799        final SparseArray<Pair<Long, String>> watchUids
18800                = mMemWatchProcesses.getMap().get(proc.processName);
18801        Long check = null;
18802        if (watchUids != null) {
18803            Pair<Long, String> val = watchUids.get(proc.uid);
18804            if (val == null) {
18805                val = watchUids.get(0);
18806            }
18807            if (val != null) {
18808                check = val.first;
18809            }
18810        }
18811        if (check != null) {
18812            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18813                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18814                if (!isDebuggable) {
18815                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18816                        isDebuggable = true;
18817                    }
18818                }
18819                if (isDebuggable) {
18820                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18821                    final ProcessRecord myProc = proc;
18822                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
18823                    mMemWatchDumpProcName = proc.processName;
18824                    mMemWatchDumpFile = heapdumpFile.toString();
18825                    mMemWatchDumpPid = proc.pid;
18826                    mMemWatchDumpUid = proc.uid;
18827                    BackgroundThread.getHandler().post(new Runnable() {
18828                        @Override
18829                        public void run() {
18830                            revokeUriPermission(ActivityThread.currentActivityThread()
18831                                            .getApplicationThread(),
18832                                    DumpHeapActivity.JAVA_URI,
18833                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
18834                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18835                                    UserHandle.myUserId());
18836                            ParcelFileDescriptor fd = null;
18837                            try {
18838                                heapdumpFile.delete();
18839                                fd = ParcelFileDescriptor.open(heapdumpFile,
18840                                        ParcelFileDescriptor.MODE_CREATE |
18841                                                ParcelFileDescriptor.MODE_TRUNCATE |
18842                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
18843                                                ParcelFileDescriptor.MODE_APPEND);
18844                                IApplicationThread thread = myProc.thread;
18845                                if (thread != null) {
18846                                    try {
18847                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
18848                                                "Requesting dump heap from "
18849                                                + myProc + " to " + heapdumpFile);
18850                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
18851                                    } catch (RemoteException e) {
18852                                    }
18853                                }
18854                            } catch (FileNotFoundException e) {
18855                                e.printStackTrace();
18856                            } finally {
18857                                if (fd != null) {
18858                                    try {
18859                                        fd.close();
18860                                    } catch (IOException e) {
18861                                    }
18862                                }
18863                            }
18864                        }
18865                    });
18866                } else {
18867                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18868                            + ", but debugging not enabled");
18869                }
18870            }
18871        }
18872    }
18873
18874    /**
18875     * Schedule PSS collection of a process.
18876     */
18877    void requestPssLocked(ProcessRecord proc, int procState) {
18878        if (mPendingPssProcesses.contains(proc)) {
18879            return;
18880        }
18881        if (mPendingPssProcesses.size() == 0) {
18882            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18883        }
18884        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18885        proc.pssProcState = procState;
18886        mPendingPssProcesses.add(proc);
18887    }
18888
18889    /**
18890     * Schedule PSS collection of all processes.
18891     */
18892    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18893        if (!always) {
18894            if (now < (mLastFullPssTime +
18895                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18896                return;
18897            }
18898        }
18899        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
18900        mLastFullPssTime = now;
18901        mFullPssPending = true;
18902        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18903        mPendingPssProcesses.clear();
18904        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18905            ProcessRecord app = mLruProcesses.get(i);
18906            if (app.thread == null
18907                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18908                continue;
18909            }
18910            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18911                app.pssProcState = app.setProcState;
18912                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18913                        mTestPssMode, isSleeping(), now);
18914                mPendingPssProcesses.add(app);
18915            }
18916        }
18917        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18918    }
18919
18920    public void setTestPssMode(boolean enabled) {
18921        synchronized (this) {
18922            mTestPssMode = enabled;
18923            if (enabled) {
18924                // Whenever we enable the mode, we want to take a snapshot all of current
18925                // process mem use.
18926                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18927            }
18928        }
18929    }
18930
18931    /**
18932     * Ask a given process to GC right now.
18933     */
18934    final void performAppGcLocked(ProcessRecord app) {
18935        try {
18936            app.lastRequestedGc = SystemClock.uptimeMillis();
18937            if (app.thread != null) {
18938                if (app.reportLowMemory) {
18939                    app.reportLowMemory = false;
18940                    app.thread.scheduleLowMemory();
18941                } else {
18942                    app.thread.processInBackground();
18943                }
18944            }
18945        } catch (Exception e) {
18946            // whatever.
18947        }
18948    }
18949
18950    /**
18951     * Returns true if things are idle enough to perform GCs.
18952     */
18953    private final boolean canGcNowLocked() {
18954        boolean processingBroadcasts = false;
18955        for (BroadcastQueue q : mBroadcastQueues) {
18956            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18957                processingBroadcasts = true;
18958            }
18959        }
18960        return !processingBroadcasts
18961                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18962    }
18963
18964    /**
18965     * Perform GCs on all processes that are waiting for it, but only
18966     * if things are idle.
18967     */
18968    final void performAppGcsLocked() {
18969        final int N = mProcessesToGc.size();
18970        if (N <= 0) {
18971            return;
18972        }
18973        if (canGcNowLocked()) {
18974            while (mProcessesToGc.size() > 0) {
18975                ProcessRecord proc = mProcessesToGc.remove(0);
18976                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18977                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18978                            <= SystemClock.uptimeMillis()) {
18979                        // To avoid spamming the system, we will GC processes one
18980                        // at a time, waiting a few seconds between each.
18981                        performAppGcLocked(proc);
18982                        scheduleAppGcsLocked();
18983                        return;
18984                    } else {
18985                        // It hasn't been long enough since we last GCed this
18986                        // process...  put it in the list to wait for its time.
18987                        addProcessToGcListLocked(proc);
18988                        break;
18989                    }
18990                }
18991            }
18992
18993            scheduleAppGcsLocked();
18994        }
18995    }
18996
18997    /**
18998     * If all looks good, perform GCs on all processes waiting for them.
18999     */
19000    final void performAppGcsIfAppropriateLocked() {
19001        if (canGcNowLocked()) {
19002            performAppGcsLocked();
19003            return;
19004        }
19005        // Still not idle, wait some more.
19006        scheduleAppGcsLocked();
19007    }
19008
19009    /**
19010     * Schedule the execution of all pending app GCs.
19011     */
19012    final void scheduleAppGcsLocked() {
19013        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19014
19015        if (mProcessesToGc.size() > 0) {
19016            // Schedule a GC for the time to the next process.
19017            ProcessRecord proc = mProcessesToGc.get(0);
19018            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19019
19020            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19021            long now = SystemClock.uptimeMillis();
19022            if (when < (now+GC_TIMEOUT)) {
19023                when = now + GC_TIMEOUT;
19024            }
19025            mHandler.sendMessageAtTime(msg, when);
19026        }
19027    }
19028
19029    /**
19030     * Add a process to the array of processes waiting to be GCed.  Keeps the
19031     * list in sorted order by the last GC time.  The process can't already be
19032     * on the list.
19033     */
19034    final void addProcessToGcListLocked(ProcessRecord proc) {
19035        boolean added = false;
19036        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19037            if (mProcessesToGc.get(i).lastRequestedGc <
19038                    proc.lastRequestedGc) {
19039                added = true;
19040                mProcessesToGc.add(i+1, proc);
19041                break;
19042            }
19043        }
19044        if (!added) {
19045            mProcessesToGc.add(0, proc);
19046        }
19047    }
19048
19049    /**
19050     * Set up to ask a process to GC itself.  This will either do it
19051     * immediately, or put it on the list of processes to gc the next
19052     * time things are idle.
19053     */
19054    final void scheduleAppGcLocked(ProcessRecord app) {
19055        long now = SystemClock.uptimeMillis();
19056        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19057            return;
19058        }
19059        if (!mProcessesToGc.contains(app)) {
19060            addProcessToGcListLocked(app);
19061            scheduleAppGcsLocked();
19062        }
19063    }
19064
19065    final void checkExcessivePowerUsageLocked(boolean doKills) {
19066        updateCpuStatsNow();
19067
19068        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19069        boolean doWakeKills = doKills;
19070        boolean doCpuKills = doKills;
19071        if (mLastPowerCheckRealtime == 0) {
19072            doWakeKills = false;
19073        }
19074        if (mLastPowerCheckUptime == 0) {
19075            doCpuKills = false;
19076        }
19077        if (stats.isScreenOn()) {
19078            doWakeKills = false;
19079        }
19080        final long curRealtime = SystemClock.elapsedRealtime();
19081        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19082        final long curUptime = SystemClock.uptimeMillis();
19083        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19084        mLastPowerCheckRealtime = curRealtime;
19085        mLastPowerCheckUptime = curUptime;
19086        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19087            doWakeKills = false;
19088        }
19089        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19090            doCpuKills = false;
19091        }
19092        int i = mLruProcesses.size();
19093        while (i > 0) {
19094            i--;
19095            ProcessRecord app = mLruProcesses.get(i);
19096            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19097                long wtime;
19098                synchronized (stats) {
19099                    wtime = stats.getProcessWakeTime(app.info.uid,
19100                            app.pid, curRealtime);
19101                }
19102                long wtimeUsed = wtime - app.lastWakeTime;
19103                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19104                if (DEBUG_POWER) {
19105                    StringBuilder sb = new StringBuilder(128);
19106                    sb.append("Wake for ");
19107                    app.toShortString(sb);
19108                    sb.append(": over ");
19109                    TimeUtils.formatDuration(realtimeSince, sb);
19110                    sb.append(" used ");
19111                    TimeUtils.formatDuration(wtimeUsed, sb);
19112                    sb.append(" (");
19113                    sb.append((wtimeUsed*100)/realtimeSince);
19114                    sb.append("%)");
19115                    Slog.i(TAG_POWER, sb.toString());
19116                    sb.setLength(0);
19117                    sb.append("CPU for ");
19118                    app.toShortString(sb);
19119                    sb.append(": over ");
19120                    TimeUtils.formatDuration(uptimeSince, sb);
19121                    sb.append(" used ");
19122                    TimeUtils.formatDuration(cputimeUsed, sb);
19123                    sb.append(" (");
19124                    sb.append((cputimeUsed*100)/uptimeSince);
19125                    sb.append("%)");
19126                    Slog.i(TAG_POWER, sb.toString());
19127                }
19128                // If a process has held a wake lock for more
19129                // than 50% of the time during this period,
19130                // that sounds bad.  Kill!
19131                if (doWakeKills && realtimeSince > 0
19132                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19133                    synchronized (stats) {
19134                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19135                                realtimeSince, wtimeUsed);
19136                    }
19137                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19138                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19139                } else if (doCpuKills && uptimeSince > 0
19140                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19141                    synchronized (stats) {
19142                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19143                                uptimeSince, cputimeUsed);
19144                    }
19145                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19146                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19147                } else {
19148                    app.lastWakeTime = wtime;
19149                    app.lastCpuTime = app.curCpuTime;
19150                }
19151            }
19152        }
19153    }
19154
19155    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19156            long nowElapsed) {
19157        boolean success = true;
19158
19159        if (app.curRawAdj != app.setRawAdj) {
19160            app.setRawAdj = app.curRawAdj;
19161        }
19162
19163        int changes = 0;
19164
19165        if (app.curAdj != app.setAdj) {
19166            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19167            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19168                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19169                    + app.adjType);
19170            app.setAdj = app.curAdj;
19171        }
19172
19173        if (app.setSchedGroup != app.curSchedGroup) {
19174            app.setSchedGroup = app.curSchedGroup;
19175            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19176                    "Setting process group of " + app.processName
19177                    + " to " + app.curSchedGroup);
19178            if (app.waitingToKill != null && app.curReceiver == null
19179                    && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19180                app.kill(app.waitingToKill, true);
19181                success = false;
19182            } else {
19183                if (true) {
19184                    long oldId = Binder.clearCallingIdentity();
19185                    try {
19186                        Process.setProcessGroup(app.pid, app.curSchedGroup);
19187                    } catch (Exception e) {
19188                        Slog.w(TAG, "Failed setting process group of " + app.pid
19189                                + " to " + app.curSchedGroup);
19190                        e.printStackTrace();
19191                    } finally {
19192                        Binder.restoreCallingIdentity(oldId);
19193                    }
19194                } else {
19195                    if (app.thread != null) {
19196                        try {
19197                            app.thread.setSchedulingGroup(app.curSchedGroup);
19198                        } catch (RemoteException e) {
19199                        }
19200                    }
19201                }
19202            }
19203        }
19204        if (app.repForegroundActivities != app.foregroundActivities) {
19205            app.repForegroundActivities = app.foregroundActivities;
19206            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19207        }
19208        if (app.repProcState != app.curProcState) {
19209            app.repProcState = app.curProcState;
19210            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19211            if (app.thread != null) {
19212                try {
19213                    if (false) {
19214                        //RuntimeException h = new RuntimeException("here");
19215                        Slog.i(TAG, "Sending new process state " + app.repProcState
19216                                + " to " + app /*, h*/);
19217                    }
19218                    app.thread.setProcessState(app.repProcState);
19219                } catch (RemoteException e) {
19220                }
19221            }
19222        }
19223        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19224                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19225            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19226                // Experimental code to more aggressively collect pss while
19227                // running test...  the problem is that this tends to collect
19228                // the data right when a process is transitioning between process
19229                // states, which well tend to give noisy data.
19230                long start = SystemClock.uptimeMillis();
19231                long pss = Debug.getPss(app.pid, mTmpLong, null);
19232                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19233                mPendingPssProcesses.remove(app);
19234                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19235                        + " to " + app.curProcState + ": "
19236                        + (SystemClock.uptimeMillis()-start) + "ms");
19237            }
19238            app.lastStateTime = now;
19239            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19240                    mTestPssMode, isSleeping(), now);
19241            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19242                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19243                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19244                    + (app.nextPssTime-now) + ": " + app);
19245        } else {
19246            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19247                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19248                    mTestPssMode)))) {
19249                requestPssLocked(app, app.setProcState);
19250                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19251                        mTestPssMode, isSleeping(), now);
19252            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19253                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19254        }
19255        if (app.setProcState != app.curProcState) {
19256            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19257                    "Proc state change of " + app.processName
19258                            + " to " + app.curProcState);
19259            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19260            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19261            if (setImportant && !curImportant) {
19262                // This app is no longer something we consider important enough to allow to
19263                // use arbitrary amounts of battery power.  Note
19264                // its current wake lock time to later know to kill it if
19265                // it is not behaving well.
19266                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19267                synchronized (stats) {
19268                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19269                            app.pid, nowElapsed);
19270                }
19271                app.lastCpuTime = app.curCpuTime;
19272
19273            }
19274            // Inform UsageStats of important process state change
19275            // Must be called before updating setProcState
19276            maybeUpdateUsageStatsLocked(app, nowElapsed);
19277
19278            app.setProcState = app.curProcState;
19279            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19280                app.notCachedSinceIdle = false;
19281            }
19282            if (!doingAll) {
19283                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19284            } else {
19285                app.procStateChanged = true;
19286            }
19287        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19288                > USAGE_STATS_INTERACTION_INTERVAL) {
19289            // For apps that sit around for a long time in the interactive state, we need
19290            // to report this at least once a day so they don't go idle.
19291            maybeUpdateUsageStatsLocked(app, nowElapsed);
19292        }
19293
19294        if (changes != 0) {
19295            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19296                    "Changes in " + app + ": " + changes);
19297            int i = mPendingProcessChanges.size()-1;
19298            ProcessChangeItem item = null;
19299            while (i >= 0) {
19300                item = mPendingProcessChanges.get(i);
19301                if (item.pid == app.pid) {
19302                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19303                            "Re-using existing item: " + item);
19304                    break;
19305                }
19306                i--;
19307            }
19308            if (i < 0) {
19309                // No existing item in pending changes; need a new one.
19310                final int NA = mAvailProcessChanges.size();
19311                if (NA > 0) {
19312                    item = mAvailProcessChanges.remove(NA-1);
19313                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19314                            "Retrieving available item: " + item);
19315                } else {
19316                    item = new ProcessChangeItem();
19317                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19318                            "Allocating new item: " + item);
19319                }
19320                item.changes = 0;
19321                item.pid = app.pid;
19322                item.uid = app.info.uid;
19323                if (mPendingProcessChanges.size() == 0) {
19324                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19325                            "*** Enqueueing dispatch processes changed!");
19326                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19327                }
19328                mPendingProcessChanges.add(item);
19329            }
19330            item.changes |= changes;
19331            item.processState = app.repProcState;
19332            item.foregroundActivities = app.repForegroundActivities;
19333            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19334                    "Item " + Integer.toHexString(System.identityHashCode(item))
19335                    + " " + app.toShortString() + ": changes=" + item.changes
19336                    + " procState=" + item.processState
19337                    + " foreground=" + item.foregroundActivities
19338                    + " type=" + app.adjType + " source=" + app.adjSource
19339                    + " target=" + app.adjTarget);
19340        }
19341
19342        return success;
19343    }
19344
19345    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19346        final UidRecord.ChangeItem pendingChange;
19347        if (uidRec == null || uidRec.pendingChange == null) {
19348            if (mPendingUidChanges.size() == 0) {
19349                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19350                        "*** Enqueueing dispatch uid changed!");
19351                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19352            }
19353            final int NA = mAvailUidChanges.size();
19354            if (NA > 0) {
19355                pendingChange = mAvailUidChanges.remove(NA-1);
19356                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19357                        "Retrieving available item: " + pendingChange);
19358            } else {
19359                pendingChange = new UidRecord.ChangeItem();
19360                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19361                        "Allocating new item: " + pendingChange);
19362            }
19363            if (uidRec != null) {
19364                uidRec.pendingChange = pendingChange;
19365                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19366                    // If this uid is going away, and we haven't yet reported it is gone,
19367                    // then do so now.
19368                    change = UidRecord.CHANGE_GONE_IDLE;
19369                }
19370            } else if (uid < 0) {
19371                throw new IllegalArgumentException("No UidRecord or uid");
19372            }
19373            pendingChange.uidRecord = uidRec;
19374            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19375            mPendingUidChanges.add(pendingChange);
19376        } else {
19377            pendingChange = uidRec.pendingChange;
19378            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19379                change = UidRecord.CHANGE_GONE_IDLE;
19380            }
19381        }
19382        pendingChange.change = change;
19383        pendingChange.processState = uidRec != null
19384                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19385    }
19386
19387    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19388            String authority) {
19389        if (app == null) return;
19390        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19391            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19392            if (userState == null) return;
19393            final long now = SystemClock.elapsedRealtime();
19394            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19395            if (lastReported == null || lastReported < now - 60 * 1000L) {
19396                mUsageStatsService.reportContentProviderUsage(
19397                        authority, providerPkgName, app.userId);
19398                userState.mProviderLastReportedFg.put(authority, now);
19399            }
19400        }
19401    }
19402
19403    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19404        if (DEBUG_USAGE_STATS) {
19405            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19406                    + "] state changes: old = " + app.setProcState + ", new = "
19407                    + app.curProcState);
19408        }
19409        if (mUsageStatsService == null) {
19410            return;
19411        }
19412        boolean isInteraction;
19413        // To avoid some abuse patterns, we are going to be careful about what we consider
19414        // to be an app interaction.  Being the top activity doesn't count while the display
19415        // is sleeping, nor do short foreground services.
19416        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19417            isInteraction = true;
19418            app.fgInteractionTime = 0;
19419        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19420            if (app.fgInteractionTime == 0) {
19421                app.fgInteractionTime = nowElapsed;
19422                isInteraction = false;
19423            } else {
19424                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19425            }
19426        } else {
19427            isInteraction = app.curProcState
19428                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19429            app.fgInteractionTime = 0;
19430        }
19431        if (isInteraction && (!app.reportedInteraction
19432                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19433            app.interactionEventTime = nowElapsed;
19434            String[] packages = app.getPackageList();
19435            if (packages != null) {
19436                for (int i = 0; i < packages.length; i++) {
19437                    mUsageStatsService.reportEvent(packages[i], app.userId,
19438                            UsageEvents.Event.SYSTEM_INTERACTION);
19439                }
19440            }
19441        }
19442        app.reportedInteraction = isInteraction;
19443        if (!isInteraction) {
19444            app.interactionEventTime = 0;
19445        }
19446    }
19447
19448    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19449        if (proc.thread != null) {
19450            if (proc.baseProcessTracker != null) {
19451                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19452            }
19453        }
19454    }
19455
19456    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19457            ProcessRecord TOP_APP, boolean doingAll, long now) {
19458        if (app.thread == null) {
19459            return false;
19460        }
19461
19462        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19463
19464        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19465    }
19466
19467    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19468            boolean oomAdj) {
19469        if (isForeground != proc.foregroundServices) {
19470            proc.foregroundServices = isForeground;
19471            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19472                    proc.info.uid);
19473            if (isForeground) {
19474                if (curProcs == null) {
19475                    curProcs = new ArrayList<ProcessRecord>();
19476                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19477                }
19478                if (!curProcs.contains(proc)) {
19479                    curProcs.add(proc);
19480                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19481                            proc.info.packageName, proc.info.uid);
19482                }
19483            } else {
19484                if (curProcs != null) {
19485                    if (curProcs.remove(proc)) {
19486                        mBatteryStatsService.noteEvent(
19487                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19488                                proc.info.packageName, proc.info.uid);
19489                        if (curProcs.size() <= 0) {
19490                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19491                        }
19492                    }
19493                }
19494            }
19495            if (oomAdj) {
19496                updateOomAdjLocked();
19497            }
19498        }
19499    }
19500
19501    private final ActivityRecord resumedAppLocked() {
19502        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19503        String pkg;
19504        int uid;
19505        if (act != null) {
19506            pkg = act.packageName;
19507            uid = act.info.applicationInfo.uid;
19508        } else {
19509            pkg = null;
19510            uid = -1;
19511        }
19512        // Has the UID or resumed package name changed?
19513        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19514                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19515            if (mCurResumedPackage != null) {
19516                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19517                        mCurResumedPackage, mCurResumedUid);
19518            }
19519            mCurResumedPackage = pkg;
19520            mCurResumedUid = uid;
19521            if (mCurResumedPackage != null) {
19522                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19523                        mCurResumedPackage, mCurResumedUid);
19524            }
19525        }
19526        return act;
19527    }
19528
19529    final boolean updateOomAdjLocked(ProcessRecord app) {
19530        final ActivityRecord TOP_ACT = resumedAppLocked();
19531        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19532        final boolean wasCached = app.cached;
19533
19534        mAdjSeq++;
19535
19536        // This is the desired cached adjusment we want to tell it to use.
19537        // If our app is currently cached, we know it, and that is it.  Otherwise,
19538        // we don't know it yet, and it needs to now be cached we will then
19539        // need to do a complete oom adj.
19540        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19541                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19542        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19543                SystemClock.uptimeMillis());
19544        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19545            // Changed to/from cached state, so apps after it in the LRU
19546            // list may also be changed.
19547            updateOomAdjLocked();
19548        }
19549        return success;
19550    }
19551
19552    final void updateOomAdjLocked() {
19553        final ActivityRecord TOP_ACT = resumedAppLocked();
19554        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19555        final long now = SystemClock.uptimeMillis();
19556        final long nowElapsed = SystemClock.elapsedRealtime();
19557        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19558        final int N = mLruProcesses.size();
19559
19560        if (false) {
19561            RuntimeException e = new RuntimeException();
19562            e.fillInStackTrace();
19563            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19564        }
19565
19566        // Reset state in all uid records.
19567        for (int i=mActiveUids.size()-1; i>=0; i--) {
19568            final UidRecord uidRec = mActiveUids.valueAt(i);
19569            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19570                    "Starting update of " + uidRec);
19571            uidRec.reset();
19572        }
19573
19574        mStackSupervisor.rankTaskLayersIfNeeded();
19575
19576        mAdjSeq++;
19577        mNewNumServiceProcs = 0;
19578        mNewNumAServiceProcs = 0;
19579
19580        final int emptyProcessLimit;
19581        final int cachedProcessLimit;
19582        if (mProcessLimit <= 0) {
19583            emptyProcessLimit = cachedProcessLimit = 0;
19584        } else if (mProcessLimit == 1) {
19585            emptyProcessLimit = 1;
19586            cachedProcessLimit = 0;
19587        } else {
19588            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19589            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19590        }
19591
19592        // Let's determine how many processes we have running vs.
19593        // how many slots we have for background processes; we may want
19594        // to put multiple processes in a slot of there are enough of
19595        // them.
19596        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19597                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19598        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19599        if (numEmptyProcs > cachedProcessLimit) {
19600            // If there are more empty processes than our limit on cached
19601            // processes, then use the cached process limit for the factor.
19602            // This ensures that the really old empty processes get pushed
19603            // down to the bottom, so if we are running low on memory we will
19604            // have a better chance at keeping around more cached processes
19605            // instead of a gazillion empty processes.
19606            numEmptyProcs = cachedProcessLimit;
19607        }
19608        int emptyFactor = numEmptyProcs/numSlots;
19609        if (emptyFactor < 1) emptyFactor = 1;
19610        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19611        if (cachedFactor < 1) cachedFactor = 1;
19612        int stepCached = 0;
19613        int stepEmpty = 0;
19614        int numCached = 0;
19615        int numEmpty = 0;
19616        int numTrimming = 0;
19617
19618        mNumNonCachedProcs = 0;
19619        mNumCachedHiddenProcs = 0;
19620
19621        // First update the OOM adjustment for each of the
19622        // application processes based on their current state.
19623        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19624        int nextCachedAdj = curCachedAdj+1;
19625        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19626        int nextEmptyAdj = curEmptyAdj+2;
19627        for (int i=N-1; i>=0; i--) {
19628            ProcessRecord app = mLruProcesses.get(i);
19629            if (!app.killedByAm && app.thread != null) {
19630                app.procStateChanged = false;
19631                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19632
19633                // If we haven't yet assigned the final cached adj
19634                // to the process, do that now.
19635                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19636                    switch (app.curProcState) {
19637                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19638                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19639                            // This process is a cached process holding activities...
19640                            // assign it the next cached value for that type, and then
19641                            // step that cached level.
19642                            app.curRawAdj = curCachedAdj;
19643                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19644                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19645                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19646                                    + ")");
19647                            if (curCachedAdj != nextCachedAdj) {
19648                                stepCached++;
19649                                if (stepCached >= cachedFactor) {
19650                                    stepCached = 0;
19651                                    curCachedAdj = nextCachedAdj;
19652                                    nextCachedAdj += 2;
19653                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19654                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19655                                    }
19656                                }
19657                            }
19658                            break;
19659                        default:
19660                            // For everything else, assign next empty cached process
19661                            // level and bump that up.  Note that this means that
19662                            // long-running services that have dropped down to the
19663                            // cached level will be treated as empty (since their process
19664                            // state is still as a service), which is what we want.
19665                            app.curRawAdj = curEmptyAdj;
19666                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19667                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19668                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19669                                    + ")");
19670                            if (curEmptyAdj != nextEmptyAdj) {
19671                                stepEmpty++;
19672                                if (stepEmpty >= emptyFactor) {
19673                                    stepEmpty = 0;
19674                                    curEmptyAdj = nextEmptyAdj;
19675                                    nextEmptyAdj += 2;
19676                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19677                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19678                                    }
19679                                }
19680                            }
19681                            break;
19682                    }
19683                }
19684
19685                applyOomAdjLocked(app, true, now, nowElapsed);
19686
19687                // Count the number of process types.
19688                switch (app.curProcState) {
19689                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19690                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19691                        mNumCachedHiddenProcs++;
19692                        numCached++;
19693                        if (numCached > cachedProcessLimit) {
19694                            app.kill("cached #" + numCached, true);
19695                        }
19696                        break;
19697                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19698                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19699                                && app.lastActivityTime < oldTime) {
19700                            app.kill("empty for "
19701                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19702                                    / 1000) + "s", true);
19703                        } else {
19704                            numEmpty++;
19705                            if (numEmpty > emptyProcessLimit) {
19706                                app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
19707                            }
19708                        }
19709                        break;
19710                    default:
19711                        mNumNonCachedProcs++;
19712                        break;
19713                }
19714
19715                if (app.isolated && app.services.size() <= 0) {
19716                    // If this is an isolated process, and there are no
19717                    // services running in it, then the process is no longer
19718                    // needed.  We agressively kill these because we can by
19719                    // definition not re-use the same process again, and it is
19720                    // good to avoid having whatever code was running in them
19721                    // left sitting around after no longer needed.
19722                    app.kill("isolated not needed", true);
19723                } else {
19724                    // Keeping this process, update its uid.
19725                    final UidRecord uidRec = app.uidRecord;
19726                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
19727                        uidRec.curProcState = app.curProcState;
19728                    }
19729                }
19730
19731                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19732                        && !app.killedByAm) {
19733                    numTrimming++;
19734                }
19735            }
19736        }
19737
19738        mNumServiceProcs = mNewNumServiceProcs;
19739
19740        // Now determine the memory trimming level of background processes.
19741        // Unfortunately we need to start at the back of the list to do this
19742        // properly.  We only do this if the number of background apps we
19743        // are managing to keep around is less than half the maximum we desire;
19744        // if we are keeping a good number around, we'll let them use whatever
19745        // memory they want.
19746        final int numCachedAndEmpty = numCached + numEmpty;
19747        int memFactor;
19748        if (numCached <= ProcessList.TRIM_CACHED_APPS
19749                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19750            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19751                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19752            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19753                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19754            } else {
19755                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19756            }
19757        } else {
19758            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19759        }
19760        // We always allow the memory level to go up (better).  We only allow it to go
19761        // down if we are in a state where that is allowed, *and* the total number of processes
19762        // has gone down since last time.
19763        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19764                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19765                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19766        if (memFactor > mLastMemoryLevel) {
19767            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19768                memFactor = mLastMemoryLevel;
19769                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19770            }
19771        }
19772        mLastMemoryLevel = memFactor;
19773        mLastNumProcesses = mLruProcesses.size();
19774        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19775        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19776        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19777            if (mLowRamStartTime == 0) {
19778                mLowRamStartTime = now;
19779            }
19780            int step = 0;
19781            int fgTrimLevel;
19782            switch (memFactor) {
19783                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19784                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19785                    break;
19786                case ProcessStats.ADJ_MEM_FACTOR_LOW:
19787                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19788                    break;
19789                default:
19790                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19791                    break;
19792            }
19793            int factor = numTrimming/3;
19794            int minFactor = 2;
19795            if (mHomeProcess != null) minFactor++;
19796            if (mPreviousProcess != null) minFactor++;
19797            if (factor < minFactor) factor = minFactor;
19798            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19799            for (int i=N-1; i>=0; i--) {
19800                ProcessRecord app = mLruProcesses.get(i);
19801                if (allChanged || app.procStateChanged) {
19802                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19803                    app.procStateChanged = false;
19804                }
19805                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19806                        && !app.killedByAm) {
19807                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
19808                        try {
19809                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19810                                    "Trimming memory of " + app.processName + " to " + curLevel);
19811                            app.thread.scheduleTrimMemory(curLevel);
19812                        } catch (RemoteException e) {
19813                        }
19814                        if (false) {
19815                            // For now we won't do this; our memory trimming seems
19816                            // to be good enough at this point that destroying
19817                            // activities causes more harm than good.
19818                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19819                                    && app != mHomeProcess && app != mPreviousProcess) {
19820                                // Need to do this on its own message because the stack may not
19821                                // be in a consistent state at this point.
19822                                // For these apps we will also finish their activities
19823                                // to help them free memory.
19824                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19825                            }
19826                        }
19827                    }
19828                    app.trimMemoryLevel = curLevel;
19829                    step++;
19830                    if (step >= factor) {
19831                        step = 0;
19832                        switch (curLevel) {
19833                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19834                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19835                                break;
19836                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19837                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19838                                break;
19839                        }
19840                    }
19841                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19842                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19843                            && app.thread != null) {
19844                        try {
19845                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19846                                    "Trimming memory of heavy-weight " + app.processName
19847                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19848                            app.thread.scheduleTrimMemory(
19849                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19850                        } catch (RemoteException e) {
19851                        }
19852                    }
19853                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19854                } else {
19855                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19856                            || app.systemNoUi) && app.pendingUiClean) {
19857                        // If this application is now in the background and it
19858                        // had done UI, then give it the special trim level to
19859                        // have it free UI resources.
19860                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19861                        if (app.trimMemoryLevel < level && app.thread != null) {
19862                            try {
19863                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19864                                        "Trimming memory of bg-ui " + app.processName
19865                                        + " to " + level);
19866                                app.thread.scheduleTrimMemory(level);
19867                            } catch (RemoteException e) {
19868                            }
19869                        }
19870                        app.pendingUiClean = false;
19871                    }
19872                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19873                        try {
19874                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19875                                    "Trimming memory of fg " + app.processName
19876                                    + " to " + fgTrimLevel);
19877                            app.thread.scheduleTrimMemory(fgTrimLevel);
19878                        } catch (RemoteException e) {
19879                        }
19880                    }
19881                    app.trimMemoryLevel = fgTrimLevel;
19882                }
19883            }
19884        } else {
19885            if (mLowRamStartTime != 0) {
19886                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19887                mLowRamStartTime = 0;
19888            }
19889            for (int i=N-1; i>=0; i--) {
19890                ProcessRecord app = mLruProcesses.get(i);
19891                if (allChanged || app.procStateChanged) {
19892                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
19893                    app.procStateChanged = false;
19894                }
19895                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19896                        || app.systemNoUi) && app.pendingUiClean) {
19897                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19898                            && app.thread != null) {
19899                        try {
19900                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19901                                    "Trimming memory of ui hidden " + app.processName
19902                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19903                            app.thread.scheduleTrimMemory(
19904                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19905                        } catch (RemoteException e) {
19906                        }
19907                    }
19908                    app.pendingUiClean = false;
19909                }
19910                app.trimMemoryLevel = 0;
19911            }
19912        }
19913
19914        if (mAlwaysFinishActivities) {
19915            // Need to do this on its own message because the stack may not
19916            // be in a consistent state at this point.
19917            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19918        }
19919
19920        if (allChanged) {
19921            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19922        }
19923
19924        // Update from any uid changes.
19925        for (int i=mActiveUids.size()-1; i>=0; i--) {
19926            final UidRecord uidRec = mActiveUids.valueAt(i);
19927            int uidChange = UidRecord.CHANGE_PROCSTATE;
19928            if (uidRec.setProcState != uidRec.curProcState) {
19929                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19930                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19931                        + " to " + uidRec.curProcState);
19932                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
19933                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
19934                        uidRec.lastBackgroundTime = nowElapsed;
19935                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
19936                            // Note: the background settle time is in elapsed realtime, while
19937                            // the handler time base is uptime.  All this means is that we may
19938                            // stop background uids later than we had intended, but that only
19939                            // happens because the device was sleeping so we are okay anyway.
19940                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
19941                        }
19942                    }
19943                } else {
19944                    if (uidRec.idle) {
19945                        uidChange = UidRecord.CHANGE_ACTIVE;
19946                        uidRec.idle = false;
19947                    }
19948                    uidRec.lastBackgroundTime = 0;
19949                }
19950                uidRec.setProcState = uidRec.curProcState;
19951                enqueueUidChangeLocked(uidRec, -1, uidChange);
19952                mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
19953            }
19954        }
19955
19956        if (mProcessStats.shouldWriteNowLocked(now)) {
19957            mHandler.post(new Runnable() {
19958                @Override public void run() {
19959                    synchronized (ActivityManagerService.this) {
19960                        mProcessStats.writeStateAsyncLocked();
19961                    }
19962                }
19963            });
19964        }
19965
19966        if (DEBUG_OOM_ADJ) {
19967            final long duration = SystemClock.uptimeMillis() - now;
19968            if (false) {
19969                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19970                        new RuntimeException("here").fillInStackTrace());
19971            } else {
19972                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19973            }
19974        }
19975    }
19976
19977    final void idleUids() {
19978        synchronized (this) {
19979            final long nowElapsed = SystemClock.elapsedRealtime();
19980            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
19981            long nextTime = 0;
19982            for (int i=mActiveUids.size()-1; i>=0; i--) {
19983                final UidRecord uidRec = mActiveUids.valueAt(i);
19984                final long bgTime = uidRec.lastBackgroundTime;
19985                if (bgTime > 0 && !uidRec.idle) {
19986                    if (bgTime <= maxBgTime) {
19987                        uidRec.idle = true;
19988                        doStopUidLocked(uidRec.uid, uidRec);
19989                    } else {
19990                        if (nextTime == 0 || nextTime > bgTime) {
19991                            nextTime = bgTime;
19992                        }
19993                    }
19994                }
19995            }
19996            if (nextTime > 0) {
19997                mHandler.removeMessages(IDLE_UIDS_MSG);
19998                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
19999                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20000            }
20001        }
20002    }
20003
20004    final void runInBackgroundDisabled(int uid) {
20005        synchronized (this) {
20006            UidRecord uidRec = mActiveUids.get(uid);
20007            if (uidRec != null) {
20008                // This uid is actually running...  should it be considered background now?
20009                if (uidRec.idle) {
20010                    doStopUidLocked(uidRec.uid, uidRec);
20011                }
20012            } else {
20013                // This uid isn't actually running...  still send a report about it being "stopped".
20014                doStopUidLocked(uid, null);
20015            }
20016        }
20017    }
20018
20019    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20020        mServices.stopInBackgroundLocked(uid);
20021        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20022    }
20023
20024    final void trimApplications() {
20025        synchronized (this) {
20026            int i;
20027
20028            // First remove any unused application processes whose package
20029            // has been removed.
20030            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20031                final ProcessRecord app = mRemovedProcesses.get(i);
20032                if (app.activities.size() == 0
20033                        && app.curReceiver == null && app.services.size() == 0) {
20034                    Slog.i(
20035                        TAG, "Exiting empty application process "
20036                        + app.processName + " ("
20037                        + (app.thread != null ? app.thread.asBinder() : null)
20038                        + ")\n");
20039                    if (app.pid > 0 && app.pid != MY_PID) {
20040                        app.kill("empty", false);
20041                    } else {
20042                        try {
20043                            app.thread.scheduleExit();
20044                        } catch (Exception e) {
20045                            // Ignore exceptions.
20046                        }
20047                    }
20048                    cleanUpApplicationRecordLocked(app, false, true, -1);
20049                    mRemovedProcesses.remove(i);
20050
20051                    if (app.persistent) {
20052                        addAppLocked(app.info, false, null /* ABI override */);
20053                    }
20054                }
20055            }
20056
20057            // Now update the oom adj for all processes.
20058            updateOomAdjLocked();
20059        }
20060    }
20061
20062    /** This method sends the specified signal to each of the persistent apps */
20063    public void signalPersistentProcesses(int sig) throws RemoteException {
20064        if (sig != Process.SIGNAL_USR1) {
20065            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20066        }
20067
20068        synchronized (this) {
20069            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20070                    != PackageManager.PERMISSION_GRANTED) {
20071                throw new SecurityException("Requires permission "
20072                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20073            }
20074
20075            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20076                ProcessRecord r = mLruProcesses.get(i);
20077                if (r.thread != null && r.persistent) {
20078                    Process.sendSignal(r.pid, sig);
20079                }
20080            }
20081        }
20082    }
20083
20084    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20085        if (proc == null || proc == mProfileProc) {
20086            proc = mProfileProc;
20087            profileType = mProfileType;
20088            clearProfilerLocked();
20089        }
20090        if (proc == null) {
20091            return;
20092        }
20093        try {
20094            proc.thread.profilerControl(false, null, profileType);
20095        } catch (RemoteException e) {
20096            throw new IllegalStateException("Process disappeared");
20097        }
20098    }
20099
20100    private void clearProfilerLocked() {
20101        if (mProfileFd != null) {
20102            try {
20103                mProfileFd.close();
20104            } catch (IOException e) {
20105            }
20106        }
20107        mProfileApp = null;
20108        mProfileProc = null;
20109        mProfileFile = null;
20110        mProfileType = 0;
20111        mAutoStopProfiler = false;
20112        mSamplingInterval = 0;
20113    }
20114
20115    public boolean profileControl(String process, int userId, boolean start,
20116            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20117
20118        try {
20119            synchronized (this) {
20120                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20121                // its own permission.
20122                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20123                        != PackageManager.PERMISSION_GRANTED) {
20124                    throw new SecurityException("Requires permission "
20125                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20126                }
20127
20128                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20129                    throw new IllegalArgumentException("null profile info or fd");
20130                }
20131
20132                ProcessRecord proc = null;
20133                if (process != null) {
20134                    proc = findProcessLocked(process, userId, "profileControl");
20135                }
20136
20137                if (start && (proc == null || proc.thread == null)) {
20138                    throw new IllegalArgumentException("Unknown process: " + process);
20139                }
20140
20141                if (start) {
20142                    stopProfilerLocked(null, 0);
20143                    setProfileApp(proc.info, proc.processName, profilerInfo);
20144                    mProfileProc = proc;
20145                    mProfileType = profileType;
20146                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20147                    try {
20148                        fd = fd.dup();
20149                    } catch (IOException e) {
20150                        fd = null;
20151                    }
20152                    profilerInfo.profileFd = fd;
20153                    proc.thread.profilerControl(start, profilerInfo, profileType);
20154                    fd = null;
20155                    mProfileFd = null;
20156                } else {
20157                    stopProfilerLocked(proc, profileType);
20158                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20159                        try {
20160                            profilerInfo.profileFd.close();
20161                        } catch (IOException e) {
20162                        }
20163                    }
20164                }
20165
20166                return true;
20167            }
20168        } catch (RemoteException e) {
20169            throw new IllegalStateException("Process disappeared");
20170        } finally {
20171            if (profilerInfo != null && profilerInfo.profileFd != null) {
20172                try {
20173                    profilerInfo.profileFd.close();
20174                } catch (IOException e) {
20175                }
20176            }
20177        }
20178    }
20179
20180    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20181        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20182                userId, true, ALLOW_FULL_ONLY, callName, null);
20183        ProcessRecord proc = null;
20184        try {
20185            int pid = Integer.parseInt(process);
20186            synchronized (mPidsSelfLocked) {
20187                proc = mPidsSelfLocked.get(pid);
20188            }
20189        } catch (NumberFormatException e) {
20190        }
20191
20192        if (proc == null) {
20193            ArrayMap<String, SparseArray<ProcessRecord>> all
20194                    = mProcessNames.getMap();
20195            SparseArray<ProcessRecord> procs = all.get(process);
20196            if (procs != null && procs.size() > 0) {
20197                proc = procs.valueAt(0);
20198                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20199                    for (int i=1; i<procs.size(); i++) {
20200                        ProcessRecord thisProc = procs.valueAt(i);
20201                        if (thisProc.userId == userId) {
20202                            proc = thisProc;
20203                            break;
20204                        }
20205                    }
20206                }
20207            }
20208        }
20209
20210        return proc;
20211    }
20212
20213    public boolean dumpHeap(String process, int userId, boolean managed,
20214            String path, ParcelFileDescriptor fd) throws RemoteException {
20215
20216        try {
20217            synchronized (this) {
20218                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20219                // its own permission (same as profileControl).
20220                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20221                        != PackageManager.PERMISSION_GRANTED) {
20222                    throw new SecurityException("Requires permission "
20223                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20224                }
20225
20226                if (fd == null) {
20227                    throw new IllegalArgumentException("null fd");
20228                }
20229
20230                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20231                if (proc == null || proc.thread == null) {
20232                    throw new IllegalArgumentException("Unknown process: " + process);
20233                }
20234
20235                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20236                if (!isDebuggable) {
20237                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20238                        throw new SecurityException("Process not debuggable: " + proc);
20239                    }
20240                }
20241
20242                proc.thread.dumpHeap(managed, path, fd);
20243                fd = null;
20244                return true;
20245            }
20246        } catch (RemoteException e) {
20247            throw new IllegalStateException("Process disappeared");
20248        } finally {
20249            if (fd != null) {
20250                try {
20251                    fd.close();
20252                } catch (IOException e) {
20253                }
20254            }
20255        }
20256    }
20257
20258    @Override
20259    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20260            String reportPackage) {
20261        if (processName != null) {
20262            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20263                    "setDumpHeapDebugLimit()");
20264        } else {
20265            synchronized (mPidsSelfLocked) {
20266                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20267                if (proc == null) {
20268                    throw new SecurityException("No process found for calling pid "
20269                            + Binder.getCallingPid());
20270                }
20271                if (!Build.IS_DEBUGGABLE
20272                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20273                    throw new SecurityException("Not running a debuggable build");
20274                }
20275                processName = proc.processName;
20276                uid = proc.uid;
20277                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20278                    throw new SecurityException("Package " + reportPackage + " is not running in "
20279                            + proc);
20280                }
20281            }
20282        }
20283        synchronized (this) {
20284            if (maxMemSize > 0) {
20285                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20286            } else {
20287                if (uid != 0) {
20288                    mMemWatchProcesses.remove(processName, uid);
20289                } else {
20290                    mMemWatchProcesses.getMap().remove(processName);
20291                }
20292            }
20293        }
20294    }
20295
20296    @Override
20297    public void dumpHeapFinished(String path) {
20298        synchronized (this) {
20299            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20300                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20301                        + " does not match last pid " + mMemWatchDumpPid);
20302                return;
20303            }
20304            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20305                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20306                        + " does not match last path " + mMemWatchDumpFile);
20307                return;
20308            }
20309            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20310            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20311        }
20312    }
20313
20314    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20315    public void monitor() {
20316        synchronized (this) { }
20317    }
20318
20319    void onCoreSettingsChange(Bundle settings) {
20320        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20321            ProcessRecord processRecord = mLruProcesses.get(i);
20322            try {
20323                if (processRecord.thread != null) {
20324                    processRecord.thread.setCoreSettings(settings);
20325                }
20326            } catch (RemoteException re) {
20327                /* ignore */
20328            }
20329        }
20330    }
20331
20332    // Multi-user methods
20333
20334    /**
20335     * Start user, if its not already running, but don't bring it to foreground.
20336     */
20337    @Override
20338    public boolean startUserInBackground(final int userId) {
20339        return mUserController.startUser(userId, /* foreground */ false);
20340    }
20341
20342    @Override
20343    public boolean unlockUser(int userId, byte[] token) {
20344        return mUserController.unlockUser(userId, token);
20345    }
20346
20347    @Override
20348    public boolean switchUser(final int targetUserId) {
20349        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20350        UserInfo currentUserInfo;
20351        UserInfo targetUserInfo;
20352        synchronized (this) {
20353            int currentUserId = mUserController.getCurrentUserIdLocked();
20354            currentUserInfo = mUserController.getUserInfo(currentUserId);
20355            targetUserInfo = mUserController.getUserInfo(targetUserId);
20356            if (targetUserInfo == null) {
20357                Slog.w(TAG, "No user info for user #" + targetUserId);
20358                return false;
20359            }
20360            if (targetUserInfo.isManagedProfile()) {
20361                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20362                return false;
20363            }
20364            mUserController.setTargetUserIdLocked(targetUserId);
20365        }
20366        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20367        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20368        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20369        return true;
20370    }
20371
20372    void scheduleStartProfilesLocked() {
20373        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20374            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20375                    DateUtils.SECOND_IN_MILLIS);
20376        }
20377    }
20378
20379    @Override
20380    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20381        return mUserController.stopUser(userId, force, callback);
20382    }
20383
20384    @Override
20385    public UserInfo getCurrentUser() {
20386        return mUserController.getCurrentUser();
20387    }
20388
20389    @Override
20390    public boolean isUserRunning(int userId, int flags) {
20391        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20392                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20393            String msg = "Permission Denial: isUserRunning() from pid="
20394                    + Binder.getCallingPid()
20395                    + ", uid=" + Binder.getCallingUid()
20396                    + " requires " + INTERACT_ACROSS_USERS;
20397            Slog.w(TAG, msg);
20398            throw new SecurityException(msg);
20399        }
20400        synchronized (this) {
20401            return mUserController.isUserRunningLocked(userId, flags);
20402        }
20403    }
20404
20405    @Override
20406    public int[] getRunningUserIds() {
20407        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20408                != PackageManager.PERMISSION_GRANTED) {
20409            String msg = "Permission Denial: isUserRunning() from pid="
20410                    + Binder.getCallingPid()
20411                    + ", uid=" + Binder.getCallingUid()
20412                    + " requires " + INTERACT_ACROSS_USERS;
20413            Slog.w(TAG, msg);
20414            throw new SecurityException(msg);
20415        }
20416        synchronized (this) {
20417            return mUserController.getStartedUserArrayLocked();
20418        }
20419    }
20420
20421    @Override
20422    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20423        mUserController.registerUserSwitchObserver(observer);
20424    }
20425
20426    @Override
20427    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20428        mUserController.unregisterUserSwitchObserver(observer);
20429    }
20430
20431    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20432        if (info == null) return null;
20433        ApplicationInfo newInfo = new ApplicationInfo(info);
20434        newInfo.initForUser(userId);
20435        return newInfo;
20436    }
20437
20438    public boolean isUserStopped(int userId) {
20439        synchronized (this) {
20440            return mUserController.getStartedUserStateLocked(userId) == null;
20441        }
20442    }
20443
20444    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20445        if (aInfo == null
20446                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20447            return aInfo;
20448        }
20449
20450        ActivityInfo info = new ActivityInfo(aInfo);
20451        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20452        return info;
20453    }
20454
20455    private boolean processSanityChecksLocked(ProcessRecord process) {
20456        if (process == null || process.thread == null) {
20457            return false;
20458        }
20459
20460        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20461        if (!isDebuggable) {
20462            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20463                return false;
20464            }
20465        }
20466
20467        return true;
20468    }
20469
20470    public boolean startBinderTracking() throws RemoteException {
20471        synchronized (this) {
20472            mBinderTransactionTrackingEnabled = true;
20473            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20474            // permission (same as profileControl).
20475            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20476                    != PackageManager.PERMISSION_GRANTED) {
20477                throw new SecurityException("Requires permission "
20478                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20479            }
20480
20481            for (int i = 0; i < mLruProcesses.size(); i++) {
20482                ProcessRecord process = mLruProcesses.get(i);
20483                if (!processSanityChecksLocked(process)) {
20484                    continue;
20485                }
20486                try {
20487                    process.thread.startBinderTracking();
20488                } catch (RemoteException e) {
20489                    Log.v(TAG, "Process disappared");
20490                }
20491            }
20492            return true;
20493        }
20494    }
20495
20496    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20497        try {
20498            synchronized (this) {
20499                mBinderTransactionTrackingEnabled = false;
20500                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20501                // permission (same as profileControl).
20502                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20503                        != PackageManager.PERMISSION_GRANTED) {
20504                    throw new SecurityException("Requires permission "
20505                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20506                }
20507
20508                if (fd == null) {
20509                    throw new IllegalArgumentException("null fd");
20510                }
20511
20512                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20513                pw.println("Binder transaction traces for all processes.\n");
20514                for (ProcessRecord process : mLruProcesses) {
20515                    if (!processSanityChecksLocked(process)) {
20516                        continue;
20517                    }
20518
20519                    pw.println("Traces for process: " + process.processName);
20520                    pw.flush();
20521                    try {
20522                        TransferPipe tp = new TransferPipe();
20523                        try {
20524                            process.thread.stopBinderTrackingAndDump(
20525                                    tp.getWriteFd().getFileDescriptor());
20526                            tp.go(fd.getFileDescriptor());
20527                        } finally {
20528                            tp.kill();
20529                        }
20530                    } catch (IOException e) {
20531                        pw.println("Failure while dumping IPC traces from " + process +
20532                                ".  Exception: " + e);
20533                        pw.flush();
20534                    } catch (RemoteException e) {
20535                        pw.println("Got a RemoteException while dumping IPC traces from " +
20536                                process + ".  Exception: " + e);
20537                        pw.flush();
20538                    }
20539                }
20540                fd = null;
20541                return true;
20542            }
20543        } finally {
20544            if (fd != null) {
20545                try {
20546                    fd.close();
20547                } catch (IOException e) {
20548                }
20549            }
20550        }
20551    }
20552
20553    private final class LocalService extends ActivityManagerInternal {
20554        @Override
20555        public void onWakefulnessChanged(int wakefulness) {
20556            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20557        }
20558
20559        @Override
20560        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20561                String processName, String abiOverride, int uid, Runnable crashHandler) {
20562            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20563                    processName, abiOverride, uid, crashHandler);
20564        }
20565
20566        @Override
20567        public SleepToken acquireSleepToken(String tag) {
20568            Preconditions.checkNotNull(tag);
20569
20570            synchronized (ActivityManagerService.this) {
20571                SleepTokenImpl token = new SleepTokenImpl(tag);
20572                mSleepTokens.add(token);
20573                updateSleepIfNeededLocked();
20574                return token;
20575            }
20576        }
20577
20578        @Override
20579        public ComponentName getHomeActivityForUser(int userId) {
20580            synchronized (ActivityManagerService.this) {
20581                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20582                return homeActivity == null ? null : homeActivity.realActivity;
20583            }
20584        }
20585
20586        @Override
20587        public void onUserRemoved(int userId) {
20588            synchronized (ActivityManagerService.this) {
20589                ActivityManagerService.this.onUserStoppedLocked(userId);
20590            }
20591        }
20592
20593        @Override
20594        public void onLocalVoiceInteractionStarted(IBinder activity,
20595                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20596            synchronized (ActivityManagerService.this) {
20597                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20598                        voiceSession, voiceInteractor);
20599            }
20600        }
20601    }
20602
20603    private final class SleepTokenImpl extends SleepToken {
20604        private final String mTag;
20605        private final long mAcquireTime;
20606
20607        public SleepTokenImpl(String tag) {
20608            mTag = tag;
20609            mAcquireTime = SystemClock.uptimeMillis();
20610        }
20611
20612        @Override
20613        public void release() {
20614            synchronized (ActivityManagerService.this) {
20615                if (mSleepTokens.remove(this)) {
20616                    updateSleepIfNeededLocked();
20617                }
20618            }
20619        }
20620
20621        @Override
20622        public String toString() {
20623            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20624        }
20625    }
20626
20627    /**
20628     * An implementation of IAppTask, that allows an app to manage its own tasks via
20629     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
20630     * only the process that calls getAppTasks() can call the AppTask methods.
20631     */
20632    class AppTaskImpl extends IAppTask.Stub {
20633        private int mTaskId;
20634        private int mCallingUid;
20635
20636        public AppTaskImpl(int taskId, int callingUid) {
20637            mTaskId = taskId;
20638            mCallingUid = callingUid;
20639        }
20640
20641        private void checkCaller() {
20642            if (mCallingUid != Binder.getCallingUid()) {
20643                throw new SecurityException("Caller " + mCallingUid
20644                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20645            }
20646        }
20647
20648        @Override
20649        public void finishAndRemoveTask() {
20650            checkCaller();
20651
20652            synchronized (ActivityManagerService.this) {
20653                long origId = Binder.clearCallingIdentity();
20654                try {
20655                    // We remove the task from recents to preserve backwards
20656                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20657                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20658                    }
20659                } finally {
20660                    Binder.restoreCallingIdentity(origId);
20661                }
20662            }
20663        }
20664
20665        @Override
20666        public ActivityManager.RecentTaskInfo getTaskInfo() {
20667            checkCaller();
20668
20669            synchronized (ActivityManagerService.this) {
20670                long origId = Binder.clearCallingIdentity();
20671                try {
20672                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20673                    if (tr == null) {
20674                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20675                    }
20676                    return createRecentTaskInfoFromTaskRecord(tr);
20677                } finally {
20678                    Binder.restoreCallingIdentity(origId);
20679                }
20680            }
20681        }
20682
20683        @Override
20684        public void moveToFront() {
20685            checkCaller();
20686            // Will bring task to front if it already has a root activity.
20687            final long origId = Binder.clearCallingIdentity();
20688            try {
20689                startActivityFromRecentsInner(mTaskId, null);
20690            } finally {
20691                Binder.restoreCallingIdentity(origId);
20692            }
20693        }
20694
20695        @Override
20696        public int startActivity(IBinder whoThread, String callingPackage,
20697                Intent intent, String resolvedType, Bundle bOptions) {
20698            checkCaller();
20699
20700            int callingUser = UserHandle.getCallingUserId();
20701            TaskRecord tr;
20702            IApplicationThread appThread;
20703            synchronized (ActivityManagerService.this) {
20704                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20705                if (tr == null) {
20706                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20707                }
20708                appThread = ApplicationThreadNative.asInterface(whoThread);
20709                if (appThread == null) {
20710                    throw new IllegalArgumentException("Bad app thread " + appThread);
20711                }
20712            }
20713            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
20714                    resolvedType, null, null, null, null, 0, 0, null, null,
20715                    null, bOptions, false, callingUser, null, tr);
20716        }
20717
20718        @Override
20719        public void setExcludeFromRecents(boolean exclude) {
20720            checkCaller();
20721
20722            synchronized (ActivityManagerService.this) {
20723                long origId = Binder.clearCallingIdentity();
20724                try {
20725                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20726                    if (tr == null) {
20727                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20728                    }
20729                    Intent intent = tr.getBaseIntent();
20730                    if (exclude) {
20731                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20732                    } else {
20733                        intent.setFlags(intent.getFlags()
20734                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20735                    }
20736                } finally {
20737                    Binder.restoreCallingIdentity(origId);
20738                }
20739            }
20740        }
20741    }
20742
20743    /**
20744     * Kill processes for the user with id userId and that depend on the package named packageName
20745     */
20746    @Override
20747    public void killPackageDependents(String packageName, int userId) {
20748        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
20749        if (packageName == null) {
20750            throw new NullPointerException(
20751                    "Cannot kill the dependents of a package without its name.");
20752        }
20753
20754        long callingId = Binder.clearCallingIdentity();
20755        IPackageManager pm = AppGlobals.getPackageManager();
20756        int pkgUid = -1;
20757        try {
20758            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
20759        } catch (RemoteException e) {
20760        }
20761        if (pkgUid == -1) {
20762            throw new IllegalArgumentException(
20763                    "Cannot kill dependents of non-existing package " + packageName);
20764        }
20765        try {
20766            synchronized(this) {
20767                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
20768                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
20769                        "dep: " + packageName);
20770            }
20771        } finally {
20772            Binder.restoreCallingIdentity(callingId);
20773        }
20774    }
20775}
20776