ActivityManagerService.java revision 9540ca4fc47ac5448826c43912aa573caecc746c
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.google.android.collect.Lists;
20import com.google.android.collect.Maps;
21import com.android.internal.R;
22import com.android.internal.annotations.GuardedBy;
23import com.android.internal.app.AssistUtils;
24import com.android.internal.app.DumpHeapActivity;
25import com.android.internal.app.IAppOpsCallback;
26import com.android.internal.app.IAppOpsService;
27import com.android.internal.app.IVoiceInteractor;
28import com.android.internal.app.ProcessMap;
29import com.android.internal.app.SystemUserHomeActivity;
30import com.android.internal.app.procstats.ProcessStats;
31import com.android.internal.os.BackgroundThread;
32import com.android.internal.os.BatteryStatsImpl;
33import com.android.internal.os.IResultReceiver;
34import com.android.internal.os.ProcessCpuTracker;
35import com.android.internal.os.TransferPipe;
36import com.android.internal.os.Zygote;
37import com.android.internal.os.InstallerConnection.InstallerException;
38import com.android.internal.util.ArrayUtils;
39import com.android.internal.util.FastPrintWriter;
40import com.android.internal.util.FastXmlSerializer;
41import com.android.internal.util.MemInfoReader;
42import com.android.internal.util.Preconditions;
43import com.android.internal.util.ProgressReporter;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.KeyguardManager;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.ProfilerInfo;
105import android.app.admin.DevicePolicyManager;
106import android.app.admin.DevicePolicyManagerInternal;
107import android.app.assist.AssistContent;
108import android.app.assist.AssistStructure;
109import android.app.backup.IBackupManager;
110import android.app.usage.UsageEvents;
111import android.app.usage.UsageStatsManagerInternal;
112import android.appwidget.AppWidgetManager;
113import android.content.ActivityNotFoundException;
114import android.content.BroadcastReceiver;
115import android.content.ClipData;
116import android.content.ComponentCallbacks2;
117import android.content.ComponentName;
118import android.content.ContentProvider;
119import android.content.ContentResolver;
120import android.content.Context;
121import android.content.DialogInterface;
122import android.content.IContentProvider;
123import android.content.IIntentReceiver;
124import android.content.IIntentSender;
125import android.content.Intent;
126import android.content.IntentFilter;
127import android.content.IntentSender;
128import android.content.pm.ActivityInfo;
129import android.content.pm.ApplicationInfo;
130import android.content.pm.ConfigurationInfo;
131import android.content.pm.IPackageDataObserver;
132import android.content.pm.IPackageManager;
133import android.content.pm.InstrumentationInfo;
134import android.content.pm.PackageInfo;
135import android.content.pm.PackageManager;
136import android.content.pm.PackageManager.NameNotFoundException;
137import android.content.pm.PackageManagerInternal;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.PathPermission;
140import android.content.pm.PermissionInfo;
141import android.content.pm.ProviderInfo;
142import android.content.pm.ResolveInfo;
143import android.content.pm.ServiceInfo;
144import android.content.pm.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.PersistableBundle;
176import android.os.PowerManager;
177import android.os.PowerManagerInternal;
178import android.os.Process;
179import android.os.RemoteCallbackList;
180import android.os.RemoteException;
181import android.os.ResultReceiver;
182import android.os.ServiceManager;
183import android.os.StrictMode;
184import android.os.SystemClock;
185import android.os.SystemProperties;
186import android.os.Trace;
187import android.os.TransactionTooLargeException;
188import android.os.UpdateLock;
189import android.os.UserHandle;
190import android.os.UserManager;
191import android.os.WorkSource;
192import android.os.storage.IMountService;
193import android.os.storage.MountServiceInternal;
194import android.os.storage.StorageManager;
195import android.provider.Settings;
196import android.service.voice.IVoiceInteractionSession;
197import android.service.voice.VoiceInteractionManagerInternal;
198import android.service.voice.VoiceInteractionSession;
199import android.text.format.DateUtils;
200import android.text.format.Time;
201import android.util.ArrayMap;
202import android.util.ArraySet;
203import android.util.AtomicFile;
204import android.util.DebugUtils;
205import android.util.EventLog;
206import android.util.LocaleList;
207import android.util.Log;
208import android.util.Pair;
209import android.util.PrintWriterPrinter;
210import android.util.Slog;
211import android.util.SparseArray;
212import android.util.TimeUtils;
213import android.util.Xml;
214import android.view.Display;
215import android.view.Gravity;
216import android.view.LayoutInflater;
217import android.view.View;
218import android.view.WindowManager;
219
220import java.io.File;
221import java.io.FileDescriptor;
222import java.io.FileInputStream;
223import java.io.FileNotFoundException;
224import java.io.FileOutputStream;
225import java.io.IOException;
226import java.io.InputStreamReader;
227import java.io.PrintWriter;
228import java.io.StringWriter;
229import java.lang.ref.WeakReference;
230import java.nio.charset.StandardCharsets;
231import java.util.ArrayList;
232import java.util.Arrays;
233import java.util.Collections;
234import java.util.Comparator;
235import java.util.HashMap;
236import java.util.HashSet;
237import java.util.Iterator;
238import java.util.List;
239import java.util.Locale;
240import java.util.Map;
241import java.util.Set;
242import java.util.concurrent.atomic.AtomicBoolean;
243import java.util.concurrent.atomic.AtomicLong;
244
245import dalvik.system.VMRuntime;
246
247import libcore.io.IoUtils;
248import libcore.util.EmptyArray;
249
250import static android.Manifest.permission.INTERACT_ACROSS_USERS;
251import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
252import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
253import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
254import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
255import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
256import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
257import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
258import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
259import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
260import static android.app.ActivityManager.StackId.HOME_STACK_ID;
261import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
262import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
263import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
264import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
265import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
266import static android.content.pm.PackageManager.GET_PROVIDERS;
267import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
268import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
269import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
270import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
271import static android.content.pm.PackageManager.PERMISSION_GRANTED;
272import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
273import static android.provider.Settings.Global.DEBUG_APP;
274import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
275import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
276import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
277import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
278import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
279import static android.provider.Settings.System.FONT_SCALE;
280import static com.android.internal.util.XmlUtils.readBooleanAttribute;
281import static com.android.internal.util.XmlUtils.readIntAttribute;
282import static com.android.internal.util.XmlUtils.readLongAttribute;
283import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
284import static com.android.internal.util.XmlUtils.writeIntAttribute;
285import static com.android.internal.util.XmlUtils.writeLongAttribute;
286import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
318import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
342import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
343import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
344import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
345import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
346import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
347import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
348import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
349import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
350import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
351import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
352import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
353import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
354import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
355import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
356import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
357import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
358import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
359import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
360import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
361import static org.xmlpull.v1.XmlPullParser.START_TAG;
362
363public final class ActivityManagerService extends ActivityManagerNative
364        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
365
366    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
367    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
368    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
369    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
370    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
371    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
372    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
373    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
374    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
375    private static final String TAG_LRU = TAG + POSTFIX_LRU;
376    private static final String TAG_MU = TAG + POSTFIX_MU;
377    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
378    private static final String TAG_POWER = TAG + POSTFIX_POWER;
379    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
380    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
381    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
382    private static final String TAG_PSS = TAG + POSTFIX_PSS;
383    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
384    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
385    private static final String TAG_STACK = TAG + POSTFIX_STACK;
386    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
387    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
388    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
389    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
390    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
391
392    /** Control over CPU and battery monitoring */
393    // write battery stats every 30 minutes.
394    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
395    static final boolean MONITOR_CPU_USAGE = true;
396    // don't sample cpu less than every 5 seconds.
397    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
398    // wait possibly forever for next cpu sample.
399    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
400    static final boolean MONITOR_THREAD_CPU_USAGE = false;
401
402    // The flags that are set for all calls we make to the package manager.
403    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
404
405    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
406
407    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
408
409    // Amount of time after a call to stopAppSwitches() during which we will
410    // prevent further untrusted switches from happening.
411    static final long APP_SWITCH_DELAY_TIME = 5*1000;
412
413    // How long we wait for a launched process to attach to the activity manager
414    // before we decide it's never going to come up for real.
415    static final int PROC_START_TIMEOUT = 10*1000;
416    // How long we wait for an attached process to publish its content providers
417    // before we decide it must be hung.
418    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
419
420    // How long we will retain processes hosting content providers in the "last activity"
421    // state before allowing them to drop down to the regular cached LRU list.  This is
422    // to avoid thrashing of provider processes under low memory situations.
423    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
424
425    // How long we wait for a launched process to attach to the activity manager
426    // before we decide it's never going to come up for real, when the process was
427    // started with a wrapper for instrumentation (such as Valgrind) because it
428    // could take much longer than usual.
429    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
430
431    // How long to wait after going idle before forcing apps to GC.
432    static final int GC_TIMEOUT = 5*1000;
433
434    // The minimum amount of time between successive GC requests for a process.
435    static final int GC_MIN_INTERVAL = 60*1000;
436
437    // The minimum amount of time between successive PSS requests for a process.
438    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
439
440    // The minimum amount of time between successive PSS requests for a process
441    // when the request is due to the memory state being lowered.
442    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
443
444    // The rate at which we check for apps using excessive power -- 15 mins.
445    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
446
447    // The minimum sample duration we will allow before deciding we have
448    // enough data on wake locks to start killing things.
449    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
450
451    // The minimum sample duration we will allow before deciding we have
452    // enough data on CPU usage to start killing things.
453    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
454
455    // How long we allow a receiver to run before giving up on it.
456    static final int BROADCAST_FG_TIMEOUT = 10*1000;
457    static final int BROADCAST_BG_TIMEOUT = 60*1000;
458
459    // How long we wait until we timeout on key dispatching.
460    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
461
462    // How long we wait until we timeout on key dispatching during instrumentation.
463    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
464
465    // This is the amount of time an app needs to be running a foreground service before
466    // we will consider it to be doing interaction for usage stats.
467    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
468
469    // Maximum amount of time we will allow to elapse before re-reporting usage stats
470    // interaction with foreground processes.
471    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
472
473    // This is the amount of time we allow an app to settle after it goes into the background,
474    // before we start restricting what it can do.
475    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
476
477    // How long to wait in getAssistContextExtras for the activity and foreground services
478    // to respond with the result.
479    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
480
481    // How long top wait when going through the modern assist (which doesn't need to block
482    // on getting this result before starting to launch its UI).
483    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
484
485    // Maximum number of persisted Uri grants a package is allowed
486    static final int MAX_PERSISTED_URI_GRANTS = 128;
487
488    static final int MY_PID = Process.myPid();
489
490    static final String[] EMPTY_STRING_ARRAY = new String[0];
491
492    // How many bytes to write into the dropbox log before truncating
493    static final int DROPBOX_MAX_SIZE = 256 * 1024;
494
495    // Access modes for handleIncomingUser.
496    static final int ALLOW_NON_FULL = 0;
497    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
498    static final int ALLOW_FULL_ONLY = 2;
499
500    // Delay in notifying task stack change listeners (in millis)
501    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
502
503    // Necessary ApplicationInfo flags to mark an app as persistent
504    private static final int PERSISTENT_MASK =
505            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
506
507    // Intent sent when remote bugreport collection has been completed
508    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
509            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
510
511    // Delay to disable app launch boost
512    static final int APP_BOOST_MESSAGE_DELAY = 3000;
513    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
514    static final int APP_BOOST_TIMEOUT = 2500;
515
516    // Used to indicate that a task is removed it should also be removed from recents.
517    private static final boolean REMOVE_FROM_RECENTS = true;
518    // Used to indicate that an app transition should be animated.
519    static final boolean ANIMATE = true;
520
521    // Determines whether to take full screen screenshots
522    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
523    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
524
525    private static native int nativeMigrateToBoost();
526    private static native int nativeMigrateFromBoost();
527    private boolean mIsBoosted = false;
528    private long mBoostStartTime = 0;
529
530    /** All system services */
531    SystemServiceManager mSystemServiceManager;
532
533    private Installer mInstaller;
534
535    /** Run all ActivityStacks through this */
536    final ActivityStackSupervisor mStackSupervisor;
537
538    final ActivityStarter mActivityStarter;
539
540    /** Task stack change listeners. */
541    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
542            new RemoteCallbackList<ITaskStackListener>();
543
544    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
545
546    public IntentFirewall mIntentFirewall;
547
548    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
549    // default actuion automatically.  Important for devices without direct input
550    // devices.
551    private boolean mShowDialogs = true;
552    private boolean mInVrMode = false;
553
554    BroadcastQueue mFgBroadcastQueue;
555    BroadcastQueue mBgBroadcastQueue;
556    // Convenient for easy iteration over the queues. Foreground is first
557    // so that dispatch of foreground broadcasts gets precedence.
558    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
559
560    BroadcastQueue broadcastQueueForIntent(Intent intent) {
561        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
562        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
563                "Broadcast intent " + intent + " on "
564                + (isFg ? "foreground" : "background") + " queue");
565        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
566    }
567
568    /**
569     * Activity we have told the window manager to have key focus.
570     */
571    ActivityRecord mFocusedActivity = null;
572
573    /**
574     * User id of the last activity mFocusedActivity was set to.
575     */
576    private int mLastFocusedUserId;
577
578    /**
579     * If non-null, we are tracking the time the user spends in the currently focused app.
580     */
581    private AppTimeTracker mCurAppTimeTracker;
582
583    /**
584     * List of intents that were used to start the most recent tasks.
585     */
586    final RecentTasks mRecentTasks;
587
588    /**
589     * For addAppTask: cached of the last activity component that was added.
590     */
591    ComponentName mLastAddedTaskComponent;
592
593    /**
594     * For addAppTask: cached of the last activity uid that was added.
595     */
596    int mLastAddedTaskUid;
597
598    /**
599     * For addAppTask: cached of the last ActivityInfo that was added.
600     */
601    ActivityInfo mLastAddedTaskActivity;
602
603    /**
604     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
605     */
606    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
607
608    /**
609     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
610     */
611    String mDeviceOwnerName;
612
613    final UserController mUserController;
614
615    final AppErrors mAppErrors;
616
617    boolean mDoingSetFocusedActivity;
618
619    public boolean canShowErrorDialogs() {
620        return mShowDialogs && !mSleeping && !mShuttingDown;
621    }
622
623    public class PendingAssistExtras extends Binder implements Runnable {
624        public final ActivityRecord activity;
625        public final Bundle extras;
626        public final Intent intent;
627        public final String hint;
628        public final IResultReceiver receiver;
629        public final int userHandle;
630        public boolean haveResult = false;
631        public Bundle result = null;
632        public AssistStructure structure = null;
633        public AssistContent content = null;
634        public Bundle receiverExtras;
635
636        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
637                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
638            activity = _activity;
639            extras = _extras;
640            intent = _intent;
641            hint = _hint;
642            receiver = _receiver;
643            receiverExtras = _receiverExtras;
644            userHandle = _userHandle;
645        }
646        @Override
647        public void run() {
648            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
649            synchronized (this) {
650                haveResult = true;
651                notifyAll();
652            }
653            pendingAssistExtrasTimedOut(this);
654        }
655    }
656
657    final ArrayList<PendingAssistExtras> mPendingAssistExtras
658            = new ArrayList<PendingAssistExtras>();
659
660    /**
661     * Process management.
662     */
663    final ProcessList mProcessList = new ProcessList();
664
665    /**
666     * All of the applications we currently have running organized by name.
667     * The keys are strings of the application package name (as
668     * returned by the package manager), and the keys are ApplicationRecord
669     * objects.
670     */
671    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
672
673    /**
674     * Tracking long-term execution of processes to look for abuse and other
675     * bad app behavior.
676     */
677    final ProcessStatsService mProcessStats;
678
679    /**
680     * The currently running isolated processes.
681     */
682    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
683
684    /**
685     * Counter for assigning isolated process uids, to avoid frequently reusing the
686     * same ones.
687     */
688    int mNextIsolatedProcessUid = 0;
689
690    /**
691     * The currently running heavy-weight process, if any.
692     */
693    ProcessRecord mHeavyWeightProcess = null;
694
695    /**
696     * All of the processes we currently have running organized by pid.
697     * The keys are the pid running the application.
698     *
699     * <p>NOTE: This object is protected by its own lock, NOT the global
700     * activity manager lock!
701     */
702    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
703
704    /**
705     * All of the processes that have been forced to be foreground.  The key
706     * is the pid of the caller who requested it (we hold a death
707     * link on it).
708     */
709    abstract class ForegroundToken implements IBinder.DeathRecipient {
710        int pid;
711        IBinder token;
712    }
713    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
714
715    /**
716     * List of records for processes that someone had tried to start before the
717     * system was ready.  We don't start them at that point, but ensure they
718     * are started by the time booting is complete.
719     */
720    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
721
722    /**
723     * List of persistent applications that are in the process
724     * of being started.
725     */
726    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
727
728    /**
729     * Processes that are being forcibly torn down.
730     */
731    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
732
733    /**
734     * List of running applications, sorted by recent usage.
735     * The first entry in the list is the least recently used.
736     */
737    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
738
739    /**
740     * Where in mLruProcesses that the processes hosting activities start.
741     */
742    int mLruProcessActivityStart = 0;
743
744    /**
745     * Where in mLruProcesses that the processes hosting services start.
746     * This is after (lower index) than mLruProcessesActivityStart.
747     */
748    int mLruProcessServiceStart = 0;
749
750    /**
751     * List of processes that should gc as soon as things are idle.
752     */
753    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
754
755    /**
756     * Processes we want to collect PSS data from.
757     */
758    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
759
760    private boolean mBinderTransactionTrackingEnabled = false;
761
762    /**
763     * Last time we requested PSS data of all processes.
764     */
765    long mLastFullPssTime = SystemClock.uptimeMillis();
766
767    /**
768     * If set, the next time we collect PSS data we should do a full collection
769     * with data from native processes and the kernel.
770     */
771    boolean mFullPssPending = false;
772
773    /**
774     * This is the process holding what we currently consider to be
775     * the "home" activity.
776     */
777    ProcessRecord mHomeProcess;
778
779    /**
780     * This is the process holding the activity the user last visited that
781     * is in a different process from the one they are currently in.
782     */
783    ProcessRecord mPreviousProcess;
784
785    /**
786     * The time at which the previous process was last visible.
787     */
788    long mPreviousProcessVisibleTime;
789
790    /**
791     * Track all uids that have actively running processes.
792     */
793    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
794
795    /**
796     * This is for verifying the UID report flow.
797     */
798    static final boolean VALIDATE_UID_STATES = true;
799    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
800
801    /**
802     * Packages that the user has asked to have run in screen size
803     * compatibility mode instead of filling the screen.
804     */
805    final CompatModePackages mCompatModePackages;
806
807    /**
808     * Set of IntentSenderRecord objects that are currently active.
809     */
810    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
811            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
812
813    /**
814     * Fingerprints (hashCode()) of stack traces that we've
815     * already logged DropBox entries for.  Guarded by itself.  If
816     * something (rogue user app) forces this over
817     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
818     */
819    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
820    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
821
822    /**
823     * Strict Mode background batched logging state.
824     *
825     * The string buffer is guarded by itself, and its lock is also
826     * used to determine if another batched write is already
827     * in-flight.
828     */
829    private final StringBuilder mStrictModeBuffer = new StringBuilder();
830
831    /**
832     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
833     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
834     */
835    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
836
837    /**
838     * Resolver for broadcast intents to registered receivers.
839     * Holds BroadcastFilter (subclass of IntentFilter).
840     */
841    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
842            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
843        @Override
844        protected boolean allowFilterResult(
845                BroadcastFilter filter, List<BroadcastFilter> dest) {
846            IBinder target = filter.receiverList.receiver.asBinder();
847            for (int i = dest.size() - 1; i >= 0; i--) {
848                if (dest.get(i).receiverList.receiver.asBinder() == target) {
849                    return false;
850                }
851            }
852            return true;
853        }
854
855        @Override
856        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
857            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
858                    || userId == filter.owningUserId) {
859                return super.newResult(filter, match, userId);
860            }
861            return null;
862        }
863
864        @Override
865        protected BroadcastFilter[] newArray(int size) {
866            return new BroadcastFilter[size];
867        }
868
869        @Override
870        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
871            return packageName.equals(filter.packageName);
872        }
873    };
874
875    /**
876     * State of all active sticky broadcasts per user.  Keys are the action of the
877     * sticky Intent, values are an ArrayList of all broadcasted intents with
878     * that action (which should usually be one).  The SparseArray is keyed
879     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
880     * for stickies that are sent to all users.
881     */
882    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
883            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
884
885    final ActiveServices mServices;
886
887    final static class Association {
888        final int mSourceUid;
889        final String mSourceProcess;
890        final int mTargetUid;
891        final ComponentName mTargetComponent;
892        final String mTargetProcess;
893
894        int mCount;
895        long mTime;
896
897        int mNesting;
898        long mStartTime;
899
900        // states of the source process when the bind occurred.
901        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
902        long mLastStateUptime;
903        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
904                - ActivityManager.MIN_PROCESS_STATE+1];
905
906        Association(int sourceUid, String sourceProcess, int targetUid,
907                ComponentName targetComponent, String targetProcess) {
908            mSourceUid = sourceUid;
909            mSourceProcess = sourceProcess;
910            mTargetUid = targetUid;
911            mTargetComponent = targetComponent;
912            mTargetProcess = targetProcess;
913        }
914    }
915
916    /**
917     * When service association tracking is enabled, this is all of the associations we
918     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
919     * -> association data.
920     */
921    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
922            mAssociations = new SparseArray<>();
923    boolean mTrackingAssociations;
924
925    /**
926     * Backup/restore process management
927     */
928    String mBackupAppName = null;
929    BackupRecord mBackupTarget = null;
930
931    final ProviderMap mProviderMap;
932
933    /**
934     * List of content providers who have clients waiting for them.  The
935     * application is currently being launched and the provider will be
936     * removed from this list once it is published.
937     */
938    final ArrayList<ContentProviderRecord> mLaunchingProviders
939            = new ArrayList<ContentProviderRecord>();
940
941    /**
942     * File storing persisted {@link #mGrantedUriPermissions}.
943     */
944    private final AtomicFile mGrantFile;
945
946    /** XML constants used in {@link #mGrantFile} */
947    private static final String TAG_URI_GRANTS = "uri-grants";
948    private static final String TAG_URI_GRANT = "uri-grant";
949    private static final String ATTR_USER_HANDLE = "userHandle";
950    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
951    private static final String ATTR_TARGET_USER_ID = "targetUserId";
952    private static final String ATTR_SOURCE_PKG = "sourcePkg";
953    private static final String ATTR_TARGET_PKG = "targetPkg";
954    private static final String ATTR_URI = "uri";
955    private static final String ATTR_MODE_FLAGS = "modeFlags";
956    private static final String ATTR_CREATED_TIME = "createdTime";
957    private static final String ATTR_PREFIX = "prefix";
958
959    /**
960     * Global set of specific {@link Uri} permissions that have been granted.
961     * This optimized lookup structure maps from {@link UriPermission#targetUid}
962     * to {@link UriPermission#uri} to {@link UriPermission}.
963     */
964    @GuardedBy("this")
965    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
966            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
967
968    public static class GrantUri {
969        public final int sourceUserId;
970        public final Uri uri;
971        public boolean prefix;
972
973        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
974            this.sourceUserId = sourceUserId;
975            this.uri = uri;
976            this.prefix = prefix;
977        }
978
979        @Override
980        public int hashCode() {
981            int hashCode = 1;
982            hashCode = 31 * hashCode + sourceUserId;
983            hashCode = 31 * hashCode + uri.hashCode();
984            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
985            return hashCode;
986        }
987
988        @Override
989        public boolean equals(Object o) {
990            if (o instanceof GrantUri) {
991                GrantUri other = (GrantUri) o;
992                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
993                        && prefix == other.prefix;
994            }
995            return false;
996        }
997
998        @Override
999        public String toString() {
1000            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1001            if (prefix) result += " [prefix]";
1002            return result;
1003        }
1004
1005        public String toSafeString() {
1006            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1007            if (prefix) result += " [prefix]";
1008            return result;
1009        }
1010
1011        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1012            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1013                    ContentProvider.getUriWithoutUserId(uri), false);
1014        }
1015    }
1016
1017    CoreSettingsObserver mCoreSettingsObserver;
1018
1019    FontScaleSettingObserver mFontScaleSettingObserver;
1020
1021    private final class FontScaleSettingObserver extends ContentObserver {
1022        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1023
1024        public FontScaleSettingObserver() {
1025            super(mHandler);
1026            ContentResolver resolver = mContext.getContentResolver();
1027            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1028        }
1029
1030        @Override
1031        public void onChange(boolean selfChange, Uri uri) {
1032            if (mFontScaleUri.equals(uri)) {
1033                updateFontScaleIfNeeded();
1034            }
1035        }
1036    }
1037
1038    /**
1039     * Thread-local storage used to carry caller permissions over through
1040     * indirect content-provider access.
1041     */
1042    private class Identity {
1043        public final IBinder token;
1044        public final int pid;
1045        public final int uid;
1046
1047        Identity(IBinder _token, int _pid, int _uid) {
1048            token = _token;
1049            pid = _pid;
1050            uid = _uid;
1051        }
1052    }
1053
1054    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1055
1056    /**
1057     * All information we have collected about the runtime performance of
1058     * any user id that can impact battery performance.
1059     */
1060    final BatteryStatsService mBatteryStatsService;
1061
1062    /**
1063     * Information about component usage
1064     */
1065    UsageStatsManagerInternal mUsageStatsService;
1066
1067    /**
1068     * Access to DeviceIdleController service.
1069     */
1070    DeviceIdleController.LocalService mLocalDeviceIdleController;
1071
1072    /**
1073     * Information about and control over application operations
1074     */
1075    final AppOpsService mAppOpsService;
1076
1077    /**
1078     * Current configuration information.  HistoryRecord objects are given
1079     * a reference to this object to indicate which configuration they are
1080     * currently running in, so this object must be kept immutable.
1081     */
1082    Configuration mConfiguration = new Configuration();
1083
1084    /**
1085     * Current sequencing integer of the configuration, for skipping old
1086     * configurations.
1087     */
1088    int mConfigurationSeq = 0;
1089
1090    boolean mSuppressResizeConfigChanges = false;
1091
1092    /**
1093     * Hardware-reported OpenGLES version.
1094     */
1095    final int GL_ES_VERSION;
1096
1097    /**
1098     * List of initialization arguments to pass to all processes when binding applications to them.
1099     * For example, references to the commonly used services.
1100     */
1101    HashMap<String, IBinder> mAppBindArgs;
1102
1103    /**
1104     * Temporary to avoid allocations.  Protected by main lock.
1105     */
1106    final StringBuilder mStringBuilder = new StringBuilder(256);
1107
1108    /**
1109     * Used to control how we initialize the service.
1110     */
1111    ComponentName mTopComponent;
1112    String mTopAction = Intent.ACTION_MAIN;
1113    String mTopData;
1114
1115    volatile boolean mProcessesReady = false;
1116    volatile boolean mSystemReady = false;
1117    volatile boolean mOnBattery = false;
1118    volatile int mFactoryTest;
1119
1120    @GuardedBy("this") boolean mBooting = false;
1121    @GuardedBy("this") boolean mCallFinishBooting = false;
1122    @GuardedBy("this") boolean mBootAnimationComplete = false;
1123    @GuardedBy("this") boolean mLaunchWarningShown = false;
1124    @GuardedBy("this") boolean mCheckedForSetup = false;
1125
1126    Context mContext;
1127
1128    /**
1129     * The time at which we will allow normal application switches again,
1130     * after a call to {@link #stopAppSwitches()}.
1131     */
1132    long mAppSwitchesAllowedTime;
1133
1134    /**
1135     * This is set to true after the first switch after mAppSwitchesAllowedTime
1136     * is set; any switches after that will clear the time.
1137     */
1138    boolean mDidAppSwitch;
1139
1140    /**
1141     * Last time (in realtime) at which we checked for power usage.
1142     */
1143    long mLastPowerCheckRealtime;
1144
1145    /**
1146     * Last time (in uptime) at which we checked for power usage.
1147     */
1148    long mLastPowerCheckUptime;
1149
1150    /**
1151     * Set while we are wanting to sleep, to prevent any
1152     * activities from being started/resumed.
1153     */
1154    private boolean mSleeping = false;
1155
1156    /**
1157     * The process state used for processes that are running the top activities.
1158     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1159     */
1160    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1161
1162    /**
1163     * Set while we are running a voice interaction.  This overrides
1164     * sleeping while it is active.
1165     */
1166    private IVoiceInteractionSession mRunningVoice;
1167
1168    /**
1169     * For some direct access we need to power manager.
1170     */
1171    PowerManagerInternal mLocalPowerManager;
1172
1173    /**
1174     * We want to hold a wake lock while running a voice interaction session, since
1175     * this may happen with the screen off and we need to keep the CPU running to
1176     * be able to continue to interact with the user.
1177     */
1178    PowerManager.WakeLock mVoiceWakeLock;
1179
1180    /**
1181     * State of external calls telling us if the device is awake or asleep.
1182     */
1183    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1184
1185    /**
1186     * A list of tokens that cause the top activity to be put to sleep.
1187     * They are used by components that may hide and block interaction with underlying
1188     * activities.
1189     */
1190    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1191
1192    static final int LOCK_SCREEN_HIDDEN = 0;
1193    static final int LOCK_SCREEN_LEAVING = 1;
1194    static final int LOCK_SCREEN_SHOWN = 2;
1195    /**
1196     * State of external call telling us if the lock screen is shown.
1197     */
1198    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1199
1200    /**
1201     * Set if we are shutting down the system, similar to sleeping.
1202     */
1203    boolean mShuttingDown = false;
1204
1205    /**
1206     * Current sequence id for oom_adj computation traversal.
1207     */
1208    int mAdjSeq = 0;
1209
1210    /**
1211     * Current sequence id for process LRU updating.
1212     */
1213    int mLruSeq = 0;
1214
1215    /**
1216     * Keep track of the non-cached/empty process we last found, to help
1217     * determine how to distribute cached/empty processes next time.
1218     */
1219    int mNumNonCachedProcs = 0;
1220
1221    /**
1222     * Keep track of the number of cached hidden procs, to balance oom adj
1223     * distribution between those and empty procs.
1224     */
1225    int mNumCachedHiddenProcs = 0;
1226
1227    /**
1228     * Keep track of the number of service processes we last found, to
1229     * determine on the next iteration which should be B services.
1230     */
1231    int mNumServiceProcs = 0;
1232    int mNewNumAServiceProcs = 0;
1233    int mNewNumServiceProcs = 0;
1234
1235    /**
1236     * Allow the current computed overall memory level of the system to go down?
1237     * This is set to false when we are killing processes for reasons other than
1238     * memory management, so that the now smaller process list will not be taken as
1239     * an indication that memory is tighter.
1240     */
1241    boolean mAllowLowerMemLevel = false;
1242
1243    /**
1244     * The last computed memory level, for holding when we are in a state that
1245     * processes are going away for other reasons.
1246     */
1247    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1248
1249    /**
1250     * The last total number of process we have, to determine if changes actually look
1251     * like a shrinking number of process due to lower RAM.
1252     */
1253    int mLastNumProcesses;
1254
1255    /**
1256     * The uptime of the last time we performed idle maintenance.
1257     */
1258    long mLastIdleTime = SystemClock.uptimeMillis();
1259
1260    /**
1261     * Total time spent with RAM that has been added in the past since the last idle time.
1262     */
1263    long mLowRamTimeSinceLastIdle = 0;
1264
1265    /**
1266     * If RAM is currently low, when that horrible situation started.
1267     */
1268    long mLowRamStartTime = 0;
1269
1270    /**
1271     * For reporting to battery stats the current top application.
1272     */
1273    private String mCurResumedPackage = null;
1274    private int mCurResumedUid = -1;
1275
1276    /**
1277     * For reporting to battery stats the apps currently running foreground
1278     * service.  The ProcessMap is package/uid tuples; each of these contain
1279     * an array of the currently foreground processes.
1280     */
1281    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1282            = new ProcessMap<ArrayList<ProcessRecord>>();
1283
1284    /**
1285     * This is set if we had to do a delayed dexopt of an app before launching
1286     * it, to increase the ANR timeouts in that case.
1287     */
1288    boolean mDidDexOpt;
1289
1290    /**
1291     * Set if the systemServer made a call to enterSafeMode.
1292     */
1293    boolean mSafeMode;
1294
1295    /**
1296     * If true, we are running under a test environment so will sample PSS from processes
1297     * much more rapidly to try to collect better data when the tests are rapidly
1298     * running through apps.
1299     */
1300    boolean mTestPssMode = false;
1301
1302    String mDebugApp = null;
1303    boolean mWaitForDebugger = false;
1304    boolean mDebugTransient = false;
1305    String mOrigDebugApp = null;
1306    boolean mOrigWaitForDebugger = false;
1307    boolean mAlwaysFinishActivities = false;
1308    boolean mLenientBackgroundCheck = false;
1309    boolean mForceResizableActivities;
1310    boolean mSupportsMultiWindow;
1311    boolean mSupportsFreeformWindowManagement;
1312    boolean mSupportsPictureInPicture;
1313    Rect mDefaultPinnedStackBounds;
1314    IActivityController mController = null;
1315    boolean mControllerIsAMonkey = false;
1316    String mProfileApp = null;
1317    ProcessRecord mProfileProc = null;
1318    String mProfileFile;
1319    ParcelFileDescriptor mProfileFd;
1320    int mSamplingInterval = 0;
1321    boolean mAutoStopProfiler = false;
1322    int mProfileType = 0;
1323    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1324    String mMemWatchDumpProcName;
1325    String mMemWatchDumpFile;
1326    int mMemWatchDumpPid;
1327    int mMemWatchDumpUid;
1328    String mTrackAllocationApp = null;
1329    String mNativeDebuggingApp = null;
1330
1331    final long[] mTmpLong = new long[2];
1332
1333    static final class ProcessChangeItem {
1334        static final int CHANGE_ACTIVITIES = 1<<0;
1335        static final int CHANGE_PROCESS_STATE = 1<<1;
1336        int changes;
1337        int uid;
1338        int pid;
1339        int processState;
1340        boolean foregroundActivities;
1341    }
1342
1343    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1344    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1345
1346    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1347    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1348
1349    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1350    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1351
1352    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1353    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1354
1355    /**
1356     * Runtime CPU use collection thread.  This object's lock is used to
1357     * perform synchronization with the thread (notifying it to run).
1358     */
1359    final Thread mProcessCpuThread;
1360
1361    /**
1362     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1363     * Must acquire this object's lock when accessing it.
1364     * NOTE: this lock will be held while doing long operations (trawling
1365     * through all processes in /proc), so it should never be acquired by
1366     * any critical paths such as when holding the main activity manager lock.
1367     */
1368    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1369            MONITOR_THREAD_CPU_USAGE);
1370    final AtomicLong mLastCpuTime = new AtomicLong(0);
1371    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1372
1373    long mLastWriteTime = 0;
1374
1375    /**
1376     * Used to retain an update lock when the foreground activity is in
1377     * immersive mode.
1378     */
1379    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1380
1381    /**
1382     * Set to true after the system has finished booting.
1383     */
1384    boolean mBooted = false;
1385
1386    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1387    int mProcessLimitOverride = -1;
1388
1389    WindowManagerService mWindowManager;
1390    final ActivityThread mSystemThread;
1391
1392    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1393        final ProcessRecord mApp;
1394        final int mPid;
1395        final IApplicationThread mAppThread;
1396
1397        AppDeathRecipient(ProcessRecord app, int pid,
1398                IApplicationThread thread) {
1399            if (DEBUG_ALL) Slog.v(
1400                TAG, "New death recipient " + this
1401                + " for thread " + thread.asBinder());
1402            mApp = app;
1403            mPid = pid;
1404            mAppThread = thread;
1405        }
1406
1407        @Override
1408        public void binderDied() {
1409            if (DEBUG_ALL) Slog.v(
1410                TAG, "Death received in " + this
1411                + " for thread " + mAppThread.asBinder());
1412            synchronized(ActivityManagerService.this) {
1413                appDiedLocked(mApp, mPid, mAppThread, true);
1414            }
1415        }
1416    }
1417
1418    static final int SHOW_ERROR_UI_MSG = 1;
1419    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1420    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1421    static final int UPDATE_CONFIGURATION_MSG = 4;
1422    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1423    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1424    static final int SERVICE_TIMEOUT_MSG = 12;
1425    static final int UPDATE_TIME_ZONE = 13;
1426    static final int SHOW_UID_ERROR_UI_MSG = 14;
1427    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1428    static final int PROC_START_TIMEOUT_MSG = 20;
1429    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1430    static final int KILL_APPLICATION_MSG = 22;
1431    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1432    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1433    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1434    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1435    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1436    static final int CLEAR_DNS_CACHE_MSG = 28;
1437    static final int UPDATE_HTTP_PROXY_MSG = 29;
1438    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1439    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1440    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1441    static final int REPORT_MEM_USAGE_MSG = 33;
1442    static final int REPORT_USER_SWITCH_MSG = 34;
1443    static final int CONTINUE_USER_SWITCH_MSG = 35;
1444    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1445    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1446    static final int PERSIST_URI_GRANTS_MSG = 38;
1447    static final int REQUEST_ALL_PSS_MSG = 39;
1448    static final int START_PROFILES_MSG = 40;
1449    static final int UPDATE_TIME = 41;
1450    static final int SYSTEM_USER_START_MSG = 42;
1451    static final int SYSTEM_USER_CURRENT_MSG = 43;
1452    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1453    static final int FINISH_BOOTING_MSG = 45;
1454    static final int START_USER_SWITCH_UI_MSG = 46;
1455    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1456    static final int DISMISS_DIALOG_UI_MSG = 48;
1457    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1458    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1459    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1460    static final int DELETE_DUMPHEAP_MSG = 52;
1461    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1462    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1463    static final int REPORT_TIME_TRACKER_MSG = 55;
1464    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1465    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1466    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1467    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1468    static final int IDLE_UIDS_MSG = 60;
1469    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1470    static final int LOG_STACK_STATE = 62;
1471    static final int VR_MODE_CHANGE_MSG = 63;
1472    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1473    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1474    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1475    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1476    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1477    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1478
1479    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1480    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1481    static final int FIRST_COMPAT_MODE_MSG = 300;
1482    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1483
1484    static ServiceThread sKillThread = null;
1485    static KillHandler sKillHandler = null;
1486
1487    CompatModeDialog mCompatModeDialog;
1488    long mLastMemUsageReportTime = 0;
1489
1490    /**
1491     * Flag whether the current user is a "monkey", i.e. whether
1492     * the UI is driven by a UI automation tool.
1493     */
1494    private boolean mUserIsMonkey;
1495
1496    /** Flag whether the device has a Recents UI */
1497    boolean mHasRecents;
1498
1499    /** The dimensions of the thumbnails in the Recents UI. */
1500    int mThumbnailWidth;
1501    int mThumbnailHeight;
1502    float mFullscreenThumbnailScale;
1503
1504    final ServiceThread mHandlerThread;
1505    final MainHandler mHandler;
1506    final UiHandler mUiHandler;
1507
1508    PackageManagerInternal mPackageManagerInt;
1509
1510    final class KillHandler extends Handler {
1511        static final int KILL_PROCESS_GROUP_MSG = 4000;
1512
1513        public KillHandler(Looper looper) {
1514            super(looper, null, true);
1515        }
1516
1517        @Override
1518        public void handleMessage(Message msg) {
1519            switch (msg.what) {
1520                case KILL_PROCESS_GROUP_MSG:
1521                {
1522                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1523                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1524                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1525                }
1526                break;
1527
1528                default:
1529                    super.handleMessage(msg);
1530            }
1531        }
1532    }
1533
1534    final class UiHandler extends Handler {
1535        public UiHandler() {
1536            super(com.android.server.UiThread.get().getLooper(), null, true);
1537        }
1538
1539        @Override
1540        public void handleMessage(Message msg) {
1541            switch (msg.what) {
1542            case SHOW_ERROR_UI_MSG: {
1543                mAppErrors.handleShowAppErrorUi(msg);
1544                ensureBootCompleted();
1545            } break;
1546            case SHOW_NOT_RESPONDING_UI_MSG: {
1547                mAppErrors.handleShowAnrUi(msg);
1548                ensureBootCompleted();
1549            } break;
1550            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1551                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1552                synchronized (ActivityManagerService.this) {
1553                    ProcessRecord proc = (ProcessRecord) data.get("app");
1554                    if (proc == null) {
1555                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1556                        break;
1557                    }
1558                    if (proc.crashDialog != null) {
1559                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1560                        return;
1561                    }
1562                    AppErrorResult res = (AppErrorResult) data.get("result");
1563                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1564                        Dialog d = new StrictModeViolationDialog(mContext,
1565                                ActivityManagerService.this, res, proc);
1566                        d.show();
1567                        proc.crashDialog = d;
1568                    } else {
1569                        // The device is asleep, so just pretend that the user
1570                        // saw a crash dialog and hit "force quit".
1571                        res.set(0);
1572                    }
1573                }
1574                ensureBootCompleted();
1575            } break;
1576            case SHOW_FACTORY_ERROR_UI_MSG: {
1577                Dialog d = new FactoryErrorDialog(
1578                    mContext, msg.getData().getCharSequence("msg"));
1579                d.show();
1580                ensureBootCompleted();
1581            } break;
1582            case WAIT_FOR_DEBUGGER_UI_MSG: {
1583                synchronized (ActivityManagerService.this) {
1584                    ProcessRecord app = (ProcessRecord)msg.obj;
1585                    if (msg.arg1 != 0) {
1586                        if (!app.waitedForDebugger) {
1587                            Dialog d = new AppWaitingForDebuggerDialog(
1588                                    ActivityManagerService.this,
1589                                    mContext, app);
1590                            app.waitDialog = d;
1591                            app.waitedForDebugger = true;
1592                            d.show();
1593                        }
1594                    } else {
1595                        if (app.waitDialog != null) {
1596                            app.waitDialog.dismiss();
1597                            app.waitDialog = null;
1598                        }
1599                    }
1600                }
1601            } break;
1602            case SHOW_UID_ERROR_UI_MSG: {
1603                if (mShowDialogs) {
1604                    AlertDialog d = new BaseErrorDialog(mContext);
1605                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1606                    d.setCancelable(false);
1607                    d.setTitle(mContext.getText(R.string.android_system_label));
1608                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1609                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1610                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1611                    d.show();
1612                }
1613            } break;
1614            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1615                if (mShowDialogs) {
1616                    AlertDialog d = new BaseErrorDialog(mContext);
1617                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1618                    d.setCancelable(false);
1619                    d.setTitle(mContext.getText(R.string.android_system_label));
1620                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1621                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1622                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1623                    d.show();
1624                }
1625            } break;
1626            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1627                synchronized (ActivityManagerService.this) {
1628                    ActivityRecord ar = (ActivityRecord) msg.obj;
1629                    if (mCompatModeDialog != null) {
1630                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1631                                ar.info.applicationInfo.packageName)) {
1632                            return;
1633                        }
1634                        mCompatModeDialog.dismiss();
1635                        mCompatModeDialog = null;
1636                    }
1637                    if (ar != null && false) {
1638                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1639                                ar.packageName)) {
1640                            int mode = mCompatModePackages.computeCompatModeLocked(
1641                                    ar.info.applicationInfo);
1642                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1643                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1644                                mCompatModeDialog = new CompatModeDialog(
1645                                        ActivityManagerService.this, mContext,
1646                                        ar.info.applicationInfo);
1647                                mCompatModeDialog.show();
1648                            }
1649                        }
1650                    }
1651                }
1652                break;
1653            }
1654            case START_USER_SWITCH_UI_MSG: {
1655                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1656                break;
1657            }
1658            case DISMISS_DIALOG_UI_MSG: {
1659                final Dialog d = (Dialog) msg.obj;
1660                d.dismiss();
1661                break;
1662            }
1663            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1664                dispatchProcessesChanged();
1665                break;
1666            }
1667            case DISPATCH_PROCESS_DIED_UI_MSG: {
1668                final int pid = msg.arg1;
1669                final int uid = msg.arg2;
1670                dispatchProcessDied(pid, uid);
1671                break;
1672            }
1673            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1674                dispatchUidsChanged();
1675            } break;
1676            }
1677        }
1678    }
1679
1680    final class MainHandler extends Handler {
1681        public MainHandler(Looper looper) {
1682            super(looper, null, true);
1683        }
1684
1685        @Override
1686        public void handleMessage(Message msg) {
1687            switch (msg.what) {
1688            case UPDATE_CONFIGURATION_MSG: {
1689                final ContentResolver resolver = mContext.getContentResolver();
1690                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1691                        msg.arg1);
1692            } break;
1693            case GC_BACKGROUND_PROCESSES_MSG: {
1694                synchronized (ActivityManagerService.this) {
1695                    performAppGcsIfAppropriateLocked();
1696                }
1697            } break;
1698            case SERVICE_TIMEOUT_MSG: {
1699                if (mDidDexOpt) {
1700                    mDidDexOpt = false;
1701                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1702                    nmsg.obj = msg.obj;
1703                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1704                    return;
1705                }
1706                mServices.serviceTimeout((ProcessRecord)msg.obj);
1707            } break;
1708            case UPDATE_TIME_ZONE: {
1709                synchronized (ActivityManagerService.this) {
1710                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1711                        ProcessRecord r = mLruProcesses.get(i);
1712                        if (r.thread != null) {
1713                            try {
1714                                r.thread.updateTimeZone();
1715                            } catch (RemoteException ex) {
1716                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1717                            }
1718                        }
1719                    }
1720                }
1721            } break;
1722            case CLEAR_DNS_CACHE_MSG: {
1723                synchronized (ActivityManagerService.this) {
1724                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1725                        ProcessRecord r = mLruProcesses.get(i);
1726                        if (r.thread != null) {
1727                            try {
1728                                r.thread.clearDnsCache();
1729                            } catch (RemoteException ex) {
1730                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1731                            }
1732                        }
1733                    }
1734                }
1735            } break;
1736            case UPDATE_HTTP_PROXY_MSG: {
1737                ProxyInfo proxy = (ProxyInfo)msg.obj;
1738                String host = "";
1739                String port = "";
1740                String exclList = "";
1741                Uri pacFileUrl = Uri.EMPTY;
1742                if (proxy != null) {
1743                    host = proxy.getHost();
1744                    port = Integer.toString(proxy.getPort());
1745                    exclList = proxy.getExclusionListAsString();
1746                    pacFileUrl = proxy.getPacFileUrl();
1747                }
1748                synchronized (ActivityManagerService.this) {
1749                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1750                        ProcessRecord r = mLruProcesses.get(i);
1751                        if (r.thread != null) {
1752                            try {
1753                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1754                            } catch (RemoteException ex) {
1755                                Slog.w(TAG, "Failed to update http proxy for: " +
1756                                        r.info.processName);
1757                            }
1758                        }
1759                    }
1760                }
1761            } break;
1762            case PROC_START_TIMEOUT_MSG: {
1763                if (mDidDexOpt) {
1764                    mDidDexOpt = false;
1765                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1766                    nmsg.obj = msg.obj;
1767                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1768                    return;
1769                }
1770                ProcessRecord app = (ProcessRecord)msg.obj;
1771                synchronized (ActivityManagerService.this) {
1772                    processStartTimedOutLocked(app);
1773                }
1774            } break;
1775            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1776                ProcessRecord app = (ProcessRecord)msg.obj;
1777                synchronized (ActivityManagerService.this) {
1778                    processContentProviderPublishTimedOutLocked(app);
1779                }
1780            } break;
1781            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1782                synchronized (ActivityManagerService.this) {
1783                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1784                }
1785            } break;
1786            case KILL_APPLICATION_MSG: {
1787                synchronized (ActivityManagerService.this) {
1788                    int appid = msg.arg1;
1789                    boolean restart = (msg.arg2 == 1);
1790                    Bundle bundle = (Bundle)msg.obj;
1791                    String pkg = bundle.getString("pkg");
1792                    String reason = bundle.getString("reason");
1793                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1794                            false, UserHandle.USER_ALL, reason);
1795                }
1796            } break;
1797            case FINALIZE_PENDING_INTENT_MSG: {
1798                ((PendingIntentRecord)msg.obj).completeFinalize();
1799            } break;
1800            case POST_HEAVY_NOTIFICATION_MSG: {
1801                INotificationManager inm = NotificationManager.getService();
1802                if (inm == null) {
1803                    return;
1804                }
1805
1806                ActivityRecord root = (ActivityRecord)msg.obj;
1807                ProcessRecord process = root.app;
1808                if (process == null) {
1809                    return;
1810                }
1811
1812                try {
1813                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1814                    String text = mContext.getString(R.string.heavy_weight_notification,
1815                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1816                    Notification notification = new Notification.Builder(context)
1817                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1818                            .setWhen(0)
1819                            .setOngoing(true)
1820                            .setTicker(text)
1821                            .setColor(mContext.getColor(
1822                                    com.android.internal.R.color.system_notification_accent_color))
1823                            .setContentTitle(text)
1824                            .setContentText(
1825                                    mContext.getText(R.string.heavy_weight_notification_detail))
1826                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1827                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1828                                    new UserHandle(root.userId)))
1829                            .build();
1830                    try {
1831                        int[] outId = new int[1];
1832                        inm.enqueueNotificationWithTag("android", "android", null,
1833                                R.string.heavy_weight_notification,
1834                                notification, outId, root.userId);
1835                    } catch (RuntimeException e) {
1836                        Slog.w(ActivityManagerService.TAG,
1837                                "Error showing notification for heavy-weight app", e);
1838                    } catch (RemoteException e) {
1839                    }
1840                } catch (NameNotFoundException e) {
1841                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1842                }
1843            } break;
1844            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1845                INotificationManager inm = NotificationManager.getService();
1846                if (inm == null) {
1847                    return;
1848                }
1849                try {
1850                    inm.cancelNotificationWithTag("android", null,
1851                            R.string.heavy_weight_notification,  msg.arg1);
1852                } catch (RuntimeException e) {
1853                    Slog.w(ActivityManagerService.TAG,
1854                            "Error canceling notification for service", e);
1855                } catch (RemoteException e) {
1856                }
1857            } break;
1858            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1859                synchronized (ActivityManagerService.this) {
1860                    checkExcessivePowerUsageLocked(true);
1861                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1862                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1863                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1864                }
1865            } break;
1866            case REPORT_MEM_USAGE_MSG: {
1867                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1868                Thread thread = new Thread() {
1869                    @Override public void run() {
1870                        reportMemUsage(memInfos);
1871                    }
1872                };
1873                thread.start();
1874                break;
1875            }
1876            case REPORT_USER_SWITCH_MSG: {
1877                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1878                break;
1879            }
1880            case CONTINUE_USER_SWITCH_MSG: {
1881                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1882                break;
1883            }
1884            case USER_SWITCH_TIMEOUT_MSG: {
1885                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1886                break;
1887            }
1888            case IMMERSIVE_MODE_LOCK_MSG: {
1889                final boolean nextState = (msg.arg1 != 0);
1890                if (mUpdateLock.isHeld() != nextState) {
1891                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1892                            "Applying new update lock state '" + nextState
1893                            + "' for " + (ActivityRecord)msg.obj);
1894                    if (nextState) {
1895                        mUpdateLock.acquire();
1896                    } else {
1897                        mUpdateLock.release();
1898                    }
1899                }
1900                break;
1901            }
1902            case PERSIST_URI_GRANTS_MSG: {
1903                writeGrantedUriPermissions();
1904                break;
1905            }
1906            case REQUEST_ALL_PSS_MSG: {
1907                synchronized (ActivityManagerService.this) {
1908                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1909                }
1910                break;
1911            }
1912            case START_PROFILES_MSG: {
1913                synchronized (ActivityManagerService.this) {
1914                    mUserController.startProfilesLocked();
1915                }
1916                break;
1917            }
1918            case UPDATE_TIME: {
1919                synchronized (ActivityManagerService.this) {
1920                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1921                        ProcessRecord r = mLruProcesses.get(i);
1922                        if (r.thread != null) {
1923                            try {
1924                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1925                            } catch (RemoteException ex) {
1926                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1927                            }
1928                        }
1929                    }
1930                }
1931                break;
1932            }
1933            case SYSTEM_USER_START_MSG: {
1934                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1935                        Integer.toString(msg.arg1), msg.arg1);
1936                mSystemServiceManager.startUser(msg.arg1);
1937                break;
1938            }
1939            case SYSTEM_USER_UNLOCK_MSG: {
1940                final int userId = msg.arg1;
1941                mSystemServiceManager.unlockUser(userId);
1942                synchronized (ActivityManagerService.this) {
1943                    mRecentTasks.loadUserRecentsLocked(userId);
1944                }
1945                if (userId == UserHandle.USER_SYSTEM) {
1946                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1947                }
1948                installEncryptionUnawareProviders(userId);
1949                mUserController.finishUserUnlocked((UserState) msg.obj);
1950                break;
1951            }
1952            case SYSTEM_USER_CURRENT_MSG: {
1953                mBatteryStatsService.noteEvent(
1954                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1955                        Integer.toString(msg.arg2), msg.arg2);
1956                mBatteryStatsService.noteEvent(
1957                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1958                        Integer.toString(msg.arg1), msg.arg1);
1959                mSystemServiceManager.switchUser(msg.arg1);
1960                break;
1961            }
1962            case ENTER_ANIMATION_COMPLETE_MSG: {
1963                synchronized (ActivityManagerService.this) {
1964                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1965                    if (r != null && r.app != null && r.app.thread != null) {
1966                        try {
1967                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1968                        } catch (RemoteException e) {
1969                        }
1970                    }
1971                }
1972                break;
1973            }
1974            case FINISH_BOOTING_MSG: {
1975                if (msg.arg1 != 0) {
1976                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1977                    finishBooting();
1978                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1979                }
1980                if (msg.arg2 != 0) {
1981                    enableScreenAfterBoot();
1982                }
1983                break;
1984            }
1985            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1986                try {
1987                    Locale l = (Locale) msg.obj;
1988                    IBinder service = ServiceManager.getService("mount");
1989                    IMountService mountService = IMountService.Stub.asInterface(service);
1990                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1991                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1992                } catch (RemoteException e) {
1993                    Log.e(TAG, "Error storing locale for decryption UI", e);
1994                }
1995                break;
1996            }
1997            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1998                synchronized (ActivityManagerService.this) {
1999                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2000                        try {
2001                            // Make a one-way callback to the listener
2002                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2003                        } catch (RemoteException e){
2004                            // Handled by the RemoteCallbackList
2005                        }
2006                    }
2007                    mTaskStackListeners.finishBroadcast();
2008                }
2009                break;
2010            }
2011            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2012                synchronized (ActivityManagerService.this) {
2013                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2014                        try {
2015                            // Make a one-way callback to the listener
2016                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2017                        } catch (RemoteException e){
2018                            // Handled by the RemoteCallbackList
2019                        }
2020                    }
2021                    mTaskStackListeners.finishBroadcast();
2022                }
2023                break;
2024            }
2025            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2026                synchronized (ActivityManagerService.this) {
2027                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2028                        try {
2029                            // Make a one-way callback to the listener
2030                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2031                        } catch (RemoteException e){
2032                            // Handled by the RemoteCallbackList
2033                        }
2034                    }
2035                    mTaskStackListeners.finishBroadcast();
2036                }
2037                break;
2038            }
2039            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2040                synchronized (ActivityManagerService.this) {
2041                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2042                        try {
2043                            // Make a one-way callback to the listener
2044                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2045                        } catch (RemoteException e){
2046                            // Handled by the RemoteCallbackList
2047                        }
2048                    }
2049                    mTaskStackListeners.finishBroadcast();
2050                }
2051                break;
2052            }
2053            case NOTIFY_FORCED_RESIZABLE_MSG: {
2054                synchronized (ActivityManagerService.this) {
2055                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2056                        try {
2057                            // Make a one-way callback to the listener
2058                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2059                                    (String) msg.obj, msg.arg1);
2060                        } catch (RemoteException e){
2061                            // Handled by the RemoteCallbackList
2062                        }
2063                    }
2064                    mTaskStackListeners.finishBroadcast();
2065                }
2066                break;
2067            }
2068                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2069                    synchronized (ActivityManagerService.this) {
2070                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2071                            try {
2072                                // Make a one-way callback to the listener
2073                                mTaskStackListeners.getBroadcastItem(i)
2074                                        .onActivityDismissingDockedStack();
2075                            } catch (RemoteException e){
2076                                // Handled by the RemoteCallbackList
2077                            }
2078                        }
2079                        mTaskStackListeners.finishBroadcast();
2080                    }
2081                    break;
2082                }
2083            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2084                final int uid = msg.arg1;
2085                final byte[] firstPacket = (byte[]) msg.obj;
2086
2087                synchronized (mPidsSelfLocked) {
2088                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2089                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2090                        if (p.uid == uid) {
2091                            try {
2092                                p.thread.notifyCleartextNetwork(firstPacket);
2093                            } catch (RemoteException ignored) {
2094                            }
2095                        }
2096                    }
2097                }
2098                break;
2099            }
2100            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2101                final String procName;
2102                final int uid;
2103                final long memLimit;
2104                final String reportPackage;
2105                synchronized (ActivityManagerService.this) {
2106                    procName = mMemWatchDumpProcName;
2107                    uid = mMemWatchDumpUid;
2108                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2109                    if (val == null) {
2110                        val = mMemWatchProcesses.get(procName, 0);
2111                    }
2112                    if (val != null) {
2113                        memLimit = val.first;
2114                        reportPackage = val.second;
2115                    } else {
2116                        memLimit = 0;
2117                        reportPackage = null;
2118                    }
2119                }
2120                if (procName == null) {
2121                    return;
2122                }
2123
2124                if (DEBUG_PSS) Slog.d(TAG_PSS,
2125                        "Showing dump heap notification from " + procName + "/" + uid);
2126
2127                INotificationManager inm = NotificationManager.getService();
2128                if (inm == null) {
2129                    return;
2130                }
2131
2132                String text = mContext.getString(R.string.dump_heap_notification, procName);
2133
2134
2135                Intent deleteIntent = new Intent();
2136                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2137                Intent intent = new Intent();
2138                intent.setClassName("android", DumpHeapActivity.class.getName());
2139                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2140                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2141                if (reportPackage != null) {
2142                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2143                }
2144                int userId = UserHandle.getUserId(uid);
2145                Notification notification = new Notification.Builder(mContext)
2146                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2147                        .setWhen(0)
2148                        .setOngoing(true)
2149                        .setAutoCancel(true)
2150                        .setTicker(text)
2151                        .setColor(mContext.getColor(
2152                                com.android.internal.R.color.system_notification_accent_color))
2153                        .setContentTitle(text)
2154                        .setContentText(
2155                                mContext.getText(R.string.dump_heap_notification_detail))
2156                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2157                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2158                                new UserHandle(userId)))
2159                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2160                                deleteIntent, 0, UserHandle.SYSTEM))
2161                        .build();
2162
2163                try {
2164                    int[] outId = new int[1];
2165                    inm.enqueueNotificationWithTag("android", "android", null,
2166                            R.string.dump_heap_notification,
2167                            notification, outId, userId);
2168                } catch (RuntimeException e) {
2169                    Slog.w(ActivityManagerService.TAG,
2170                            "Error showing notification for dump heap", e);
2171                } catch (RemoteException e) {
2172                }
2173            } break;
2174            case DELETE_DUMPHEAP_MSG: {
2175                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2176                        DumpHeapActivity.JAVA_URI,
2177                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2178                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2179                        UserHandle.myUserId());
2180                synchronized (ActivityManagerService.this) {
2181                    mMemWatchDumpFile = null;
2182                    mMemWatchDumpProcName = null;
2183                    mMemWatchDumpPid = -1;
2184                    mMemWatchDumpUid = -1;
2185                }
2186            } break;
2187            case FOREGROUND_PROFILE_CHANGED_MSG: {
2188                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2189            } break;
2190            case REPORT_TIME_TRACKER_MSG: {
2191                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2192                tracker.deliverResult(mContext);
2193            } break;
2194            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2195                mUserController.dispatchUserSwitchComplete(msg.arg1);
2196            } break;
2197            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2198                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2199                try {
2200                    connection.shutdown();
2201                } catch (RemoteException e) {
2202                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2203                }
2204                // Only a UiAutomation can set this flag and now that
2205                // it is finished we make sure it is reset to its default.
2206                mUserIsMonkey = false;
2207            } break;
2208            case APP_BOOST_DEACTIVATE_MSG: {
2209                synchronized(ActivityManagerService.this) {
2210                    if (mIsBoosted) {
2211                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2212                            nativeMigrateFromBoost();
2213                            mIsBoosted = false;
2214                            mBoostStartTime = 0;
2215                        } else {
2216                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2217                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2218                        }
2219                    }
2220                }
2221            } break;
2222            case IDLE_UIDS_MSG: {
2223                idleUids();
2224            } break;
2225            case LOG_STACK_STATE: {
2226                synchronized (ActivityManagerService.this) {
2227                    mStackSupervisor.logStackState();
2228                }
2229            } break;
2230            case VR_MODE_CHANGE_MSG: {
2231                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2232                final ActivityRecord r = (ActivityRecord) msg.obj;
2233                boolean vrMode;
2234                ComponentName requestedPackage;
2235                ComponentName callingPackage;
2236                int userId;
2237                synchronized (ActivityManagerService.this) {
2238                    vrMode = r.requestedVrComponent != null;
2239                    requestedPackage = r.requestedVrComponent;
2240                    userId = r.userId;
2241                    callingPackage = r.info.getComponentName();
2242                    if (mInVrMode != vrMode) {
2243                        mInVrMode = vrMode;
2244                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2245                    }
2246                }
2247                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2248            } break;
2249            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2250                final ActivityRecord r = (ActivityRecord) msg.obj;
2251                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2252                if (needsVrMode) {
2253                    VrManagerInternal vrService =
2254                            LocalServices.getService(VrManagerInternal.class);
2255                    boolean enable = msg.arg1 == 1;
2256                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2257                            r.info.getComponentName());
2258                }
2259            } break;
2260            }
2261        }
2262    };
2263
2264    static final int COLLECT_PSS_BG_MSG = 1;
2265
2266    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2267        @Override
2268        public void handleMessage(Message msg) {
2269            switch (msg.what) {
2270            case COLLECT_PSS_BG_MSG: {
2271                long start = SystemClock.uptimeMillis();
2272                MemInfoReader memInfo = null;
2273                synchronized (ActivityManagerService.this) {
2274                    if (mFullPssPending) {
2275                        mFullPssPending = false;
2276                        memInfo = new MemInfoReader();
2277                    }
2278                }
2279                if (memInfo != null) {
2280                    updateCpuStatsNow();
2281                    long nativeTotalPss = 0;
2282                    synchronized (mProcessCpuTracker) {
2283                        final int N = mProcessCpuTracker.countStats();
2284                        for (int j=0; j<N; j++) {
2285                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2286                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2287                                // This is definitely an application process; skip it.
2288                                continue;
2289                            }
2290                            synchronized (mPidsSelfLocked) {
2291                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2292                                    // This is one of our own processes; skip it.
2293                                    continue;
2294                                }
2295                            }
2296                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2297                        }
2298                    }
2299                    memInfo.readMemInfo();
2300                    synchronized (ActivityManagerService.this) {
2301                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2302                                + (SystemClock.uptimeMillis()-start) + "ms");
2303                        final long cachedKb = memInfo.getCachedSizeKb();
2304                        final long freeKb = memInfo.getFreeSizeKb();
2305                        final long zramKb = memInfo.getZramTotalSizeKb();
2306                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2307                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2308                                kernelKb*1024, nativeTotalPss*1024);
2309                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2310                                nativeTotalPss);
2311                    }
2312                }
2313
2314                int num = 0;
2315                long[] tmp = new long[2];
2316                do {
2317                    ProcessRecord proc;
2318                    int procState;
2319                    int pid;
2320                    long lastPssTime;
2321                    synchronized (ActivityManagerService.this) {
2322                        if (mPendingPssProcesses.size() <= 0) {
2323                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2324                                    "Collected PSS of " + num + " processes in "
2325                                    + (SystemClock.uptimeMillis() - start) + "ms");
2326                            mPendingPssProcesses.clear();
2327                            return;
2328                        }
2329                        proc = mPendingPssProcesses.remove(0);
2330                        procState = proc.pssProcState;
2331                        lastPssTime = proc.lastPssTime;
2332                        if (proc.thread != null && procState == proc.setProcState
2333                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2334                                        < SystemClock.uptimeMillis()) {
2335                            pid = proc.pid;
2336                        } else {
2337                            proc = null;
2338                            pid = 0;
2339                        }
2340                    }
2341                    if (proc != null) {
2342                        long pss = Debug.getPss(pid, tmp, null);
2343                        synchronized (ActivityManagerService.this) {
2344                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2345                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2346                                num++;
2347                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2348                                        SystemClock.uptimeMillis());
2349                            }
2350                        }
2351                    }
2352                } while (true);
2353            }
2354            }
2355        }
2356    };
2357
2358    public void setSystemProcess() {
2359        try {
2360            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2361            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2362            ServiceManager.addService("meminfo", new MemBinder(this));
2363            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2364            ServiceManager.addService("dbinfo", new DbBinder(this));
2365            if (MONITOR_CPU_USAGE) {
2366                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2367            }
2368            ServiceManager.addService("permission", new PermissionController(this));
2369            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2370
2371            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2372                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2373            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2374
2375            synchronized (this) {
2376                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2377                app.persistent = true;
2378                app.pid = MY_PID;
2379                app.maxAdj = ProcessList.SYSTEM_ADJ;
2380                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2381                synchronized (mPidsSelfLocked) {
2382                    mPidsSelfLocked.put(app.pid, app);
2383                }
2384                updateLruProcessLocked(app, false, null);
2385                updateOomAdjLocked();
2386            }
2387        } catch (PackageManager.NameNotFoundException e) {
2388            throw new RuntimeException(
2389                    "Unable to find android system package", e);
2390        }
2391    }
2392
2393    public void setWindowManager(WindowManagerService wm) {
2394        mWindowManager = wm;
2395        mStackSupervisor.setWindowManager(wm);
2396        mActivityStarter.setWindowManager(wm);
2397    }
2398
2399    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2400        mUsageStatsService = usageStatsManager;
2401    }
2402
2403    public void startObservingNativeCrashes() {
2404        final NativeCrashListener ncl = new NativeCrashListener(this);
2405        ncl.start();
2406    }
2407
2408    public IAppOpsService getAppOpsService() {
2409        return mAppOpsService;
2410    }
2411
2412    static class MemBinder extends Binder {
2413        ActivityManagerService mActivityManagerService;
2414        MemBinder(ActivityManagerService activityManagerService) {
2415            mActivityManagerService = activityManagerService;
2416        }
2417
2418        @Override
2419        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2420            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2421                    != PackageManager.PERMISSION_GRANTED) {
2422                pw.println("Permission Denial: can't dump meminfo from from pid="
2423                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2424                        + " without permission " + android.Manifest.permission.DUMP);
2425                return;
2426            }
2427
2428            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2429        }
2430    }
2431
2432    static class GraphicsBinder extends Binder {
2433        ActivityManagerService mActivityManagerService;
2434        GraphicsBinder(ActivityManagerService activityManagerService) {
2435            mActivityManagerService = activityManagerService;
2436        }
2437
2438        @Override
2439        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2440            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2441                    != PackageManager.PERMISSION_GRANTED) {
2442                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2443                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2444                        + " without permission " + android.Manifest.permission.DUMP);
2445                return;
2446            }
2447
2448            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2449        }
2450    }
2451
2452    static class DbBinder extends Binder {
2453        ActivityManagerService mActivityManagerService;
2454        DbBinder(ActivityManagerService activityManagerService) {
2455            mActivityManagerService = activityManagerService;
2456        }
2457
2458        @Override
2459        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2460            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2461                    != PackageManager.PERMISSION_GRANTED) {
2462                pw.println("Permission Denial: can't dump dbinfo from from pid="
2463                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2464                        + " without permission " + android.Manifest.permission.DUMP);
2465                return;
2466            }
2467
2468            mActivityManagerService.dumpDbInfo(fd, pw, args);
2469        }
2470    }
2471
2472    static class CpuBinder extends Binder {
2473        ActivityManagerService mActivityManagerService;
2474        CpuBinder(ActivityManagerService activityManagerService) {
2475            mActivityManagerService = activityManagerService;
2476        }
2477
2478        @Override
2479        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2480            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2481                    != PackageManager.PERMISSION_GRANTED) {
2482                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2483                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2484                        + " without permission " + android.Manifest.permission.DUMP);
2485                return;
2486            }
2487
2488            synchronized (mActivityManagerService.mProcessCpuTracker) {
2489                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2490                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2491                        SystemClock.uptimeMillis()));
2492            }
2493        }
2494    }
2495
2496    public static final class Lifecycle extends SystemService {
2497        private final ActivityManagerService mService;
2498
2499        public Lifecycle(Context context) {
2500            super(context);
2501            mService = new ActivityManagerService(context);
2502        }
2503
2504        @Override
2505        public void onStart() {
2506            mService.start();
2507        }
2508
2509        public ActivityManagerService getService() {
2510            return mService;
2511        }
2512    }
2513
2514    // Note: This method is invoked on the main thread but may need to attach various
2515    // handlers to other threads.  So take care to be explicit about the looper.
2516    public ActivityManagerService(Context systemContext) {
2517        mContext = systemContext;
2518        mFactoryTest = FactoryTest.getMode();
2519        mSystemThread = ActivityThread.currentActivityThread();
2520
2521        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2522
2523        mHandlerThread = new ServiceThread(TAG,
2524                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2525        mHandlerThread.start();
2526        mHandler = new MainHandler(mHandlerThread.getLooper());
2527        mUiHandler = new UiHandler();
2528
2529        /* static; one-time init here */
2530        if (sKillHandler == null) {
2531            sKillThread = new ServiceThread(TAG + ":kill",
2532                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2533            sKillThread.start();
2534            sKillHandler = new KillHandler(sKillThread.getLooper());
2535        }
2536
2537        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2538                "foreground", BROADCAST_FG_TIMEOUT, false);
2539        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2540                "background", BROADCAST_BG_TIMEOUT, true);
2541        mBroadcastQueues[0] = mFgBroadcastQueue;
2542        mBroadcastQueues[1] = mBgBroadcastQueue;
2543
2544        mServices = new ActiveServices(this);
2545        mProviderMap = new ProviderMap(this);
2546        mAppErrors = new AppErrors(mContext, this);
2547
2548        // TODO: Move creation of battery stats service outside of activity manager service.
2549        File dataDir = Environment.getDataDirectory();
2550        File systemDir = new File(dataDir, "system");
2551        systemDir.mkdirs();
2552        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2553        mBatteryStatsService.getActiveStatistics().readLocked();
2554        mBatteryStatsService.scheduleWriteToDisk();
2555        mOnBattery = DEBUG_POWER ? true
2556                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2557        mBatteryStatsService.getActiveStatistics().setCallback(this);
2558
2559        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2560
2561        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2562        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2563                new IAppOpsCallback.Stub() {
2564                    @Override public void opChanged(int op, int uid, String packageName) {
2565                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2566                            if (mAppOpsService.checkOperation(op, uid, packageName)
2567                                    != AppOpsManager.MODE_ALLOWED) {
2568                                runInBackgroundDisabled(uid);
2569                            }
2570                        }
2571                    }
2572                });
2573
2574        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2575
2576        mUserController = new UserController(this);
2577
2578        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2579            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2580
2581        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2582
2583        mConfiguration.setToDefaults();
2584        mConfiguration.setLocales(LocaleList.getDefault());
2585
2586        mConfigurationSeq = mConfiguration.seq = 1;
2587        mProcessCpuTracker.init();
2588
2589        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2590        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2591        mStackSupervisor = new ActivityStackSupervisor(this);
2592        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2593        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2594
2595        mProcessCpuThread = new Thread("CpuTracker") {
2596            @Override
2597            public void run() {
2598                while (true) {
2599                    try {
2600                        try {
2601                            synchronized(this) {
2602                                final long now = SystemClock.uptimeMillis();
2603                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2604                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2605                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2606                                //        + ", write delay=" + nextWriteDelay);
2607                                if (nextWriteDelay < nextCpuDelay) {
2608                                    nextCpuDelay = nextWriteDelay;
2609                                }
2610                                if (nextCpuDelay > 0) {
2611                                    mProcessCpuMutexFree.set(true);
2612                                    this.wait(nextCpuDelay);
2613                                }
2614                            }
2615                        } catch (InterruptedException e) {
2616                        }
2617                        updateCpuStatsNow();
2618                    } catch (Exception e) {
2619                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2620                    }
2621                }
2622            }
2623        };
2624
2625        Watchdog.getInstance().addMonitor(this);
2626        Watchdog.getInstance().addThread(mHandler);
2627    }
2628
2629    public void setSystemServiceManager(SystemServiceManager mgr) {
2630        mSystemServiceManager = mgr;
2631    }
2632
2633    public void setInstaller(Installer installer) {
2634        mInstaller = installer;
2635    }
2636
2637    private void start() {
2638        Process.removeAllProcessGroups();
2639        mProcessCpuThread.start();
2640
2641        mBatteryStatsService.publish(mContext);
2642        mAppOpsService.publish(mContext);
2643        Slog.d("AppOps", "AppOpsService published");
2644        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2645    }
2646
2647    void onUserStoppedLocked(int userId) {
2648        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2649    }
2650
2651    public void initPowerManagement() {
2652        mStackSupervisor.initPowerManagement();
2653        mBatteryStatsService.initPowerManagement();
2654        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2655        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2656        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2657        mVoiceWakeLock.setReferenceCounted(false);
2658    }
2659
2660    @Override
2661    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2662            throws RemoteException {
2663        if (code == SYSPROPS_TRANSACTION) {
2664            // We need to tell all apps about the system property change.
2665            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2666            synchronized(this) {
2667                final int NP = mProcessNames.getMap().size();
2668                for (int ip=0; ip<NP; ip++) {
2669                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2670                    final int NA = apps.size();
2671                    for (int ia=0; ia<NA; ia++) {
2672                        ProcessRecord app = apps.valueAt(ia);
2673                        if (app.thread != null) {
2674                            procs.add(app.thread.asBinder());
2675                        }
2676                    }
2677                }
2678            }
2679
2680            int N = procs.size();
2681            for (int i=0; i<N; i++) {
2682                Parcel data2 = Parcel.obtain();
2683                try {
2684                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2685                } catch (RemoteException e) {
2686                }
2687                data2.recycle();
2688            }
2689        }
2690        try {
2691            return super.onTransact(code, data, reply, flags);
2692        } catch (RuntimeException e) {
2693            // The activity manager only throws security exceptions, so let's
2694            // log all others.
2695            if (!(e instanceof SecurityException)) {
2696                Slog.wtf(TAG, "Activity Manager Crash", e);
2697            }
2698            throw e;
2699        }
2700    }
2701
2702    void updateCpuStats() {
2703        final long now = SystemClock.uptimeMillis();
2704        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2705            return;
2706        }
2707        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2708            synchronized (mProcessCpuThread) {
2709                mProcessCpuThread.notify();
2710            }
2711        }
2712    }
2713
2714    void updateCpuStatsNow() {
2715        synchronized (mProcessCpuTracker) {
2716            mProcessCpuMutexFree.set(false);
2717            final long now = SystemClock.uptimeMillis();
2718            boolean haveNewCpuStats = false;
2719
2720            if (MONITOR_CPU_USAGE &&
2721                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2722                mLastCpuTime.set(now);
2723                mProcessCpuTracker.update();
2724                if (mProcessCpuTracker.hasGoodLastStats()) {
2725                    haveNewCpuStats = true;
2726                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2727                    //Slog.i(TAG, "Total CPU usage: "
2728                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2729
2730                    // Slog the cpu usage if the property is set.
2731                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2732                        int user = mProcessCpuTracker.getLastUserTime();
2733                        int system = mProcessCpuTracker.getLastSystemTime();
2734                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2735                        int irq = mProcessCpuTracker.getLastIrqTime();
2736                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2737                        int idle = mProcessCpuTracker.getLastIdleTime();
2738
2739                        int total = user + system + iowait + irq + softIrq + idle;
2740                        if (total == 0) total = 1;
2741
2742                        EventLog.writeEvent(EventLogTags.CPU,
2743                                ((user+system+iowait+irq+softIrq) * 100) / total,
2744                                (user * 100) / total,
2745                                (system * 100) / total,
2746                                (iowait * 100) / total,
2747                                (irq * 100) / total,
2748                                (softIrq * 100) / total);
2749                    }
2750                }
2751            }
2752
2753            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2754            synchronized(bstats) {
2755                synchronized(mPidsSelfLocked) {
2756                    if (haveNewCpuStats) {
2757                        if (bstats.startAddingCpuLocked()) {
2758                            int totalUTime = 0;
2759                            int totalSTime = 0;
2760                            final int N = mProcessCpuTracker.countStats();
2761                            for (int i=0; i<N; i++) {
2762                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2763                                if (!st.working) {
2764                                    continue;
2765                                }
2766                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2767                                totalUTime += st.rel_utime;
2768                                totalSTime += st.rel_stime;
2769                                if (pr != null) {
2770                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2771                                    if (ps == null || !ps.isActive()) {
2772                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2773                                                pr.info.uid, pr.processName);
2774                                    }
2775                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2776                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2777                                } else {
2778                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2779                                    if (ps == null || !ps.isActive()) {
2780                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2781                                                bstats.mapUid(st.uid), st.name);
2782                                    }
2783                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2784                                }
2785                            }
2786                            final int userTime = mProcessCpuTracker.getLastUserTime();
2787                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2788                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2789                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2790                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2791                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2792                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2793                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2794                        }
2795                    }
2796                }
2797
2798                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2799                    mLastWriteTime = now;
2800                    mBatteryStatsService.scheduleWriteToDisk();
2801                }
2802            }
2803        }
2804    }
2805
2806    @Override
2807    public void batteryNeedsCpuUpdate() {
2808        updateCpuStatsNow();
2809    }
2810
2811    @Override
2812    public void batteryPowerChanged(boolean onBattery) {
2813        // When plugging in, update the CPU stats first before changing
2814        // the plug state.
2815        updateCpuStatsNow();
2816        synchronized (this) {
2817            synchronized(mPidsSelfLocked) {
2818                mOnBattery = DEBUG_POWER ? true : onBattery;
2819            }
2820        }
2821    }
2822
2823    @Override
2824    public void batterySendBroadcast(Intent intent) {
2825        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2826                AppOpsManager.OP_NONE, null, false, false,
2827                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2828    }
2829
2830    /**
2831     * Initialize the application bind args. These are passed to each
2832     * process when the bindApplication() IPC is sent to the process. They're
2833     * lazily setup to make sure the services are running when they're asked for.
2834     */
2835    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2836        if (mAppBindArgs == null) {
2837            mAppBindArgs = new HashMap<>();
2838
2839            // Isolated processes won't get this optimization, so that we don't
2840            // violate the rules about which services they have access to.
2841            if (!isolated) {
2842                // Setup the application init args
2843                mAppBindArgs.put("package", ServiceManager.getService("package"));
2844                mAppBindArgs.put("window", ServiceManager.getService("window"));
2845                mAppBindArgs.put(Context.ALARM_SERVICE,
2846                        ServiceManager.getService(Context.ALARM_SERVICE));
2847            }
2848        }
2849        return mAppBindArgs;
2850    }
2851
2852    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2853        if (r == null || mFocusedActivity == r) {
2854            return false;
2855        }
2856
2857        if (!r.isFocusable()) {
2858            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2859            return false;
2860        }
2861
2862        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2863
2864        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2865        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2866                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2867        mDoingSetFocusedActivity = true;
2868
2869        final ActivityRecord last = mFocusedActivity;
2870        mFocusedActivity = r;
2871        if (r.task.isApplicationTask()) {
2872            if (mCurAppTimeTracker != r.appTimeTracker) {
2873                // We are switching app tracking.  Complete the current one.
2874                if (mCurAppTimeTracker != null) {
2875                    mCurAppTimeTracker.stop();
2876                    mHandler.obtainMessage(
2877                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2878                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2879                    mCurAppTimeTracker = null;
2880                }
2881                if (r.appTimeTracker != null) {
2882                    mCurAppTimeTracker = r.appTimeTracker;
2883                    startTimeTrackingFocusedActivityLocked();
2884                }
2885            } else {
2886                startTimeTrackingFocusedActivityLocked();
2887            }
2888        } else {
2889            r.appTimeTracker = null;
2890        }
2891        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2892        // TODO: Probably not, because we don't want to resume voice on switching
2893        // back to this activity
2894        if (r.task.voiceInteractor != null) {
2895            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2896        } else {
2897            finishRunningVoiceLocked();
2898            IVoiceInteractionSession session;
2899            if (last != null && ((session = last.task.voiceSession) != null
2900                    || (session = last.voiceSession) != null)) {
2901                // We had been in a voice interaction session, but now focused has
2902                // move to something different.  Just finish the session, we can't
2903                // return to it and retain the proper state and synchronization with
2904                // the voice interaction service.
2905                finishVoiceTask(session);
2906            }
2907        }
2908        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2909            mWindowManager.setFocusedApp(r.appToken, true);
2910        }
2911        applyUpdateLockStateLocked(r);
2912        applyUpdateVrModeLocked(r);
2913        if (mFocusedActivity.userId != mLastFocusedUserId) {
2914            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2915            mHandler.obtainMessage(
2916                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2917            mLastFocusedUserId = mFocusedActivity.userId;
2918        }
2919
2920        // Log a warning if the focused app is changed during the process. This could
2921        // indicate a problem of the focus setting logic!
2922        if (mFocusedActivity != r) Slog.w(TAG,
2923                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2924        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2925
2926        EventLogTags.writeAmFocusedActivity(
2927                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2928                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2929                reason);
2930        return true;
2931    }
2932
2933    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2934        if (mFocusedActivity != goingAway) {
2935            return;
2936        }
2937
2938        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2939        if (focusedStack != null) {
2940            final ActivityRecord top = focusedStack.topActivity();
2941            if (top != null && top.userId != mLastFocusedUserId) {
2942                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2943                mHandler.sendMessage(
2944                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2945                mLastFocusedUserId = top.userId;
2946            }
2947        }
2948
2949        // Try to move focus to another activity if possible.
2950        if (setFocusedActivityLocked(
2951                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2952            return;
2953        }
2954
2955        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2956                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2957        mFocusedActivity = null;
2958        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2959    }
2960
2961    @Override
2962    public void setFocusedStack(int stackId) {
2963        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2964        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2965        final long callingId = Binder.clearCallingIdentity();
2966        try {
2967            synchronized (this) {
2968                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2969                if (stack == null) {
2970                    return;
2971                }
2972                final ActivityRecord r = stack.topRunningActivityLocked();
2973                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2974                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2975                }
2976            }
2977        } finally {
2978            Binder.restoreCallingIdentity(callingId);
2979        }
2980    }
2981
2982    @Override
2983    public void setFocusedTask(int taskId) {
2984        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2985        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2986        final long callingId = Binder.clearCallingIdentity();
2987        try {
2988            synchronized (this) {
2989                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2990                if (task == null) {
2991                    return;
2992                }
2993                final ActivityRecord r = task.topRunningActivityLocked();
2994                if (setFocusedActivityLocked(r, "setFocusedTask")) {
2995                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2996                }
2997            }
2998        } finally {
2999            Binder.restoreCallingIdentity(callingId);
3000        }
3001    }
3002
3003    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3004    @Override
3005    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3006        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3007        synchronized (this) {
3008            if (listener != null) {
3009                mTaskStackListeners.register(listener);
3010            }
3011        }
3012    }
3013
3014    @Override
3015    public void notifyActivityDrawn(IBinder token) {
3016        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3017        synchronized (this) {
3018            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3019            if (r != null) {
3020                r.task.stack.notifyActivityDrawnLocked(r);
3021            }
3022        }
3023    }
3024
3025    final void applyUpdateLockStateLocked(ActivityRecord r) {
3026        // Modifications to the UpdateLock state are done on our handler, outside
3027        // the activity manager's locks.  The new state is determined based on the
3028        // state *now* of the relevant activity record.  The object is passed to
3029        // the handler solely for logging detail, not to be consulted/modified.
3030        final boolean nextState = r != null && r.immersive;
3031        mHandler.sendMessage(
3032                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3033    }
3034
3035    final void applyUpdateVrModeLocked(ActivityRecord r) {
3036        mHandler.sendMessage(
3037                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3038    }
3039
3040    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3041        mHandler.sendMessage(
3042                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3043    }
3044
3045    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3046        Message msg = Message.obtain();
3047        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3048        msg.obj = r.task.askedCompatMode ? null : r;
3049        mUiHandler.sendMessage(msg);
3050    }
3051
3052    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3053            String what, Object obj, ProcessRecord srcApp) {
3054        app.lastActivityTime = now;
3055
3056        if (app.activities.size() > 0) {
3057            // Don't want to touch dependent processes that are hosting activities.
3058            return index;
3059        }
3060
3061        int lrui = mLruProcesses.lastIndexOf(app);
3062        if (lrui < 0) {
3063            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3064                    + what + " " + obj + " from " + srcApp);
3065            return index;
3066        }
3067
3068        if (lrui >= index) {
3069            // Don't want to cause this to move dependent processes *back* in the
3070            // list as if they were less frequently used.
3071            return index;
3072        }
3073
3074        if (lrui >= mLruProcessActivityStart) {
3075            // Don't want to touch dependent processes that are hosting activities.
3076            return index;
3077        }
3078
3079        mLruProcesses.remove(lrui);
3080        if (index > 0) {
3081            index--;
3082        }
3083        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3084                + " in LRU list: " + app);
3085        mLruProcesses.add(index, app);
3086        return index;
3087    }
3088
3089    static void killProcessGroup(int uid, int pid) {
3090        if (sKillHandler != null) {
3091            sKillHandler.sendMessage(
3092                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3093        } else {
3094            Slog.w(TAG, "Asked to kill process group before system bringup!");
3095            Process.killProcessGroup(uid, pid);
3096        }
3097    }
3098
3099    final void removeLruProcessLocked(ProcessRecord app) {
3100        int lrui = mLruProcesses.lastIndexOf(app);
3101        if (lrui >= 0) {
3102            if (!app.killed) {
3103                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3104                Process.killProcessQuiet(app.pid);
3105                killProcessGroup(app.uid, app.pid);
3106            }
3107            if (lrui <= mLruProcessActivityStart) {
3108                mLruProcessActivityStart--;
3109            }
3110            if (lrui <= mLruProcessServiceStart) {
3111                mLruProcessServiceStart--;
3112            }
3113            mLruProcesses.remove(lrui);
3114        }
3115    }
3116
3117    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3118            ProcessRecord client) {
3119        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3120                || app.treatLikeActivity;
3121        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3122        if (!activityChange && hasActivity) {
3123            // The process has activities, so we are only allowing activity-based adjustments
3124            // to move it.  It should be kept in the front of the list with other
3125            // processes that have activities, and we don't want those to change their
3126            // order except due to activity operations.
3127            return;
3128        }
3129
3130        mLruSeq++;
3131        final long now = SystemClock.uptimeMillis();
3132        app.lastActivityTime = now;
3133
3134        // First a quick reject: if the app is already at the position we will
3135        // put it, then there is nothing to do.
3136        if (hasActivity) {
3137            final int N = mLruProcesses.size();
3138            if (N > 0 && mLruProcesses.get(N-1) == app) {
3139                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3140                return;
3141            }
3142        } else {
3143            if (mLruProcessServiceStart > 0
3144                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3145                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3146                return;
3147            }
3148        }
3149
3150        int lrui = mLruProcesses.lastIndexOf(app);
3151
3152        if (app.persistent && lrui >= 0) {
3153            // We don't care about the position of persistent processes, as long as
3154            // they are in the list.
3155            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3156            return;
3157        }
3158
3159        /* In progress: compute new position first, so we can avoid doing work
3160           if the process is not actually going to move.  Not yet working.
3161        int addIndex;
3162        int nextIndex;
3163        boolean inActivity = false, inService = false;
3164        if (hasActivity) {
3165            // Process has activities, put it at the very tipsy-top.
3166            addIndex = mLruProcesses.size();
3167            nextIndex = mLruProcessServiceStart;
3168            inActivity = true;
3169        } else if (hasService) {
3170            // Process has services, put it at the top of the service list.
3171            addIndex = mLruProcessActivityStart;
3172            nextIndex = mLruProcessServiceStart;
3173            inActivity = true;
3174            inService = true;
3175        } else  {
3176            // Process not otherwise of interest, it goes to the top of the non-service area.
3177            addIndex = mLruProcessServiceStart;
3178            if (client != null) {
3179                int clientIndex = mLruProcesses.lastIndexOf(client);
3180                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3181                        + app);
3182                if (clientIndex >= 0 && addIndex > clientIndex) {
3183                    addIndex = clientIndex;
3184                }
3185            }
3186            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3187        }
3188
3189        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3190                + mLruProcessActivityStart + "): " + app);
3191        */
3192
3193        if (lrui >= 0) {
3194            if (lrui < mLruProcessActivityStart) {
3195                mLruProcessActivityStart--;
3196            }
3197            if (lrui < mLruProcessServiceStart) {
3198                mLruProcessServiceStart--;
3199            }
3200            /*
3201            if (addIndex > lrui) {
3202                addIndex--;
3203            }
3204            if (nextIndex > lrui) {
3205                nextIndex--;
3206            }
3207            */
3208            mLruProcesses.remove(lrui);
3209        }
3210
3211        /*
3212        mLruProcesses.add(addIndex, app);
3213        if (inActivity) {
3214            mLruProcessActivityStart++;
3215        }
3216        if (inService) {
3217            mLruProcessActivityStart++;
3218        }
3219        */
3220
3221        int nextIndex;
3222        if (hasActivity) {
3223            final int N = mLruProcesses.size();
3224            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3225                // Process doesn't have activities, but has clients with
3226                // activities...  move it up, but one below the top (the top
3227                // should always have a real activity).
3228                if (DEBUG_LRU) Slog.d(TAG_LRU,
3229                        "Adding to second-top of LRU activity list: " + app);
3230                mLruProcesses.add(N - 1, app);
3231                // To keep it from spamming the LRU list (by making a bunch of clients),
3232                // we will push down any other entries owned by the app.
3233                final int uid = app.info.uid;
3234                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3235                    ProcessRecord subProc = mLruProcesses.get(i);
3236                    if (subProc.info.uid == uid) {
3237                        // We want to push this one down the list.  If the process after
3238                        // it is for the same uid, however, don't do so, because we don't
3239                        // want them internally to be re-ordered.
3240                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3241                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3242                                    "Pushing uid " + uid + " swapping at " + i + ": "
3243                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3244                            ProcessRecord tmp = mLruProcesses.get(i);
3245                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3246                            mLruProcesses.set(i - 1, tmp);
3247                            i--;
3248                        }
3249                    } else {
3250                        // A gap, we can stop here.
3251                        break;
3252                    }
3253                }
3254            } else {
3255                // Process has activities, put it at the very tipsy-top.
3256                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3257                mLruProcesses.add(app);
3258            }
3259            nextIndex = mLruProcessServiceStart;
3260        } else if (hasService) {
3261            // Process has services, put it at the top of the service list.
3262            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3263            mLruProcesses.add(mLruProcessActivityStart, app);
3264            nextIndex = mLruProcessServiceStart;
3265            mLruProcessActivityStart++;
3266        } else  {
3267            // Process not otherwise of interest, it goes to the top of the non-service area.
3268            int index = mLruProcessServiceStart;
3269            if (client != null) {
3270                // If there is a client, don't allow the process to be moved up higher
3271                // in the list than that client.
3272                int clientIndex = mLruProcesses.lastIndexOf(client);
3273                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3274                        + " when updating " + app);
3275                if (clientIndex <= lrui) {
3276                    // Don't allow the client index restriction to push it down farther in the
3277                    // list than it already is.
3278                    clientIndex = lrui;
3279                }
3280                if (clientIndex >= 0 && index > clientIndex) {
3281                    index = clientIndex;
3282                }
3283            }
3284            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3285            mLruProcesses.add(index, app);
3286            nextIndex = index-1;
3287            mLruProcessActivityStart++;
3288            mLruProcessServiceStart++;
3289        }
3290
3291        // If the app is currently using a content provider or service,
3292        // bump those processes as well.
3293        for (int j=app.connections.size()-1; j>=0; j--) {
3294            ConnectionRecord cr = app.connections.valueAt(j);
3295            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3296                    && cr.binding.service.app != null
3297                    && cr.binding.service.app.lruSeq != mLruSeq
3298                    && !cr.binding.service.app.persistent) {
3299                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3300                        "service connection", cr, app);
3301            }
3302        }
3303        for (int j=app.conProviders.size()-1; j>=0; j--) {
3304            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3305            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3306                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3307                        "provider reference", cpr, app);
3308            }
3309        }
3310    }
3311
3312    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3313        if (uid == Process.SYSTEM_UID) {
3314            // The system gets to run in any process.  If there are multiple
3315            // processes with the same uid, just pick the first (this
3316            // should never happen).
3317            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3318            if (procs == null) return null;
3319            final int procCount = procs.size();
3320            for (int i = 0; i < procCount; i++) {
3321                final int procUid = procs.keyAt(i);
3322                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3323                    // Don't use an app process or different user process for system component.
3324                    continue;
3325                }
3326                return procs.valueAt(i);
3327            }
3328        }
3329        ProcessRecord proc = mProcessNames.get(processName, uid);
3330        if (false && proc != null && !keepIfLarge
3331                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3332                && proc.lastCachedPss >= 4000) {
3333            // Turn this condition on to cause killing to happen regularly, for testing.
3334            if (proc.baseProcessTracker != null) {
3335                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3336            }
3337            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3338        } else if (proc != null && !keepIfLarge
3339                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3340                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3341            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3342            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3343                if (proc.baseProcessTracker != null) {
3344                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3345                }
3346                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3347            }
3348        }
3349        return proc;
3350    }
3351
3352    void notifyPackageUse(String packageName, int reason) {
3353        IPackageManager pm = AppGlobals.getPackageManager();
3354        try {
3355            pm.notifyPackageUse(packageName, reason);
3356        } catch (RemoteException e) {
3357        }
3358    }
3359
3360    boolean isNextTransitionForward() {
3361        int transit = mWindowManager.getPendingAppTransition();
3362        return transit == TRANSIT_ACTIVITY_OPEN
3363                || transit == TRANSIT_TASK_OPEN
3364                || transit == TRANSIT_TASK_TO_FRONT;
3365    }
3366
3367    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3368            String processName, String abiOverride, int uid, Runnable crashHandler) {
3369        synchronized(this) {
3370            ApplicationInfo info = new ApplicationInfo();
3371            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3372            // For isolated processes, the former contains the parent's uid and the latter the
3373            // actual uid of the isolated process.
3374            // In the special case introduced by this method (which is, starting an isolated
3375            // process directly from the SystemServer without an actual parent app process) the
3376            // closest thing to a parent's uid is SYSTEM_UID.
3377            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3378            // the |isolated| logic in the ProcessRecord constructor.
3379            info.uid = Process.SYSTEM_UID;
3380            info.processName = processName;
3381            info.className = entryPoint;
3382            info.packageName = "android";
3383            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3384                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3385                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3386                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3387                    crashHandler);
3388            return proc != null ? proc.pid : 0;
3389        }
3390    }
3391
3392    final ProcessRecord startProcessLocked(String processName,
3393            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3394            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3395            boolean isolated, boolean keepIfLarge) {
3396        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3397                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3398                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3399                null /* crashHandler */);
3400    }
3401
3402    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3403            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3404            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3405            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3406        long startTime = SystemClock.elapsedRealtime();
3407        ProcessRecord app;
3408        if (!isolated) {
3409            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3410            checkTime(startTime, "startProcess: after getProcessRecord");
3411
3412            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3413                // If we are in the background, then check to see if this process
3414                // is bad.  If so, we will just silently fail.
3415                if (mAppErrors.isBadProcessLocked(info)) {
3416                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3417                            + "/" + info.processName);
3418                    return null;
3419                }
3420            } else {
3421                // When the user is explicitly starting a process, then clear its
3422                // crash count so that we won't make it bad until they see at
3423                // least one crash dialog again, and make the process good again
3424                // if it had been bad.
3425                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3426                        + "/" + info.processName);
3427                mAppErrors.resetProcessCrashTimeLocked(info);
3428                if (mAppErrors.isBadProcessLocked(info)) {
3429                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3430                            UserHandle.getUserId(info.uid), info.uid,
3431                            info.processName);
3432                    mAppErrors.clearBadProcessLocked(info);
3433                    if (app != null) {
3434                        app.bad = false;
3435                    }
3436                }
3437            }
3438        } else {
3439            // If this is an isolated process, it can't re-use an existing process.
3440            app = null;
3441        }
3442
3443        // app launch boost for big.little configurations
3444        // use cpusets to migrate freshly launched tasks to big cores
3445        synchronized(ActivityManagerService.this) {
3446            nativeMigrateToBoost();
3447            mIsBoosted = true;
3448            mBoostStartTime = SystemClock.uptimeMillis();
3449            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3450            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3451        }
3452
3453        // We don't have to do anything more if:
3454        // (1) There is an existing application record; and
3455        // (2) The caller doesn't think it is dead, OR there is no thread
3456        //     object attached to it so we know it couldn't have crashed; and
3457        // (3) There is a pid assigned to it, so it is either starting or
3458        //     already running.
3459        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3460                + " app=" + app + " knownToBeDead=" + knownToBeDead
3461                + " thread=" + (app != null ? app.thread : null)
3462                + " pid=" + (app != null ? app.pid : -1));
3463        if (app != null && app.pid > 0) {
3464            if (!knownToBeDead || app.thread == null) {
3465                // We already have the app running, or are waiting for it to
3466                // come up (we have a pid but not yet its thread), so keep it.
3467                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3468                // If this is a new package in the process, add the package to the list
3469                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3470                checkTime(startTime, "startProcess: done, added package to proc");
3471                return app;
3472            }
3473
3474            // An application record is attached to a previous process,
3475            // clean it up now.
3476            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3477            checkTime(startTime, "startProcess: bad proc running, killing");
3478            killProcessGroup(app.uid, app.pid);
3479            handleAppDiedLocked(app, true, true);
3480            checkTime(startTime, "startProcess: done killing old proc");
3481        }
3482
3483        String hostingNameStr = hostingName != null
3484                ? hostingName.flattenToShortString() : null;
3485
3486        if (app == null) {
3487            checkTime(startTime, "startProcess: creating new process record");
3488            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3489            if (app == null) {
3490                Slog.w(TAG, "Failed making new process record for "
3491                        + processName + "/" + info.uid + " isolated=" + isolated);
3492                return null;
3493            }
3494            app.crashHandler = crashHandler;
3495            checkTime(startTime, "startProcess: done creating new process record");
3496        } else {
3497            // If this is a new package in the process, add the package to the list
3498            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3499            checkTime(startTime, "startProcess: added package to existing proc");
3500        }
3501
3502        // If the system is not ready yet, then hold off on starting this
3503        // process until it is.
3504        if (!mProcessesReady
3505                && !isAllowedWhileBooting(info)
3506                && !allowWhileBooting) {
3507            if (!mProcessesOnHold.contains(app)) {
3508                mProcessesOnHold.add(app);
3509            }
3510            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3511                    "System not ready, putting on hold: " + app);
3512            checkTime(startTime, "startProcess: returning with proc on hold");
3513            return app;
3514        }
3515
3516        checkTime(startTime, "startProcess: stepping in to startProcess");
3517        startProcessLocked(
3518                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3519        checkTime(startTime, "startProcess: done starting proc!");
3520        return (app.pid != 0) ? app : null;
3521    }
3522
3523    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3524        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3525    }
3526
3527    private final void startProcessLocked(ProcessRecord app,
3528            String hostingType, String hostingNameStr) {
3529        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3530                null /* entryPoint */, null /* entryPointArgs */);
3531    }
3532
3533    private final void startProcessLocked(ProcessRecord app, String hostingType,
3534            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3535        long startTime = SystemClock.elapsedRealtime();
3536        if (app.pid > 0 && app.pid != MY_PID) {
3537            checkTime(startTime, "startProcess: removing from pids map");
3538            synchronized (mPidsSelfLocked) {
3539                mPidsSelfLocked.remove(app.pid);
3540                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3541            }
3542            checkTime(startTime, "startProcess: done removing from pids map");
3543            app.setPid(0);
3544        }
3545
3546        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3547                "startProcessLocked removing on hold: " + app);
3548        mProcessesOnHold.remove(app);
3549
3550        checkTime(startTime, "startProcess: starting to update cpu stats");
3551        updateCpuStats();
3552        checkTime(startTime, "startProcess: done updating cpu stats");
3553
3554        try {
3555            try {
3556                final int userId = UserHandle.getUserId(app.uid);
3557                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3558            } catch (RemoteException e) {
3559                throw e.rethrowAsRuntimeException();
3560            }
3561
3562            int uid = app.uid;
3563            int[] gids = null;
3564            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3565            if (!app.isolated) {
3566                int[] permGids = null;
3567                try {
3568                    checkTime(startTime, "startProcess: getting gids from package manager");
3569                    final IPackageManager pm = AppGlobals.getPackageManager();
3570                    permGids = pm.getPackageGids(app.info.packageName,
3571                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3572                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3573                            MountServiceInternal.class);
3574                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3575                            app.info.packageName);
3576                } catch (RemoteException e) {
3577                    throw e.rethrowAsRuntimeException();
3578                }
3579
3580                /*
3581                 * Add shared application and profile GIDs so applications can share some
3582                 * resources like shared libraries and access user-wide resources
3583                 */
3584                if (ArrayUtils.isEmpty(permGids)) {
3585                    gids = new int[2];
3586                } else {
3587                    gids = new int[permGids.length + 2];
3588                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3589                }
3590                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3591                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3592            }
3593            checkTime(startTime, "startProcess: building args");
3594            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3595                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3596                        && mTopComponent != null
3597                        && app.processName.equals(mTopComponent.getPackageName())) {
3598                    uid = 0;
3599                }
3600                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3601                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3602                    uid = 0;
3603                }
3604            }
3605            int debugFlags = 0;
3606            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3607                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3608                // Also turn on CheckJNI for debuggable apps. It's quite
3609                // awkward to turn on otherwise.
3610                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3611            }
3612            // Run the app in safe mode if its manifest requests so or the
3613            // system is booted in safe mode.
3614            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3615                mSafeMode == true) {
3616                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3617            }
3618            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3619                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3620            }
3621            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3622            if ("true".equals(genDebugInfoProperty)) {
3623                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3624            }
3625            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3626                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3627            }
3628            if ("1".equals(SystemProperties.get("debug.assert"))) {
3629                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3630            }
3631            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3632                // Enable all debug flags required by the native debugger.
3633                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3634                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3635                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3636                mNativeDebuggingApp = null;
3637            }
3638
3639            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3640            if (requiredAbi == null) {
3641                requiredAbi = Build.SUPPORTED_ABIS[0];
3642            }
3643
3644            String instructionSet = null;
3645            if (app.info.primaryCpuAbi != null) {
3646                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3647            }
3648
3649            app.gids = gids;
3650            app.requiredAbi = requiredAbi;
3651            app.instructionSet = instructionSet;
3652
3653            // Start the process.  It will either succeed and return a result containing
3654            // the PID of the new process, or else throw a RuntimeException.
3655            boolean isActivityProcess = (entryPoint == null);
3656            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3657            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3658                    app.processName);
3659            checkTime(startTime, "startProcess: asking zygote to start proc");
3660            Process.ProcessStartResult startResult = Process.start(entryPoint,
3661                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3662                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3663                    app.info.dataDir, entryPointArgs);
3664            checkTime(startTime, "startProcess: returned from zygote!");
3665            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3666
3667            if (app.isolated) {
3668                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3669            }
3670            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3671            checkTime(startTime, "startProcess: done updating battery stats");
3672
3673            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3674                    UserHandle.getUserId(uid), startResult.pid, uid,
3675                    app.processName, hostingType,
3676                    hostingNameStr != null ? hostingNameStr : "");
3677
3678            try {
3679                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3680                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3681            } catch (RemoteException ex) {
3682                // Ignore
3683            }
3684
3685            if (app.persistent) {
3686                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3687            }
3688
3689            checkTime(startTime, "startProcess: building log message");
3690            StringBuilder buf = mStringBuilder;
3691            buf.setLength(0);
3692            buf.append("Start proc ");
3693            buf.append(startResult.pid);
3694            buf.append(':');
3695            buf.append(app.processName);
3696            buf.append('/');
3697            UserHandle.formatUid(buf, uid);
3698            if (!isActivityProcess) {
3699                buf.append(" [");
3700                buf.append(entryPoint);
3701                buf.append("]");
3702            }
3703            buf.append(" for ");
3704            buf.append(hostingType);
3705            if (hostingNameStr != null) {
3706                buf.append(" ");
3707                buf.append(hostingNameStr);
3708            }
3709            Slog.i(TAG, buf.toString());
3710            app.setPid(startResult.pid);
3711            app.usingWrapper = startResult.usingWrapper;
3712            app.removed = false;
3713            app.killed = false;
3714            app.killedByAm = false;
3715            checkTime(startTime, "startProcess: starting to update pids map");
3716            synchronized (mPidsSelfLocked) {
3717                this.mPidsSelfLocked.put(startResult.pid, app);
3718                if (isActivityProcess) {
3719                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3720                    msg.obj = app;
3721                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3722                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3723                }
3724            }
3725            checkTime(startTime, "startProcess: done updating pids map");
3726        } catch (RuntimeException e) {
3727            Slog.e(TAG, "Failure starting process " + app.processName, e);
3728
3729            // Something went very wrong while trying to start this process; one
3730            // common case is when the package is frozen due to an active
3731            // upgrade. To recover, clean up any active bookkeeping related to
3732            // starting this process. (We already invoked this method once when
3733            // the package was initially frozen through KILL_APPLICATION_MSG, so
3734            // it doesn't hurt to use it again.)
3735            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3736                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3737        }
3738    }
3739
3740    void updateUsageStats(ActivityRecord component, boolean resumed) {
3741        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3742                "updateUsageStats: comp=" + component + "res=" + resumed);
3743        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3744        if (resumed) {
3745            if (mUsageStatsService != null) {
3746                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3747                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3748            }
3749            synchronized (stats) {
3750                stats.noteActivityResumedLocked(component.app.uid);
3751            }
3752        } else {
3753            if (mUsageStatsService != null) {
3754                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3755                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3756            }
3757            synchronized (stats) {
3758                stats.noteActivityPausedLocked(component.app.uid);
3759            }
3760        }
3761    }
3762
3763    Intent getHomeIntent() {
3764        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3765        intent.setComponent(mTopComponent);
3766        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3767        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3768            intent.addCategory(Intent.CATEGORY_HOME);
3769        }
3770        return intent;
3771    }
3772
3773    boolean startHomeActivityLocked(int userId, String reason) {
3774        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3775                && mTopAction == null) {
3776            // We are running in factory test mode, but unable to find
3777            // the factory test app, so just sit around displaying the
3778            // error message and don't try to start anything.
3779            return false;
3780        }
3781        Intent intent = getHomeIntent();
3782        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3783        if (aInfo != null) {
3784            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3785            // Don't do this if the home app is currently being
3786            // instrumented.
3787            aInfo = new ActivityInfo(aInfo);
3788            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3789            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3790                    aInfo.applicationInfo.uid, true);
3791            if (app == null || app.instrumentationClass == null) {
3792                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3793                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3794            }
3795        }
3796
3797        return true;
3798    }
3799
3800    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3801        ActivityInfo ai = null;
3802        ComponentName comp = intent.getComponent();
3803        try {
3804            if (comp != null) {
3805                // Factory test.
3806                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3807            } else {
3808                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3809                        intent,
3810                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3811                        flags, userId);
3812
3813                if (info != null) {
3814                    ai = info.activityInfo;
3815                }
3816            }
3817        } catch (RemoteException e) {
3818            // ignore
3819        }
3820
3821        return ai;
3822    }
3823
3824    /**
3825     * Starts the "new version setup screen" if appropriate.
3826     */
3827    void startSetupActivityLocked() {
3828        // Only do this once per boot.
3829        if (mCheckedForSetup) {
3830            return;
3831        }
3832
3833        // We will show this screen if the current one is a different
3834        // version than the last one shown, and we are not running in
3835        // low-level factory test mode.
3836        final ContentResolver resolver = mContext.getContentResolver();
3837        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3838                Settings.Global.getInt(resolver,
3839                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3840            mCheckedForSetup = true;
3841
3842            // See if we should be showing the platform update setup UI.
3843            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3844            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3845                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3846            if (!ris.isEmpty()) {
3847                final ResolveInfo ri = ris.get(0);
3848                String vers = ri.activityInfo.metaData != null
3849                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3850                        : null;
3851                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3852                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3853                            Intent.METADATA_SETUP_VERSION);
3854                }
3855                String lastVers = Settings.Secure.getString(
3856                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3857                if (vers != null && !vers.equals(lastVers)) {
3858                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3859                    intent.setComponent(new ComponentName(
3860                            ri.activityInfo.packageName, ri.activityInfo.name));
3861                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3862                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3863                            null, 0, 0, 0, null, false, false, null, null, null);
3864                }
3865            }
3866        }
3867    }
3868
3869    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3870        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3871    }
3872
3873    void enforceNotIsolatedCaller(String caller) {
3874        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3875            throw new SecurityException("Isolated process not allowed to call " + caller);
3876        }
3877    }
3878
3879    void enforceShellRestriction(String restriction, int userHandle) {
3880        if (Binder.getCallingUid() == Process.SHELL_UID) {
3881            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3882                throw new SecurityException("Shell does not have permission to access user "
3883                        + userHandle);
3884            }
3885        }
3886    }
3887
3888    @Override
3889    public int getFrontActivityScreenCompatMode() {
3890        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3891        synchronized (this) {
3892            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3893        }
3894    }
3895
3896    @Override
3897    public void setFrontActivityScreenCompatMode(int mode) {
3898        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3899                "setFrontActivityScreenCompatMode");
3900        synchronized (this) {
3901            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3902        }
3903    }
3904
3905    @Override
3906    public int getPackageScreenCompatMode(String packageName) {
3907        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3908        synchronized (this) {
3909            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3910        }
3911    }
3912
3913    @Override
3914    public void setPackageScreenCompatMode(String packageName, int mode) {
3915        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3916                "setPackageScreenCompatMode");
3917        synchronized (this) {
3918            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3919        }
3920    }
3921
3922    @Override
3923    public boolean getPackageAskScreenCompat(String packageName) {
3924        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3925        synchronized (this) {
3926            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3927        }
3928    }
3929
3930    @Override
3931    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3932        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3933                "setPackageAskScreenCompat");
3934        synchronized (this) {
3935            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3936        }
3937    }
3938
3939    private boolean hasUsageStatsPermission(String callingPackage) {
3940        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3941                Binder.getCallingUid(), callingPackage);
3942        if (mode == AppOpsManager.MODE_DEFAULT) {
3943            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3944                    == PackageManager.PERMISSION_GRANTED;
3945        }
3946        return mode == AppOpsManager.MODE_ALLOWED;
3947    }
3948
3949    @Override
3950    public int getPackageProcessState(String packageName, String callingPackage) {
3951        if (!hasUsageStatsPermission(callingPackage)) {
3952            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3953                    "getPackageProcessState");
3954        }
3955
3956        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3957        synchronized (this) {
3958            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3959                final ProcessRecord proc = mLruProcesses.get(i);
3960                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3961                        || procState > proc.setProcState) {
3962                    boolean found = false;
3963                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3964                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3965                            procState = proc.setProcState;
3966                            found = true;
3967                        }
3968                    }
3969                    if (proc.pkgDeps != null && !found) {
3970                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3971                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3972                                procState = proc.setProcState;
3973                                break;
3974                            }
3975                        }
3976                    }
3977                }
3978            }
3979        }
3980        return procState;
3981    }
3982
3983    @Override
3984    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3985        synchronized (this) {
3986            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3987            if (app == null) {
3988                return false;
3989            }
3990            if (app.trimMemoryLevel < level && app.thread != null &&
3991                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3992                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3993                try {
3994                    app.thread.scheduleTrimMemory(level);
3995                    app.trimMemoryLevel = level;
3996                    return true;
3997                } catch (RemoteException e) {
3998                    // Fallthrough to failure case.
3999                }
4000            }
4001        }
4002        return false;
4003    }
4004
4005    private void dispatchProcessesChanged() {
4006        int N;
4007        synchronized (this) {
4008            N = mPendingProcessChanges.size();
4009            if (mActiveProcessChanges.length < N) {
4010                mActiveProcessChanges = new ProcessChangeItem[N];
4011            }
4012            mPendingProcessChanges.toArray(mActiveProcessChanges);
4013            mPendingProcessChanges.clear();
4014            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4015                    "*** Delivering " + N + " process changes");
4016        }
4017
4018        int i = mProcessObservers.beginBroadcast();
4019        while (i > 0) {
4020            i--;
4021            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4022            if (observer != null) {
4023                try {
4024                    for (int j=0; j<N; j++) {
4025                        ProcessChangeItem item = mActiveProcessChanges[j];
4026                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4027                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4028                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4029                                    + item.uid + ": " + item.foregroundActivities);
4030                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4031                                    item.foregroundActivities);
4032                        }
4033                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4034                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4035                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4036                                    + ": " + item.processState);
4037                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4038                        }
4039                    }
4040                } catch (RemoteException e) {
4041                }
4042            }
4043        }
4044        mProcessObservers.finishBroadcast();
4045
4046        synchronized (this) {
4047            for (int j=0; j<N; j++) {
4048                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4049            }
4050        }
4051    }
4052
4053    private void dispatchProcessDied(int pid, int uid) {
4054        int i = mProcessObservers.beginBroadcast();
4055        while (i > 0) {
4056            i--;
4057            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4058            if (observer != null) {
4059                try {
4060                    observer.onProcessDied(pid, uid);
4061                } catch (RemoteException e) {
4062                }
4063            }
4064        }
4065        mProcessObservers.finishBroadcast();
4066    }
4067
4068    private void dispatchUidsChanged() {
4069        int N;
4070        synchronized (this) {
4071            N = mPendingUidChanges.size();
4072            if (mActiveUidChanges.length < N) {
4073                mActiveUidChanges = new UidRecord.ChangeItem[N];
4074            }
4075            for (int i=0; i<N; i++) {
4076                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4077                mActiveUidChanges[i] = change;
4078                if (change.uidRecord != null) {
4079                    change.uidRecord.pendingChange = null;
4080                    change.uidRecord = null;
4081                }
4082            }
4083            mPendingUidChanges.clear();
4084            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4085                    "*** Delivering " + N + " uid changes");
4086        }
4087
4088        if (mLocalPowerManager != null) {
4089            for (int j=0; j<N; j++) {
4090                UidRecord.ChangeItem item = mActiveUidChanges[j];
4091                if (item.change == UidRecord.CHANGE_GONE
4092                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4093                    mLocalPowerManager.uidGone(item.uid);
4094                } else {
4095                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4096                }
4097            }
4098        }
4099
4100        int i = mUidObservers.beginBroadcast();
4101        while (i > 0) {
4102            i--;
4103            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4104            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4105            if (observer != null) {
4106                try {
4107                    for (int j=0; j<N; j++) {
4108                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4109                        final int change = item.change;
4110                        UidRecord validateUid = null;
4111                        if (VALIDATE_UID_STATES && i == 0) {
4112                            validateUid = mValidateUids.get(item.uid);
4113                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4114                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4115                                validateUid = new UidRecord(item.uid);
4116                                mValidateUids.put(item.uid, validateUid);
4117                            }
4118                        }
4119                        if (change == UidRecord.CHANGE_IDLE
4120                                || change == UidRecord.CHANGE_GONE_IDLE) {
4121                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4122                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4123                                        "UID idle uid=" + item.uid);
4124                                observer.onUidIdle(item.uid);
4125                            }
4126                            if (VALIDATE_UID_STATES && i == 0) {
4127                                if (validateUid != null) {
4128                                    validateUid.idle = true;
4129                                }
4130                            }
4131                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4132                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4133                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4134                                        "UID active uid=" + item.uid);
4135                                observer.onUidActive(item.uid);
4136                            }
4137                            if (VALIDATE_UID_STATES && i == 0) {
4138                                validateUid.idle = false;
4139                            }
4140                        }
4141                        if (change == UidRecord.CHANGE_GONE
4142                                || change == UidRecord.CHANGE_GONE_IDLE) {
4143                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4144                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4145                                        "UID gone uid=" + item.uid);
4146                                observer.onUidGone(item.uid);
4147                            }
4148                            if (VALIDATE_UID_STATES && i == 0) {
4149                                if (validateUid != null) {
4150                                    mValidateUids.remove(item.uid);
4151                                }
4152                            }
4153                        } else {
4154                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4155                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4156                                        "UID CHANGED uid=" + item.uid
4157                                                + ": " + item.processState);
4158                                observer.onUidStateChanged(item.uid, item.processState);
4159                            }
4160                            if (VALIDATE_UID_STATES && i == 0) {
4161                                validateUid.curProcState = validateUid.setProcState
4162                                        = item.processState;
4163                            }
4164                        }
4165                    }
4166                } catch (RemoteException e) {
4167                }
4168            }
4169        }
4170        mUidObservers.finishBroadcast();
4171
4172        synchronized (this) {
4173            for (int j=0; j<N; j++) {
4174                mAvailUidChanges.add(mActiveUidChanges[j]);
4175            }
4176        }
4177    }
4178
4179    @Override
4180    public final int startActivity(IApplicationThread caller, String callingPackage,
4181            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4182            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4183        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4184                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4185                UserHandle.getCallingUserId());
4186    }
4187
4188    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4189        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4190        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4191                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4192                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4193
4194        // TODO: Switch to user app stacks here.
4195        String mimeType = intent.getType();
4196        final Uri data = intent.getData();
4197        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4198            mimeType = getProviderMimeType(data, userId);
4199        }
4200        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4201
4202        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4203        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4204                null, 0, 0, null, null, null, null, false, userId, container, null);
4205    }
4206
4207    @Override
4208    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4209            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4210            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4211        enforceNotIsolatedCaller("startActivity");
4212        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4213                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4214        // TODO: Switch to user app stacks here.
4215        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4216                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4217                profilerInfo, null, null, bOptions, false, userId, null, null);
4218    }
4219
4220    @Override
4221    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4222            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4223            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4224            int userId) {
4225
4226        // This is very dangerous -- it allows you to perform a start activity (including
4227        // permission grants) as any app that may launch one of your own activities.  So
4228        // we will only allow this to be done from activities that are part of the core framework,
4229        // and then only when they are running as the system.
4230        final ActivityRecord sourceRecord;
4231        final int targetUid;
4232        final String targetPackage;
4233        synchronized (this) {
4234            if (resultTo == null) {
4235                throw new SecurityException("Must be called from an activity");
4236            }
4237            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4238            if (sourceRecord == null) {
4239                throw new SecurityException("Called with bad activity token: " + resultTo);
4240            }
4241            if (!sourceRecord.info.packageName.equals("android")) {
4242                throw new SecurityException(
4243                        "Must be called from an activity that is declared in the android package");
4244            }
4245            if (sourceRecord.app == null) {
4246                throw new SecurityException("Called without a process attached to activity");
4247            }
4248            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4249                // This is still okay, as long as this activity is running under the
4250                // uid of the original calling activity.
4251                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4252                    throw new SecurityException(
4253                            "Calling activity in uid " + sourceRecord.app.uid
4254                                    + " must be system uid or original calling uid "
4255                                    + sourceRecord.launchedFromUid);
4256                }
4257            }
4258            if (ignoreTargetSecurity) {
4259                if (intent.getComponent() == null) {
4260                    throw new SecurityException(
4261                            "Component must be specified with ignoreTargetSecurity");
4262                }
4263                if (intent.getSelector() != null) {
4264                    throw new SecurityException(
4265                            "Selector not allowed with ignoreTargetSecurity");
4266                }
4267            }
4268            targetUid = sourceRecord.launchedFromUid;
4269            targetPackage = sourceRecord.launchedFromPackage;
4270        }
4271
4272        if (userId == UserHandle.USER_NULL) {
4273            userId = UserHandle.getUserId(sourceRecord.app.uid);
4274        }
4275
4276        // TODO: Switch to user app stacks here.
4277        try {
4278            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4279                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4280                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4281            return ret;
4282        } catch (SecurityException e) {
4283            // XXX need to figure out how to propagate to original app.
4284            // A SecurityException here is generally actually a fault of the original
4285            // calling activity (such as a fairly granting permissions), so propagate it
4286            // back to them.
4287            /*
4288            StringBuilder msg = new StringBuilder();
4289            msg.append("While launching");
4290            msg.append(intent.toString());
4291            msg.append(": ");
4292            msg.append(e.getMessage());
4293            */
4294            throw e;
4295        }
4296    }
4297
4298    @Override
4299    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4300            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4301            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4302        enforceNotIsolatedCaller("startActivityAndWait");
4303        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4304                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4305        WaitResult res = new WaitResult();
4306        // TODO: Switch to user app stacks here.
4307        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4308                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4309                bOptions, false, userId, null, null);
4310        return res;
4311    }
4312
4313    @Override
4314    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4315            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4316            int startFlags, Configuration config, Bundle bOptions, int userId) {
4317        enforceNotIsolatedCaller("startActivityWithConfig");
4318        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4319                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4320        // TODO: Switch to user app stacks here.
4321        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4322                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4323                null, null, config, bOptions, false, userId, null, null);
4324        return ret;
4325    }
4326
4327    @Override
4328    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4329            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4330            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4331            throws TransactionTooLargeException {
4332        enforceNotIsolatedCaller("startActivityIntentSender");
4333        // Refuse possible leaked file descriptors
4334        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4335            throw new IllegalArgumentException("File descriptors passed in Intent");
4336        }
4337
4338        IIntentSender sender = intent.getTarget();
4339        if (!(sender instanceof PendingIntentRecord)) {
4340            throw new IllegalArgumentException("Bad PendingIntent object");
4341        }
4342
4343        PendingIntentRecord pir = (PendingIntentRecord)sender;
4344
4345        synchronized (this) {
4346            // If this is coming from the currently resumed activity, it is
4347            // effectively saying that app switches are allowed at this point.
4348            final ActivityStack stack = getFocusedStack();
4349            if (stack.mResumedActivity != null &&
4350                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4351                mAppSwitchesAllowedTime = 0;
4352            }
4353        }
4354        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4355                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4356        return ret;
4357    }
4358
4359    @Override
4360    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4361            Intent intent, String resolvedType, IVoiceInteractionSession session,
4362            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4363            Bundle bOptions, int userId) {
4364        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4365                != PackageManager.PERMISSION_GRANTED) {
4366            String msg = "Permission Denial: startVoiceActivity() from pid="
4367                    + Binder.getCallingPid()
4368                    + ", uid=" + Binder.getCallingUid()
4369                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4370            Slog.w(TAG, msg);
4371            throw new SecurityException(msg);
4372        }
4373        if (session == null || interactor == null) {
4374            throw new NullPointerException("null session or interactor");
4375        }
4376        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4377                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4378        // TODO: Switch to user app stacks here.
4379        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4380                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4381                null, bOptions, false, userId, null, null);
4382    }
4383
4384    @Override
4385    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4386            throws RemoteException {
4387        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4388        synchronized (this) {
4389            ActivityRecord activity = getFocusedStack().topActivity();
4390            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4391                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4392            }
4393            if (mRunningVoice != null || activity.task.voiceSession != null
4394                    || activity.voiceSession != null) {
4395                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4396                return;
4397            }
4398            if (activity.pendingVoiceInteractionStart) {
4399                Slog.w(TAG, "Pending start of voice interaction already.");
4400                return;
4401            }
4402            activity.pendingVoiceInteractionStart = true;
4403        }
4404        LocalServices.getService(VoiceInteractionManagerInternal.class)
4405                .startLocalVoiceInteraction(callingActivity, options);
4406    }
4407
4408    @Override
4409    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4410        LocalServices.getService(VoiceInteractionManagerInternal.class)
4411                .stopLocalVoiceInteraction(callingActivity);
4412    }
4413
4414    @Override
4415    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4416        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4417                .supportsLocalVoiceInteraction();
4418    }
4419
4420    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4421            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4422        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4423        if (activityToCallback == null) return;
4424        activityToCallback.setVoiceSessionLocked(voiceSession);
4425
4426        // Inform the activity
4427        try {
4428            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4429                    voiceInteractor);
4430            long token = Binder.clearCallingIdentity();
4431            try {
4432                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4433            } finally {
4434                Binder.restoreCallingIdentity(token);
4435            }
4436            // TODO: VI Should we cache the activity so that it's easier to find later
4437            // rather than scan through all the stacks and activities?
4438        } catch (RemoteException re) {
4439            activityToCallback.clearVoiceSessionLocked();
4440            // TODO: VI Should this terminate the voice session?
4441        }
4442    }
4443
4444    @Override
4445    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4446        synchronized (this) {
4447            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4448                if (keepAwake) {
4449                    mVoiceWakeLock.acquire();
4450                } else {
4451                    mVoiceWakeLock.release();
4452                }
4453            }
4454        }
4455    }
4456
4457    @Override
4458    public boolean startNextMatchingActivity(IBinder callingActivity,
4459            Intent intent, Bundle bOptions) {
4460        // Refuse possible leaked file descriptors
4461        if (intent != null && intent.hasFileDescriptors() == true) {
4462            throw new IllegalArgumentException("File descriptors passed in Intent");
4463        }
4464        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4465
4466        synchronized (this) {
4467            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4468            if (r == null) {
4469                ActivityOptions.abort(options);
4470                return false;
4471            }
4472            if (r.app == null || r.app.thread == null) {
4473                // The caller is not running...  d'oh!
4474                ActivityOptions.abort(options);
4475                return false;
4476            }
4477            intent = new Intent(intent);
4478            // The caller is not allowed to change the data.
4479            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4480            // And we are resetting to find the next component...
4481            intent.setComponent(null);
4482
4483            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4484
4485            ActivityInfo aInfo = null;
4486            try {
4487                List<ResolveInfo> resolves =
4488                    AppGlobals.getPackageManager().queryIntentActivities(
4489                            intent, r.resolvedType,
4490                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4491                            UserHandle.getCallingUserId()).getList();
4492
4493                // Look for the original activity in the list...
4494                final int N = resolves != null ? resolves.size() : 0;
4495                for (int i=0; i<N; i++) {
4496                    ResolveInfo rInfo = resolves.get(i);
4497                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4498                            && rInfo.activityInfo.name.equals(r.info.name)) {
4499                        // We found the current one...  the next matching is
4500                        // after it.
4501                        i++;
4502                        if (i<N) {
4503                            aInfo = resolves.get(i).activityInfo;
4504                        }
4505                        if (debug) {
4506                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4507                                    + "/" + r.info.name);
4508                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4509                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4510                        }
4511                        break;
4512                    }
4513                }
4514            } catch (RemoteException e) {
4515            }
4516
4517            if (aInfo == null) {
4518                // Nobody who is next!
4519                ActivityOptions.abort(options);
4520                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4521                return false;
4522            }
4523
4524            intent.setComponent(new ComponentName(
4525                    aInfo.applicationInfo.packageName, aInfo.name));
4526            intent.setFlags(intent.getFlags()&~(
4527                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4528                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4529                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4530                    Intent.FLAG_ACTIVITY_NEW_TASK));
4531
4532            // Okay now we need to start the new activity, replacing the
4533            // currently running activity.  This is a little tricky because
4534            // we want to start the new one as if the current one is finished,
4535            // but not finish the current one first so that there is no flicker.
4536            // And thus...
4537            final boolean wasFinishing = r.finishing;
4538            r.finishing = true;
4539
4540            // Propagate reply information over to the new activity.
4541            final ActivityRecord resultTo = r.resultTo;
4542            final String resultWho = r.resultWho;
4543            final int requestCode = r.requestCode;
4544            r.resultTo = null;
4545            if (resultTo != null) {
4546                resultTo.removeResultsLocked(r, resultWho, requestCode);
4547            }
4548
4549            final long origId = Binder.clearCallingIdentity();
4550            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4551                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4552                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4553                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4554                    false, false, null, null, null);
4555            Binder.restoreCallingIdentity(origId);
4556
4557            r.finishing = wasFinishing;
4558            if (res != ActivityManager.START_SUCCESS) {
4559                return false;
4560            }
4561            return true;
4562        }
4563    }
4564
4565    @Override
4566    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4567        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4568            String msg = "Permission Denial: startActivityFromRecents called without " +
4569                    START_TASKS_FROM_RECENTS;
4570            Slog.w(TAG, msg);
4571            throw new SecurityException(msg);
4572        }
4573        final long origId = Binder.clearCallingIdentity();
4574        try {
4575            synchronized (this) {
4576                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4577            }
4578        } finally {
4579            Binder.restoreCallingIdentity(origId);
4580        }
4581    }
4582
4583    final int startActivityInPackage(int uid, String callingPackage,
4584            Intent intent, String resolvedType, IBinder resultTo,
4585            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4586            IActivityContainer container, TaskRecord inTask) {
4587
4588        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4589                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4590
4591        // TODO: Switch to user app stacks here.
4592        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4593                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4594                null, null, null, bOptions, false, userId, container, inTask);
4595        return ret;
4596    }
4597
4598    @Override
4599    public final int startActivities(IApplicationThread caller, String callingPackage,
4600            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4601            int userId) {
4602        enforceNotIsolatedCaller("startActivities");
4603        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4604                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4605        // TODO: Switch to user app stacks here.
4606        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4607                resolvedTypes, resultTo, bOptions, userId);
4608        return ret;
4609    }
4610
4611    final int startActivitiesInPackage(int uid, String callingPackage,
4612            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4613            Bundle bOptions, int userId) {
4614
4615        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4616                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4617        // TODO: Switch to user app stacks here.
4618        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4619                resultTo, bOptions, userId);
4620        return ret;
4621    }
4622
4623    @Override
4624    public void reportActivityFullyDrawn(IBinder token) {
4625        synchronized (this) {
4626            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4627            if (r == null) {
4628                return;
4629            }
4630            r.reportFullyDrawnLocked();
4631        }
4632    }
4633
4634    @Override
4635    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4636        synchronized (this) {
4637            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4638            if (r == null) {
4639                return;
4640            }
4641            TaskRecord task = r.task;
4642            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4643                // Fixed screen orientation isn't supported when activities aren't in full screen
4644                // mode.
4645                return;
4646            }
4647            final long origId = Binder.clearCallingIdentity();
4648            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4649            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4650                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4651            if (config != null) {
4652                r.frozenBeforeDestroy = true;
4653                if (!updateConfigurationLocked(config, r, false)) {
4654                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4655                }
4656            }
4657            Binder.restoreCallingIdentity(origId);
4658        }
4659    }
4660
4661    @Override
4662    public int getRequestedOrientation(IBinder token) {
4663        synchronized (this) {
4664            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4665            if (r == null) {
4666                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4667            }
4668            return mWindowManager.getAppOrientation(r.appToken);
4669        }
4670    }
4671
4672    /**
4673     * This is the internal entry point for handling Activity.finish().
4674     *
4675     * @param token The Binder token referencing the Activity we want to finish.
4676     * @param resultCode Result code, if any, from this Activity.
4677     * @param resultData Result data (Intent), if any, from this Activity.
4678     * @param finishTask Whether to finish the task associated with this Activity.
4679     *
4680     * @return Returns true if the activity successfully finished, or false if it is still running.
4681     */
4682    @Override
4683    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4684            int finishTask) {
4685        // Refuse possible leaked file descriptors
4686        if (resultData != null && resultData.hasFileDescriptors() == true) {
4687            throw new IllegalArgumentException("File descriptors passed in Intent");
4688        }
4689
4690        synchronized(this) {
4691            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4692            if (r == null) {
4693                return true;
4694            }
4695            // Keep track of the root activity of the task before we finish it
4696            TaskRecord tr = r.task;
4697            ActivityRecord rootR = tr.getRootActivity();
4698            if (rootR == null) {
4699                Slog.w(TAG, "Finishing task with all activities already finished");
4700            }
4701            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4702            // finish.
4703            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4704                    mStackSupervisor.isLastLockedTask(tr)) {
4705                Slog.i(TAG, "Not finishing task in lock task mode");
4706                mStackSupervisor.showLockTaskToast();
4707                return false;
4708            }
4709            if (mController != null) {
4710                // Find the first activity that is not finishing.
4711                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4712                if (next != null) {
4713                    // ask watcher if this is allowed
4714                    boolean resumeOK = true;
4715                    try {
4716                        resumeOK = mController.activityResuming(next.packageName);
4717                    } catch (RemoteException e) {
4718                        mController = null;
4719                        Watchdog.getInstance().setActivityController(null);
4720                    }
4721
4722                    if (!resumeOK) {
4723                        Slog.i(TAG, "Not finishing activity because controller resumed");
4724                        return false;
4725                    }
4726                }
4727            }
4728            final long origId = Binder.clearCallingIdentity();
4729            try {
4730                boolean res;
4731                final boolean finishWithRootActivity =
4732                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4733                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4734                        || (finishWithRootActivity && r == rootR)) {
4735                    // If requested, remove the task that is associated to this activity only if it
4736                    // was the root activity in the task. The result code and data is ignored
4737                    // because we don't support returning them across task boundaries. Also, to
4738                    // keep backwards compatibility we remove the task from recents when finishing
4739                    // task with root activity.
4740                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4741                    if (!res) {
4742                        Slog.i(TAG, "Removing task failed to finish activity");
4743                    }
4744                } else {
4745                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4746                            resultData, "app-request", true);
4747                    if (!res) {
4748                        Slog.i(TAG, "Failed to finish by app-request");
4749                    }
4750                }
4751                return res;
4752            } finally {
4753                Binder.restoreCallingIdentity(origId);
4754            }
4755        }
4756    }
4757
4758    @Override
4759    public final void finishHeavyWeightApp() {
4760        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4761                != PackageManager.PERMISSION_GRANTED) {
4762            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4763                    + Binder.getCallingPid()
4764                    + ", uid=" + Binder.getCallingUid()
4765                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4766            Slog.w(TAG, msg);
4767            throw new SecurityException(msg);
4768        }
4769
4770        synchronized(this) {
4771            if (mHeavyWeightProcess == null) {
4772                return;
4773            }
4774
4775            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4776            for (int i = 0; i < activities.size(); i++) {
4777                ActivityRecord r = activities.get(i);
4778                if (!r.finishing && r.isInStackLocked()) {
4779                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4780                            null, "finish-heavy", true);
4781                }
4782            }
4783
4784            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4785                    mHeavyWeightProcess.userId, 0));
4786            mHeavyWeightProcess = null;
4787        }
4788    }
4789
4790    @Override
4791    public void crashApplication(int uid, int initialPid, String packageName,
4792            String message) {
4793        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4794                != PackageManager.PERMISSION_GRANTED) {
4795            String msg = "Permission Denial: crashApplication() from pid="
4796                    + Binder.getCallingPid()
4797                    + ", uid=" + Binder.getCallingUid()
4798                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4799            Slog.w(TAG, msg);
4800            throw new SecurityException(msg);
4801        }
4802
4803        synchronized(this) {
4804            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4805        }
4806    }
4807
4808    @Override
4809    public final void finishSubActivity(IBinder token, String resultWho,
4810            int requestCode) {
4811        synchronized(this) {
4812            final long origId = Binder.clearCallingIdentity();
4813            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4814            if (r != null) {
4815                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4816            }
4817            Binder.restoreCallingIdentity(origId);
4818        }
4819    }
4820
4821    @Override
4822    public boolean finishActivityAffinity(IBinder token) {
4823        synchronized(this) {
4824            final long origId = Binder.clearCallingIdentity();
4825            try {
4826                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4827                if (r == null) {
4828                    return false;
4829                }
4830
4831                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4832                // can finish.
4833                final TaskRecord task = r.task;
4834                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4835                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4836                    mStackSupervisor.showLockTaskToast();
4837                    return false;
4838                }
4839                return task.stack.finishActivityAffinityLocked(r);
4840            } finally {
4841                Binder.restoreCallingIdentity(origId);
4842            }
4843        }
4844    }
4845
4846    @Override
4847    public void finishVoiceTask(IVoiceInteractionSession session) {
4848        synchronized (this) {
4849            final long origId = Binder.clearCallingIdentity();
4850            try {
4851                // TODO: VI Consider treating local voice interactions and voice tasks
4852                // differently here
4853                mStackSupervisor.finishVoiceTask(session);
4854            } finally {
4855                Binder.restoreCallingIdentity(origId);
4856            }
4857        }
4858
4859    }
4860
4861    @Override
4862    public boolean releaseActivityInstance(IBinder token) {
4863        synchronized(this) {
4864            final long origId = Binder.clearCallingIdentity();
4865            try {
4866                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4867                if (r == null) {
4868                    return false;
4869                }
4870                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4871            } finally {
4872                Binder.restoreCallingIdentity(origId);
4873            }
4874        }
4875    }
4876
4877    @Override
4878    public void releaseSomeActivities(IApplicationThread appInt) {
4879        synchronized(this) {
4880            final long origId = Binder.clearCallingIdentity();
4881            try {
4882                ProcessRecord app = getRecordForAppLocked(appInt);
4883                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4884            } finally {
4885                Binder.restoreCallingIdentity(origId);
4886            }
4887        }
4888    }
4889
4890    @Override
4891    public boolean willActivityBeVisible(IBinder token) {
4892        synchronized(this) {
4893            ActivityStack stack = ActivityRecord.getStackLocked(token);
4894            if (stack != null) {
4895                return stack.willActivityBeVisibleLocked(token);
4896            }
4897            return false;
4898        }
4899    }
4900
4901    @Override
4902    public void overridePendingTransition(IBinder token, String packageName,
4903            int enterAnim, int exitAnim) {
4904        synchronized(this) {
4905            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4906            if (self == null) {
4907                return;
4908            }
4909
4910            final long origId = Binder.clearCallingIdentity();
4911
4912            if (self.state == ActivityState.RESUMED
4913                    || self.state == ActivityState.PAUSING) {
4914                mWindowManager.overridePendingAppTransition(packageName,
4915                        enterAnim, exitAnim, null);
4916            }
4917
4918            Binder.restoreCallingIdentity(origId);
4919        }
4920    }
4921
4922    /**
4923     * Main function for removing an existing process from the activity manager
4924     * as a result of that process going away.  Clears out all connections
4925     * to the process.
4926     */
4927    private final void handleAppDiedLocked(ProcessRecord app,
4928            boolean restarting, boolean allowRestart) {
4929        int pid = app.pid;
4930        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4931        if (!kept && !restarting) {
4932            removeLruProcessLocked(app);
4933            if (pid > 0) {
4934                ProcessList.remove(pid);
4935            }
4936        }
4937
4938        if (mProfileProc == app) {
4939            clearProfilerLocked();
4940        }
4941
4942        // Remove this application's activities from active lists.
4943        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4944
4945        app.activities.clear();
4946
4947        if (app.instrumentationClass != null) {
4948            Slog.w(TAG, "Crash of app " + app.processName
4949                  + " running instrumentation " + app.instrumentationClass);
4950            Bundle info = new Bundle();
4951            info.putString("shortMsg", "Process crashed.");
4952            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4953        }
4954
4955        if (!restarting && hasVisibleActivities
4956                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4957            // If there was nothing to resume, and we are not already restarting this process, but
4958            // there is a visible activity that is hosted by the process...  then make sure all
4959            // visible activities are running, taking care of restarting this process.
4960            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4961        }
4962    }
4963
4964    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4965        IBinder threadBinder = thread.asBinder();
4966        // Find the application record.
4967        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4968            ProcessRecord rec = mLruProcesses.get(i);
4969            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4970                return i;
4971            }
4972        }
4973        return -1;
4974    }
4975
4976    final ProcessRecord getRecordForAppLocked(
4977            IApplicationThread thread) {
4978        if (thread == null) {
4979            return null;
4980        }
4981
4982        int appIndex = getLRURecordIndexForAppLocked(thread);
4983        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4984    }
4985
4986    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4987        // If there are no longer any background processes running,
4988        // and the app that died was not running instrumentation,
4989        // then tell everyone we are now low on memory.
4990        boolean haveBg = false;
4991        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4992            ProcessRecord rec = mLruProcesses.get(i);
4993            if (rec.thread != null
4994                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4995                haveBg = true;
4996                break;
4997            }
4998        }
4999
5000        if (!haveBg) {
5001            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5002            if (doReport) {
5003                long now = SystemClock.uptimeMillis();
5004                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5005                    doReport = false;
5006                } else {
5007                    mLastMemUsageReportTime = now;
5008                }
5009            }
5010            final ArrayList<ProcessMemInfo> memInfos
5011                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5012            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5013            long now = SystemClock.uptimeMillis();
5014            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5015                ProcessRecord rec = mLruProcesses.get(i);
5016                if (rec == dyingProc || rec.thread == null) {
5017                    continue;
5018                }
5019                if (doReport) {
5020                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5021                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5022                }
5023                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5024                    // The low memory report is overriding any current
5025                    // state for a GC request.  Make sure to do
5026                    // heavy/important/visible/foreground processes first.
5027                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5028                        rec.lastRequestedGc = 0;
5029                    } else {
5030                        rec.lastRequestedGc = rec.lastLowMemory;
5031                    }
5032                    rec.reportLowMemory = true;
5033                    rec.lastLowMemory = now;
5034                    mProcessesToGc.remove(rec);
5035                    addProcessToGcListLocked(rec);
5036                }
5037            }
5038            if (doReport) {
5039                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5040                mHandler.sendMessage(msg);
5041            }
5042            scheduleAppGcsLocked();
5043        }
5044    }
5045
5046    final void appDiedLocked(ProcessRecord app) {
5047       appDiedLocked(app, app.pid, app.thread, false);
5048    }
5049
5050    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5051            boolean fromBinderDied) {
5052        // First check if this ProcessRecord is actually active for the pid.
5053        synchronized (mPidsSelfLocked) {
5054            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5055            if (curProc != app) {
5056                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5057                return;
5058            }
5059        }
5060
5061        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5062        synchronized (stats) {
5063            stats.noteProcessDiedLocked(app.info.uid, pid);
5064        }
5065
5066        if (!app.killed) {
5067            if (!fromBinderDied) {
5068                Process.killProcessQuiet(pid);
5069            }
5070            killProcessGroup(app.uid, pid);
5071            app.killed = true;
5072        }
5073
5074        // Clean up already done if the process has been re-started.
5075        if (app.pid == pid && app.thread != null &&
5076                app.thread.asBinder() == thread.asBinder()) {
5077            boolean doLowMem = app.instrumentationClass == null;
5078            boolean doOomAdj = doLowMem;
5079            if (!app.killedByAm) {
5080                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5081                        + ") has died");
5082                mAllowLowerMemLevel = true;
5083            } else {
5084                // Note that we always want to do oom adj to update our state with the
5085                // new number of procs.
5086                mAllowLowerMemLevel = false;
5087                doLowMem = false;
5088            }
5089            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5090            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5091                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5092            handleAppDiedLocked(app, false, true);
5093
5094            if (doOomAdj) {
5095                updateOomAdjLocked();
5096            }
5097            if (doLowMem) {
5098                doLowMemReportIfNeededLocked(app);
5099            }
5100        } else if (app.pid != pid) {
5101            // A new process has already been started.
5102            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5103                    + ") has died and restarted (pid " + app.pid + ").");
5104            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5105        } else if (DEBUG_PROCESSES) {
5106            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5107                    + thread.asBinder());
5108        }
5109    }
5110
5111    /**
5112     * If a stack trace dump file is configured, dump process stack traces.
5113     * @param clearTraces causes the dump file to be erased prior to the new
5114     *    traces being written, if true; when false, the new traces will be
5115     *    appended to any existing file content.
5116     * @param firstPids of dalvik VM processes to dump stack traces for first
5117     * @param lastPids of dalvik VM processes to dump stack traces for last
5118     * @param nativeProcs optional list of native process names to dump stack crawls
5119     * @return file containing stack traces, or null if no dump file is configured
5120     */
5121    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5122            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5123        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5124        if (tracesPath == null || tracesPath.length() == 0) {
5125            return null;
5126        }
5127
5128        File tracesFile = new File(tracesPath);
5129        try {
5130            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5131            tracesFile.createNewFile();
5132            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5133        } catch (IOException e) {
5134            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5135            return null;
5136        }
5137
5138        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5139        return tracesFile;
5140    }
5141
5142    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5143            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5144        // Use a FileObserver to detect when traces finish writing.
5145        // The order of traces is considered important to maintain for legibility.
5146        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5147            @Override
5148            public synchronized void onEvent(int event, String path) { notify(); }
5149        };
5150
5151        try {
5152            observer.startWatching();
5153
5154            // First collect all of the stacks of the most important pids.
5155            if (firstPids != null) {
5156                try {
5157                    int num = firstPids.size();
5158                    for (int i = 0; i < num; i++) {
5159                        synchronized (observer) {
5160                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5161                                    + firstPids.get(i));
5162                            final long sime = SystemClock.elapsedRealtime();
5163                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5164                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5165                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5166                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5167                        }
5168                    }
5169                } catch (InterruptedException e) {
5170                    Slog.wtf(TAG, e);
5171                }
5172            }
5173
5174            // Next collect the stacks of the native pids
5175            if (nativeProcs != null) {
5176                int[] pids = Process.getPidsForCommands(nativeProcs);
5177                if (pids != null) {
5178                    for (int pid : pids) {
5179                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5180                        final long sime = SystemClock.elapsedRealtime();
5181                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5182                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5183                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5184                    }
5185                }
5186            }
5187
5188            // Lastly, measure CPU usage.
5189            if (processCpuTracker != null) {
5190                processCpuTracker.init();
5191                System.gc();
5192                processCpuTracker.update();
5193                try {
5194                    synchronized (processCpuTracker) {
5195                        processCpuTracker.wait(500); // measure over 1/2 second.
5196                    }
5197                } catch (InterruptedException e) {
5198                }
5199                processCpuTracker.update();
5200
5201                // We'll take the stack crawls of just the top apps using CPU.
5202                final int N = processCpuTracker.countWorkingStats();
5203                int numProcs = 0;
5204                for (int i=0; i<N && numProcs<5; i++) {
5205                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5206                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5207                        numProcs++;
5208                        try {
5209                            synchronized (observer) {
5210                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5211                                        + stats.pid);
5212                                final long stime = SystemClock.elapsedRealtime();
5213                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5214                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5215                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5216                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5217                            }
5218                        } catch (InterruptedException e) {
5219                            Slog.wtf(TAG, e);
5220                        }
5221                    } else if (DEBUG_ANR) {
5222                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5223                                + stats.pid);
5224                    }
5225                }
5226            }
5227        } finally {
5228            observer.stopWatching();
5229        }
5230    }
5231
5232    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5233        if (true || IS_USER_BUILD) {
5234            return;
5235        }
5236        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5237        if (tracesPath == null || tracesPath.length() == 0) {
5238            return;
5239        }
5240
5241        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5242        StrictMode.allowThreadDiskWrites();
5243        try {
5244            final File tracesFile = new File(tracesPath);
5245            final File tracesDir = tracesFile.getParentFile();
5246            final File tracesTmp = new File(tracesDir, "__tmp__");
5247            try {
5248                if (tracesFile.exists()) {
5249                    tracesTmp.delete();
5250                    tracesFile.renameTo(tracesTmp);
5251                }
5252                StringBuilder sb = new StringBuilder();
5253                Time tobj = new Time();
5254                tobj.set(System.currentTimeMillis());
5255                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5256                sb.append(": ");
5257                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5258                sb.append(" since ");
5259                sb.append(msg);
5260                FileOutputStream fos = new FileOutputStream(tracesFile);
5261                fos.write(sb.toString().getBytes());
5262                if (app == null) {
5263                    fos.write("\n*** No application process!".getBytes());
5264                }
5265                fos.close();
5266                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5267            } catch (IOException e) {
5268                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5269                return;
5270            }
5271
5272            if (app != null) {
5273                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5274                firstPids.add(app.pid);
5275                dumpStackTraces(tracesPath, firstPids, null, null, null);
5276            }
5277
5278            File lastTracesFile = null;
5279            File curTracesFile = null;
5280            for (int i=9; i>=0; i--) {
5281                String name = String.format(Locale.US, "slow%02d.txt", i);
5282                curTracesFile = new File(tracesDir, name);
5283                if (curTracesFile.exists()) {
5284                    if (lastTracesFile != null) {
5285                        curTracesFile.renameTo(lastTracesFile);
5286                    } else {
5287                        curTracesFile.delete();
5288                    }
5289                }
5290                lastTracesFile = curTracesFile;
5291            }
5292            tracesFile.renameTo(curTracesFile);
5293            if (tracesTmp.exists()) {
5294                tracesTmp.renameTo(tracesFile);
5295            }
5296        } finally {
5297            StrictMode.setThreadPolicy(oldPolicy);
5298        }
5299    }
5300
5301    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5302        if (!mLaunchWarningShown) {
5303            mLaunchWarningShown = true;
5304            mUiHandler.post(new Runnable() {
5305                @Override
5306                public void run() {
5307                    synchronized (ActivityManagerService.this) {
5308                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5309                        d.show();
5310                        mUiHandler.postDelayed(new Runnable() {
5311                            @Override
5312                            public void run() {
5313                                synchronized (ActivityManagerService.this) {
5314                                    d.dismiss();
5315                                    mLaunchWarningShown = false;
5316                                }
5317                            }
5318                        }, 4000);
5319                    }
5320                }
5321            });
5322        }
5323    }
5324
5325    @Override
5326    public boolean clearApplicationUserData(final String packageName,
5327            final IPackageDataObserver observer, int userId) {
5328        enforceNotIsolatedCaller("clearApplicationUserData");
5329        int uid = Binder.getCallingUid();
5330        int pid = Binder.getCallingPid();
5331        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5332                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5333
5334        final DevicePolicyManagerInternal dpmi = LocalServices
5335                .getService(DevicePolicyManagerInternal.class);
5336        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5337            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5338        }
5339
5340        long callingId = Binder.clearCallingIdentity();
5341        try {
5342            IPackageManager pm = AppGlobals.getPackageManager();
5343            int pkgUid = -1;
5344            synchronized(this) {
5345                try {
5346                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5347                } catch (RemoteException e) {
5348                }
5349                if (pkgUid == -1) {
5350                    Slog.w(TAG, "Invalid packageName: " + packageName);
5351                    if (observer != null) {
5352                        try {
5353                            observer.onRemoveCompleted(packageName, false);
5354                        } catch (RemoteException e) {
5355                            Slog.i(TAG, "Observer no longer exists.");
5356                        }
5357                    }
5358                    return false;
5359                }
5360                if (uid == pkgUid || checkComponentPermission(
5361                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5362                        pid, uid, -1, true)
5363                        == PackageManager.PERMISSION_GRANTED) {
5364                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5365                } else {
5366                    throw new SecurityException("PID " + pid + " does not have permission "
5367                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5368                                    + " of package " + packageName);
5369                }
5370
5371                // Remove all tasks match the cleared application package and user
5372                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5373                    final TaskRecord tr = mRecentTasks.get(i);
5374                    final String taskPackageName =
5375                            tr.getBaseIntent().getComponent().getPackageName();
5376                    if (tr.userId != userId) continue;
5377                    if (!taskPackageName.equals(packageName)) continue;
5378                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5379                }
5380            }
5381
5382            try {
5383                // Clear application user data
5384                pm.clearApplicationUserData(packageName, observer, userId);
5385
5386                synchronized(this) {
5387                    // Remove all permissions granted from/to this package
5388                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5389                }
5390
5391                // Remove all zen rules created by this package; revoke it's zen access.
5392                INotificationManager inm = NotificationManager.getService();
5393                inm.removeAutomaticZenRules(packageName);
5394                inm.setNotificationPolicyAccessGranted(packageName, false);
5395
5396                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5397                        Uri.fromParts("package", packageName, null));
5398                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5399                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5400                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5401                        null, null, 0, null, null, null, null, false, false, userId);
5402            } catch (RemoteException e) {
5403            }
5404        } finally {
5405            Binder.restoreCallingIdentity(callingId);
5406        }
5407        return true;
5408    }
5409
5410    @Override
5411    public void killBackgroundProcesses(final String packageName, int userId) {
5412        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5413                != PackageManager.PERMISSION_GRANTED &&
5414                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5415                        != PackageManager.PERMISSION_GRANTED) {
5416            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5417                    + Binder.getCallingPid()
5418                    + ", uid=" + Binder.getCallingUid()
5419                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5420            Slog.w(TAG, msg);
5421            throw new SecurityException(msg);
5422        }
5423
5424        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5425                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5426        long callingId = Binder.clearCallingIdentity();
5427        try {
5428            IPackageManager pm = AppGlobals.getPackageManager();
5429            synchronized(this) {
5430                int appId = -1;
5431                try {
5432                    appId = UserHandle.getAppId(
5433                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5434                } catch (RemoteException e) {
5435                }
5436                if (appId == -1) {
5437                    Slog.w(TAG, "Invalid packageName: " + packageName);
5438                    return;
5439                }
5440                killPackageProcessesLocked(packageName, appId, userId,
5441                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5442            }
5443        } finally {
5444            Binder.restoreCallingIdentity(callingId);
5445        }
5446    }
5447
5448    @Override
5449    public void killAllBackgroundProcesses() {
5450        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5451                != PackageManager.PERMISSION_GRANTED) {
5452            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5453                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5454                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5455            Slog.w(TAG, msg);
5456            throw new SecurityException(msg);
5457        }
5458
5459        final long callingId = Binder.clearCallingIdentity();
5460        try {
5461            synchronized (this) {
5462                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5463                final int NP = mProcessNames.getMap().size();
5464                for (int ip = 0; ip < NP; ip++) {
5465                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5466                    final int NA = apps.size();
5467                    for (int ia = 0; ia < NA; ia++) {
5468                        final ProcessRecord app = apps.valueAt(ia);
5469                        if (app.persistent) {
5470                            // We don't kill persistent processes.
5471                            continue;
5472                        }
5473                        if (app.removed) {
5474                            procs.add(app);
5475                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5476                            app.removed = true;
5477                            procs.add(app);
5478                        }
5479                    }
5480                }
5481
5482                final int N = procs.size();
5483                for (int i = 0; i < N; i++) {
5484                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5485                }
5486
5487                mAllowLowerMemLevel = true;
5488
5489                updateOomAdjLocked();
5490                doLowMemReportIfNeededLocked(null);
5491            }
5492        } finally {
5493            Binder.restoreCallingIdentity(callingId);
5494        }
5495    }
5496
5497    /**
5498     * Kills all background processes, except those matching any of the
5499     * specified properties.
5500     *
5501     * @param minTargetSdk the target SDK version at or above which to preserve
5502     *                     processes, or {@code -1} to ignore the target SDK
5503     * @param maxProcState the process state at or below which to preserve
5504     *                     processes, or {@code -1} to ignore the process state
5505     */
5506    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5507        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5508                != PackageManager.PERMISSION_GRANTED) {
5509            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5510                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5511                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5512            Slog.w(TAG, msg);
5513            throw new SecurityException(msg);
5514        }
5515
5516        final long callingId = Binder.clearCallingIdentity();
5517        try {
5518            synchronized (this) {
5519                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5520                final int NP = mProcessNames.getMap().size();
5521                for (int ip = 0; ip < NP; ip++) {
5522                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5523                    final int NA = apps.size();
5524                    for (int ia = 0; ia < NA; ia++) {
5525                        final ProcessRecord app = apps.valueAt(ia);
5526                        if (app.removed) {
5527                            procs.add(app);
5528                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5529                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5530                            app.removed = true;
5531                            procs.add(app);
5532                        }
5533                    }
5534                }
5535
5536                final int N = procs.size();
5537                for (int i = 0; i < N; i++) {
5538                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5539                }
5540            }
5541        } finally {
5542            Binder.restoreCallingIdentity(callingId);
5543        }
5544    }
5545
5546    @Override
5547    public void forceStopPackage(final String packageName, int userId) {
5548        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5549                != PackageManager.PERMISSION_GRANTED) {
5550            String msg = "Permission Denial: forceStopPackage() from pid="
5551                    + Binder.getCallingPid()
5552                    + ", uid=" + Binder.getCallingUid()
5553                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5554            Slog.w(TAG, msg);
5555            throw new SecurityException(msg);
5556        }
5557        final int callingPid = Binder.getCallingPid();
5558        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5559                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5560        long callingId = Binder.clearCallingIdentity();
5561        try {
5562            IPackageManager pm = AppGlobals.getPackageManager();
5563            synchronized(this) {
5564                int[] users = userId == UserHandle.USER_ALL
5565                        ? mUserController.getUsers() : new int[] { userId };
5566                for (int user : users) {
5567                    int pkgUid = -1;
5568                    try {
5569                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5570                                user);
5571                    } catch (RemoteException e) {
5572                    }
5573                    if (pkgUid == -1) {
5574                        Slog.w(TAG, "Invalid packageName: " + packageName);
5575                        continue;
5576                    }
5577                    try {
5578                        pm.setPackageStoppedState(packageName, true, user);
5579                    } catch (RemoteException e) {
5580                    } catch (IllegalArgumentException e) {
5581                        Slog.w(TAG, "Failed trying to unstop package "
5582                                + packageName + ": " + e);
5583                    }
5584                    if (mUserController.isUserRunningLocked(user, 0)) {
5585                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5586                    }
5587                }
5588            }
5589        } finally {
5590            Binder.restoreCallingIdentity(callingId);
5591        }
5592    }
5593
5594    @Override
5595    public void addPackageDependency(String packageName) {
5596        synchronized (this) {
5597            int callingPid = Binder.getCallingPid();
5598            if (callingPid == Process.myPid()) {
5599                //  Yeah, um, no.
5600                return;
5601            }
5602            ProcessRecord proc;
5603            synchronized (mPidsSelfLocked) {
5604                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5605            }
5606            if (proc != null) {
5607                if (proc.pkgDeps == null) {
5608                    proc.pkgDeps = new ArraySet<String>(1);
5609                }
5610                proc.pkgDeps.add(packageName);
5611            }
5612        }
5613    }
5614
5615    /*
5616     * The pkg name and app id have to be specified.
5617     */
5618    @Override
5619    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5620        if (pkg == null) {
5621            return;
5622        }
5623        // Make sure the uid is valid.
5624        if (appid < 0) {
5625            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5626            return;
5627        }
5628        int callerUid = Binder.getCallingUid();
5629        // Only the system server can kill an application
5630        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5631            // Post an aysnc message to kill the application
5632            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5633            msg.arg1 = appid;
5634            msg.arg2 = 0;
5635            Bundle bundle = new Bundle();
5636            bundle.putString("pkg", pkg);
5637            bundle.putString("reason", reason);
5638            msg.obj = bundle;
5639            mHandler.sendMessage(msg);
5640        } else {
5641            throw new SecurityException(callerUid + " cannot kill pkg: " +
5642                    pkg);
5643        }
5644    }
5645
5646    @Override
5647    public void closeSystemDialogs(String reason) {
5648        enforceNotIsolatedCaller("closeSystemDialogs");
5649
5650        final int pid = Binder.getCallingPid();
5651        final int uid = Binder.getCallingUid();
5652        final long origId = Binder.clearCallingIdentity();
5653        try {
5654            synchronized (this) {
5655                // Only allow this from foreground processes, so that background
5656                // applications can't abuse it to prevent system UI from being shown.
5657                if (uid >= Process.FIRST_APPLICATION_UID) {
5658                    ProcessRecord proc;
5659                    synchronized (mPidsSelfLocked) {
5660                        proc = mPidsSelfLocked.get(pid);
5661                    }
5662                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5663                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5664                                + " from background process " + proc);
5665                        return;
5666                    }
5667                }
5668                closeSystemDialogsLocked(reason);
5669            }
5670        } finally {
5671            Binder.restoreCallingIdentity(origId);
5672        }
5673    }
5674
5675    void closeSystemDialogsLocked(String reason) {
5676        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5677        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5678                | Intent.FLAG_RECEIVER_FOREGROUND);
5679        if (reason != null) {
5680            intent.putExtra("reason", reason);
5681        }
5682        mWindowManager.closeSystemDialogs(reason);
5683
5684        mStackSupervisor.closeSystemDialogsLocked();
5685
5686        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5687                AppOpsManager.OP_NONE, null, false, false,
5688                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5689    }
5690
5691    @Override
5692    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5693        enforceNotIsolatedCaller("getProcessMemoryInfo");
5694        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5695        for (int i=pids.length-1; i>=0; i--) {
5696            ProcessRecord proc;
5697            int oomAdj;
5698            synchronized (this) {
5699                synchronized (mPidsSelfLocked) {
5700                    proc = mPidsSelfLocked.get(pids[i]);
5701                    oomAdj = proc != null ? proc.setAdj : 0;
5702                }
5703            }
5704            infos[i] = new Debug.MemoryInfo();
5705            Debug.getMemoryInfo(pids[i], infos[i]);
5706            if (proc != null) {
5707                synchronized (this) {
5708                    if (proc.thread != null && proc.setAdj == oomAdj) {
5709                        // Record this for posterity if the process has been stable.
5710                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5711                                infos[i].getTotalUss(), false, proc.pkgList);
5712                    }
5713                }
5714            }
5715        }
5716        return infos;
5717    }
5718
5719    @Override
5720    public long[] getProcessPss(int[] pids) {
5721        enforceNotIsolatedCaller("getProcessPss");
5722        long[] pss = new long[pids.length];
5723        for (int i=pids.length-1; i>=0; i--) {
5724            ProcessRecord proc;
5725            int oomAdj;
5726            synchronized (this) {
5727                synchronized (mPidsSelfLocked) {
5728                    proc = mPidsSelfLocked.get(pids[i]);
5729                    oomAdj = proc != null ? proc.setAdj : 0;
5730                }
5731            }
5732            long[] tmpUss = new long[1];
5733            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5734            if (proc != null) {
5735                synchronized (this) {
5736                    if (proc.thread != null && proc.setAdj == oomAdj) {
5737                        // Record this for posterity if the process has been stable.
5738                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5739                    }
5740                }
5741            }
5742        }
5743        return pss;
5744    }
5745
5746    @Override
5747    public void killApplicationProcess(String processName, int uid) {
5748        if (processName == null) {
5749            return;
5750        }
5751
5752        int callerUid = Binder.getCallingUid();
5753        // Only the system server can kill an application
5754        if (callerUid == Process.SYSTEM_UID) {
5755            synchronized (this) {
5756                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5757                if (app != null && app.thread != null) {
5758                    try {
5759                        app.thread.scheduleSuicide();
5760                    } catch (RemoteException e) {
5761                        // If the other end already died, then our work here is done.
5762                    }
5763                } else {
5764                    Slog.w(TAG, "Process/uid not found attempting kill of "
5765                            + processName + " / " + uid);
5766                }
5767            }
5768        } else {
5769            throw new SecurityException(callerUid + " cannot kill app process: " +
5770                    processName);
5771        }
5772    }
5773
5774    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5775        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5776                false, true, false, false, UserHandle.getUserId(uid), reason);
5777        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5778                Uri.fromParts("package", packageName, null));
5779        if (!mProcessesReady) {
5780            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5781                    | Intent.FLAG_RECEIVER_FOREGROUND);
5782        }
5783        intent.putExtra(Intent.EXTRA_UID, uid);
5784        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5785        broadcastIntentLocked(null, null, intent,
5786                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5787                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5788    }
5789
5790
5791    private final boolean killPackageProcessesLocked(String packageName, int appId,
5792            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5793            boolean doit, boolean evenPersistent, String reason) {
5794        ArrayList<ProcessRecord> procs = new ArrayList<>();
5795
5796        // Remove all processes this package may have touched: all with the
5797        // same UID (except for the system or root user), and all whose name
5798        // matches the package name.
5799        final int NP = mProcessNames.getMap().size();
5800        for (int ip=0; ip<NP; ip++) {
5801            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5802            final int NA = apps.size();
5803            for (int ia=0; ia<NA; ia++) {
5804                ProcessRecord app = apps.valueAt(ia);
5805                if (app.persistent && !evenPersistent) {
5806                    // we don't kill persistent processes
5807                    continue;
5808                }
5809                if (app.removed) {
5810                    if (doit) {
5811                        procs.add(app);
5812                    }
5813                    continue;
5814                }
5815
5816                // Skip process if it doesn't meet our oom adj requirement.
5817                if (app.setAdj < minOomAdj) {
5818                    continue;
5819                }
5820
5821                // If no package is specified, we call all processes under the
5822                // give user id.
5823                if (packageName == null) {
5824                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5825                        continue;
5826                    }
5827                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5828                        continue;
5829                    }
5830                // Package has been specified, we want to hit all processes
5831                // that match it.  We need to qualify this by the processes
5832                // that are running under the specified app and user ID.
5833                } else {
5834                    final boolean isDep = app.pkgDeps != null
5835                            && app.pkgDeps.contains(packageName);
5836                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5837                        continue;
5838                    }
5839                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5840                        continue;
5841                    }
5842                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5843                        continue;
5844                    }
5845                }
5846
5847                // Process has passed all conditions, kill it!
5848                if (!doit) {
5849                    return true;
5850                }
5851                app.removed = true;
5852                procs.add(app);
5853            }
5854        }
5855
5856        int N = procs.size();
5857        for (int i=0; i<N; i++) {
5858            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5859        }
5860        updateOomAdjLocked();
5861        return N > 0;
5862    }
5863
5864    private void cleanupDisabledPackageComponentsLocked(
5865            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5866
5867        Set<String> disabledClasses = null;
5868        boolean packageDisabled = false;
5869        IPackageManager pm = AppGlobals.getPackageManager();
5870
5871        if (changedClasses == null) {
5872            // Nothing changed...
5873            return;
5874        }
5875
5876        // Determine enable/disable state of the package and its components.
5877        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5878        for (int i = changedClasses.length - 1; i >= 0; i--) {
5879            final String changedClass = changedClasses[i];
5880
5881            if (changedClass.equals(packageName)) {
5882                try {
5883                    // Entire package setting changed
5884                    enabled = pm.getApplicationEnabledSetting(packageName,
5885                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5886                } catch (Exception e) {
5887                    // No such package/component; probably racing with uninstall.  In any
5888                    // event it means we have nothing further to do here.
5889                    return;
5890                }
5891                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5892                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5893                if (packageDisabled) {
5894                    // Entire package is disabled.
5895                    // No need to continue to check component states.
5896                    disabledClasses = null;
5897                    break;
5898                }
5899            } else {
5900                try {
5901                    enabled = pm.getComponentEnabledSetting(
5902                            new ComponentName(packageName, changedClass),
5903                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5904                } catch (Exception e) {
5905                    // As above, probably racing with uninstall.
5906                    return;
5907                }
5908                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5909                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5910                    if (disabledClasses == null) {
5911                        disabledClasses = new ArraySet<>(changedClasses.length);
5912                    }
5913                    disabledClasses.add(changedClass);
5914                }
5915            }
5916        }
5917
5918        if (!packageDisabled && disabledClasses == null) {
5919            // Nothing to do here...
5920            return;
5921        }
5922
5923        // Clean-up disabled activities.
5924        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5925                packageName, disabledClasses, true, false, userId) && mBooted) {
5926            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5927            mStackSupervisor.scheduleIdleLocked();
5928        }
5929
5930        // Clean-up disabled tasks
5931        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5932
5933        // Clean-up disabled services.
5934        mServices.bringDownDisabledPackageServicesLocked(
5935                packageName, disabledClasses, userId, false, killProcess, true);
5936
5937        // Clean-up disabled providers.
5938        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5939        mProviderMap.collectPackageProvidersLocked(
5940                packageName, disabledClasses, true, false, userId, providers);
5941        for (int i = providers.size() - 1; i >= 0; i--) {
5942            removeDyingProviderLocked(null, providers.get(i), true);
5943        }
5944
5945        // Clean-up disabled broadcast receivers.
5946        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5947            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5948                    packageName, disabledClasses, userId, true);
5949        }
5950
5951    }
5952
5953    final boolean clearBroadcastQueueForUserLocked(int userId) {
5954        boolean didSomething = false;
5955        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5956            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5957                    null, null, userId, true);
5958        }
5959        return didSomething;
5960    }
5961
5962    final boolean forceStopPackageLocked(String packageName, int appId,
5963            boolean callerWillRestart, boolean purgeCache, boolean doit,
5964            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5965        int i;
5966
5967        if (userId == UserHandle.USER_ALL && packageName == null) {
5968            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5969        }
5970
5971        if (appId < 0 && packageName != null) {
5972            try {
5973                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5974                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5975            } catch (RemoteException e) {
5976            }
5977        }
5978
5979        if (doit) {
5980            if (packageName != null) {
5981                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5982                        + " user=" + userId + ": " + reason);
5983            } else {
5984                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5985            }
5986
5987            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5988        }
5989
5990        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5991                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5992                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5993
5994        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5995                packageName, null, doit, evenPersistent, userId)) {
5996            if (!doit) {
5997                return true;
5998            }
5999            didSomething = true;
6000        }
6001
6002        if (mServices.bringDownDisabledPackageServicesLocked(
6003                packageName, null, userId, evenPersistent, true, doit)) {
6004            if (!doit) {
6005                return true;
6006            }
6007            didSomething = true;
6008        }
6009
6010        if (packageName == null) {
6011            // Remove all sticky broadcasts from this user.
6012            mStickyBroadcasts.remove(userId);
6013        }
6014
6015        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6016        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6017                userId, providers)) {
6018            if (!doit) {
6019                return true;
6020            }
6021            didSomething = true;
6022        }
6023        for (i = providers.size() - 1; i >= 0; i--) {
6024            removeDyingProviderLocked(null, providers.get(i), true);
6025        }
6026
6027        // Remove transient permissions granted from/to this package/user
6028        removeUriPermissionsForPackageLocked(packageName, userId, false);
6029
6030        if (doit) {
6031            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6032                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6033                        packageName, null, userId, doit);
6034            }
6035        }
6036
6037        if (packageName == null || uninstalling) {
6038            // Remove pending intents.  For now we only do this when force
6039            // stopping users, because we have some problems when doing this
6040            // for packages -- app widgets are not currently cleaned up for
6041            // such packages, so they can be left with bad pending intents.
6042            if (mIntentSenderRecords.size() > 0) {
6043                Iterator<WeakReference<PendingIntentRecord>> it
6044                        = mIntentSenderRecords.values().iterator();
6045                while (it.hasNext()) {
6046                    WeakReference<PendingIntentRecord> wpir = it.next();
6047                    if (wpir == null) {
6048                        it.remove();
6049                        continue;
6050                    }
6051                    PendingIntentRecord pir = wpir.get();
6052                    if (pir == null) {
6053                        it.remove();
6054                        continue;
6055                    }
6056                    if (packageName == null) {
6057                        // Stopping user, remove all objects for the user.
6058                        if (pir.key.userId != userId) {
6059                            // Not the same user, skip it.
6060                            continue;
6061                        }
6062                    } else {
6063                        if (UserHandle.getAppId(pir.uid) != appId) {
6064                            // Different app id, skip it.
6065                            continue;
6066                        }
6067                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6068                            // Different user, skip it.
6069                            continue;
6070                        }
6071                        if (!pir.key.packageName.equals(packageName)) {
6072                            // Different package, skip it.
6073                            continue;
6074                        }
6075                    }
6076                    if (!doit) {
6077                        return true;
6078                    }
6079                    didSomething = true;
6080                    it.remove();
6081                    pir.canceled = true;
6082                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6083                        pir.key.activity.pendingResults.remove(pir.ref);
6084                    }
6085                }
6086            }
6087        }
6088
6089        if (doit) {
6090            if (purgeCache && packageName != null) {
6091                AttributeCache ac = AttributeCache.instance();
6092                if (ac != null) {
6093                    ac.removePackage(packageName);
6094                }
6095            }
6096            if (mBooted) {
6097                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6098                mStackSupervisor.scheduleIdleLocked();
6099            }
6100        }
6101
6102        return didSomething;
6103    }
6104
6105    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6106        ProcessRecord old = mProcessNames.remove(name, uid);
6107        if (old != null) {
6108            old.uidRecord.numProcs--;
6109            if (old.uidRecord.numProcs == 0) {
6110                // No more processes using this uid, tell clients it is gone.
6111                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6112                        "No more processes in " + old.uidRecord);
6113                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6114                mActiveUids.remove(uid);
6115                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6116            }
6117            old.uidRecord = null;
6118        }
6119        mIsolatedProcesses.remove(uid);
6120        return old;
6121    }
6122
6123    private final void addProcessNameLocked(ProcessRecord proc) {
6124        // We shouldn't already have a process under this name, but just in case we
6125        // need to clean up whatever may be there now.
6126        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6127        if (old == proc && proc.persistent) {
6128            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6129            Slog.w(TAG, "Re-adding persistent process " + proc);
6130        } else if (old != null) {
6131            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6132        }
6133        UidRecord uidRec = mActiveUids.get(proc.uid);
6134        if (uidRec == null) {
6135            uidRec = new UidRecord(proc.uid);
6136            // This is the first appearance of the uid, report it now!
6137            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6138                    "Creating new process uid: " + uidRec);
6139            mActiveUids.put(proc.uid, uidRec);
6140            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6141            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6142        }
6143        proc.uidRecord = uidRec;
6144        uidRec.numProcs++;
6145        mProcessNames.put(proc.processName, proc.uid, proc);
6146        if (proc.isolated) {
6147            mIsolatedProcesses.put(proc.uid, proc);
6148        }
6149    }
6150
6151    boolean removeProcessLocked(ProcessRecord app,
6152            boolean callerWillRestart, boolean allowRestart, String reason) {
6153        final String name = app.processName;
6154        final int uid = app.uid;
6155        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6156            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6157
6158        removeProcessNameLocked(name, uid);
6159        if (mHeavyWeightProcess == app) {
6160            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6161                    mHeavyWeightProcess.userId, 0));
6162            mHeavyWeightProcess = null;
6163        }
6164        boolean needRestart = false;
6165        if (app.pid > 0 && app.pid != MY_PID) {
6166            int pid = app.pid;
6167            synchronized (mPidsSelfLocked) {
6168                mPidsSelfLocked.remove(pid);
6169                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6170            }
6171            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6172            if (app.isolated) {
6173                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6174            }
6175            boolean willRestart = false;
6176            if (app.persistent && !app.isolated) {
6177                if (!callerWillRestart) {
6178                    willRestart = true;
6179                } else {
6180                    needRestart = true;
6181                }
6182            }
6183            app.kill(reason, true);
6184            handleAppDiedLocked(app, willRestart, allowRestart);
6185            if (willRestart) {
6186                removeLruProcessLocked(app);
6187                addAppLocked(app.info, false, null /* ABI override */);
6188            }
6189        } else {
6190            mRemovedProcesses.add(app);
6191        }
6192
6193        return needRestart;
6194    }
6195
6196    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6197        cleanupAppInLaunchingProvidersLocked(app, true);
6198        removeProcessLocked(app, false, true, "timeout publishing content providers");
6199    }
6200
6201    private final void processStartTimedOutLocked(ProcessRecord app) {
6202        final int pid = app.pid;
6203        boolean gone = false;
6204        synchronized (mPidsSelfLocked) {
6205            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6206            if (knownApp != null && knownApp.thread == null) {
6207                mPidsSelfLocked.remove(pid);
6208                gone = true;
6209            }
6210        }
6211
6212        if (gone) {
6213            Slog.w(TAG, "Process " + app + " failed to attach");
6214            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6215                    pid, app.uid, app.processName);
6216            removeProcessNameLocked(app.processName, app.uid);
6217            if (mHeavyWeightProcess == app) {
6218                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6219                        mHeavyWeightProcess.userId, 0));
6220                mHeavyWeightProcess = null;
6221            }
6222            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6223            if (app.isolated) {
6224                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6225            }
6226            // Take care of any launching providers waiting for this process.
6227            cleanupAppInLaunchingProvidersLocked(app, true);
6228            // Take care of any services that are waiting for the process.
6229            mServices.processStartTimedOutLocked(app);
6230            app.kill("start timeout", true);
6231            removeLruProcessLocked(app);
6232            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6233                Slog.w(TAG, "Unattached app died before backup, skipping");
6234                try {
6235                    IBackupManager bm = IBackupManager.Stub.asInterface(
6236                            ServiceManager.getService(Context.BACKUP_SERVICE));
6237                    bm.agentDisconnected(app.info.packageName);
6238                } catch (RemoteException e) {
6239                    // Can't happen; the backup manager is local
6240                }
6241            }
6242            if (isPendingBroadcastProcessLocked(pid)) {
6243                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6244                skipPendingBroadcastLocked(pid);
6245            }
6246        } else {
6247            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6248        }
6249    }
6250
6251    private final boolean attachApplicationLocked(IApplicationThread thread,
6252            int pid) {
6253
6254        // Find the application record that is being attached...  either via
6255        // the pid if we are running in multiple processes, or just pull the
6256        // next app record if we are emulating process with anonymous threads.
6257        ProcessRecord app;
6258        if (pid != MY_PID && pid >= 0) {
6259            synchronized (mPidsSelfLocked) {
6260                app = mPidsSelfLocked.get(pid);
6261            }
6262        } else {
6263            app = null;
6264        }
6265
6266        if (app == null) {
6267            Slog.w(TAG, "No pending application record for pid " + pid
6268                    + " (IApplicationThread " + thread + "); dropping process");
6269            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6270            if (pid > 0 && pid != MY_PID) {
6271                Process.killProcessQuiet(pid);
6272                //TODO: killProcessGroup(app.info.uid, pid);
6273            } else {
6274                try {
6275                    thread.scheduleExit();
6276                } catch (Exception e) {
6277                    // Ignore exceptions.
6278                }
6279            }
6280            return false;
6281        }
6282
6283        // If this application record is still attached to a previous
6284        // process, clean it up now.
6285        if (app.thread != null) {
6286            handleAppDiedLocked(app, true, true);
6287        }
6288
6289        // Tell the process all about itself.
6290
6291        if (DEBUG_ALL) Slog.v(
6292                TAG, "Binding process pid " + pid + " to record " + app);
6293
6294        final String processName = app.processName;
6295        try {
6296            AppDeathRecipient adr = new AppDeathRecipient(
6297                    app, pid, thread);
6298            thread.asBinder().linkToDeath(adr, 0);
6299            app.deathRecipient = adr;
6300        } catch (RemoteException e) {
6301            app.resetPackageList(mProcessStats);
6302            startProcessLocked(app, "link fail", processName);
6303            return false;
6304        }
6305
6306        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6307
6308        app.makeActive(thread, mProcessStats);
6309        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6310        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6311        app.forcingToForeground = null;
6312        updateProcessForegroundLocked(app, false, false);
6313        app.hasShownUi = false;
6314        app.debugging = false;
6315        app.cached = false;
6316        app.killedByAm = false;
6317
6318        // We carefully use the same state that PackageManager uses for
6319        // filtering, since we use this flag to decide if we need to install
6320        // providers when user is unlocked later
6321        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6322
6323        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6324
6325        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6326        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6327
6328        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6329            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6330            msg.obj = app;
6331            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6332        }
6333
6334        if (!normalMode) {
6335            Slog.i(TAG, "Launching preboot mode app: " + app);
6336        }
6337
6338        if (DEBUG_ALL) Slog.v(
6339            TAG, "New app record " + app
6340            + " thread=" + thread.asBinder() + " pid=" + pid);
6341        try {
6342            int testMode = IApplicationThread.DEBUG_OFF;
6343            if (mDebugApp != null && mDebugApp.equals(processName)) {
6344                testMode = mWaitForDebugger
6345                    ? IApplicationThread.DEBUG_WAIT
6346                    : IApplicationThread.DEBUG_ON;
6347                app.debugging = true;
6348                if (mDebugTransient) {
6349                    mDebugApp = mOrigDebugApp;
6350                    mWaitForDebugger = mOrigWaitForDebugger;
6351                }
6352            }
6353            String profileFile = app.instrumentationProfileFile;
6354            ParcelFileDescriptor profileFd = null;
6355            int samplingInterval = 0;
6356            boolean profileAutoStop = false;
6357            if (mProfileApp != null && mProfileApp.equals(processName)) {
6358                mProfileProc = app;
6359                profileFile = mProfileFile;
6360                profileFd = mProfileFd;
6361                samplingInterval = mSamplingInterval;
6362                profileAutoStop = mAutoStopProfiler;
6363            }
6364            boolean enableTrackAllocation = false;
6365            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6366                enableTrackAllocation = true;
6367                mTrackAllocationApp = null;
6368            }
6369
6370            // If the app is being launched for restore or full backup, set it up specially
6371            boolean isRestrictedBackupMode = false;
6372            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6373                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6374                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6375                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6376                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6377            }
6378
6379            if (app.instrumentationClass != null) {
6380                notifyPackageUse(app.instrumentationClass.getPackageName(),
6381                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6382            }
6383            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6384                    + processName + " with config " + mConfiguration);
6385            ApplicationInfo appInfo = app.instrumentationInfo != null
6386                    ? app.instrumentationInfo : app.info;
6387            app.compat = compatibilityInfoForPackageLocked(appInfo);
6388            if (profileFd != null) {
6389                profileFd = profileFd.dup();
6390            }
6391            ProfilerInfo profilerInfo = profileFile == null ? null
6392                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6393            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6394                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6395                    app.instrumentationUiAutomationConnection, testMode,
6396                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6397                    isRestrictedBackupMode || !normalMode, app.persistent,
6398                    new Configuration(mConfiguration), app.compat,
6399                    getCommonServicesLocked(app.isolated),
6400                    mCoreSettingsObserver.getCoreSettingsLocked());
6401            updateLruProcessLocked(app, false, null);
6402            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6403        } catch (Exception e) {
6404            // todo: Yikes!  What should we do?  For now we will try to
6405            // start another process, but that could easily get us in
6406            // an infinite loop of restarting processes...
6407            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6408
6409            app.resetPackageList(mProcessStats);
6410            app.unlinkDeathRecipient();
6411            startProcessLocked(app, "bind fail", processName);
6412            return false;
6413        }
6414
6415        // Remove this record from the list of starting applications.
6416        mPersistentStartingProcesses.remove(app);
6417        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6418                "Attach application locked removing on hold: " + app);
6419        mProcessesOnHold.remove(app);
6420
6421        boolean badApp = false;
6422        boolean didSomething = false;
6423
6424        // See if the top visible activity is waiting to run in this process...
6425        if (normalMode) {
6426            try {
6427                if (mStackSupervisor.attachApplicationLocked(app)) {
6428                    didSomething = true;
6429                }
6430            } catch (Exception e) {
6431                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6432                badApp = true;
6433            }
6434        }
6435
6436        // Find any services that should be running in this process...
6437        if (!badApp) {
6438            try {
6439                didSomething |= mServices.attachApplicationLocked(app, processName);
6440            } catch (Exception e) {
6441                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6442                badApp = true;
6443            }
6444        }
6445
6446        // Check if a next-broadcast receiver is in this process...
6447        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6448            try {
6449                didSomething |= sendPendingBroadcastsLocked(app);
6450            } catch (Exception e) {
6451                // If the app died trying to launch the receiver we declare it 'bad'
6452                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6453                badApp = true;
6454            }
6455        }
6456
6457        // Check whether the next backup agent is in this process...
6458        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6459            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6460                    "New app is backup target, launching agent for " + app);
6461            notifyPackageUse(mBackupTarget.appInfo.packageName,
6462                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6463            try {
6464                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6465                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6466                        mBackupTarget.backupMode);
6467            } catch (Exception e) {
6468                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6469                badApp = true;
6470            }
6471        }
6472
6473        if (badApp) {
6474            app.kill("error during init", true);
6475            handleAppDiedLocked(app, false, true);
6476            return false;
6477        }
6478
6479        if (!didSomething) {
6480            updateOomAdjLocked();
6481        }
6482
6483        return true;
6484    }
6485
6486    @Override
6487    public final void attachApplication(IApplicationThread thread) {
6488        synchronized (this) {
6489            int callingPid = Binder.getCallingPid();
6490            final long origId = Binder.clearCallingIdentity();
6491            attachApplicationLocked(thread, callingPid);
6492            Binder.restoreCallingIdentity(origId);
6493        }
6494    }
6495
6496    @Override
6497    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6498        final long origId = Binder.clearCallingIdentity();
6499        synchronized (this) {
6500            ActivityStack stack = ActivityRecord.getStackLocked(token);
6501            if (stack != null) {
6502                ActivityRecord r =
6503                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6504                if (stopProfiling) {
6505                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6506                        try {
6507                            mProfileFd.close();
6508                        } catch (IOException e) {
6509                        }
6510                        clearProfilerLocked();
6511                    }
6512                }
6513            }
6514        }
6515        Binder.restoreCallingIdentity(origId);
6516    }
6517
6518    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6519        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6520                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6521    }
6522
6523    void enableScreenAfterBoot() {
6524        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6525                SystemClock.uptimeMillis());
6526        mWindowManager.enableScreenAfterBoot();
6527
6528        synchronized (this) {
6529            updateEventDispatchingLocked();
6530        }
6531    }
6532
6533    @Override
6534    public void showBootMessage(final CharSequence msg, final boolean always) {
6535        if (Binder.getCallingUid() != Process.myUid()) {
6536            // These days only the core system can call this, so apps can't get in
6537            // the way of what we show about running them.
6538        }
6539        mWindowManager.showBootMessage(msg, always);
6540    }
6541
6542    @Override
6543    public void keyguardWaitingForActivityDrawn() {
6544        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6545        final long token = Binder.clearCallingIdentity();
6546        try {
6547            synchronized (this) {
6548                if (DEBUG_LOCKSCREEN) logLockScreen("");
6549                mWindowManager.keyguardWaitingForActivityDrawn();
6550                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6551                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6552                    updateSleepIfNeededLocked();
6553                }
6554            }
6555        } finally {
6556            Binder.restoreCallingIdentity(token);
6557        }
6558    }
6559
6560    @Override
6561    public void keyguardGoingAway(int flags) {
6562        enforceNotIsolatedCaller("keyguardGoingAway");
6563        final long token = Binder.clearCallingIdentity();
6564        try {
6565            synchronized (this) {
6566                if (DEBUG_LOCKSCREEN) logLockScreen("");
6567                mWindowManager.keyguardGoingAway(flags);
6568                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6569                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6570                    updateSleepIfNeededLocked();
6571
6572                    // Some stack visibility might change (e.g. docked stack)
6573                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6574                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6575                }
6576            }
6577        } finally {
6578            Binder.restoreCallingIdentity(token);
6579        }
6580    }
6581
6582    final void finishBooting() {
6583        synchronized (this) {
6584            if (!mBootAnimationComplete) {
6585                mCallFinishBooting = true;
6586                return;
6587            }
6588            mCallFinishBooting = false;
6589        }
6590
6591        ArraySet<String> completedIsas = new ArraySet<String>();
6592        for (String abi : Build.SUPPORTED_ABIS) {
6593            Process.establishZygoteConnectionForAbi(abi);
6594            final String instructionSet = VMRuntime.getInstructionSet(abi);
6595            if (!completedIsas.contains(instructionSet)) {
6596                try {
6597                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6598                } catch (InstallerException e) {
6599                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6600                }
6601                completedIsas.add(instructionSet);
6602            }
6603        }
6604
6605        IntentFilter pkgFilter = new IntentFilter();
6606        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6607        pkgFilter.addDataScheme("package");
6608        mContext.registerReceiver(new BroadcastReceiver() {
6609            @Override
6610            public void onReceive(Context context, Intent intent) {
6611                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6612                if (pkgs != null) {
6613                    for (String pkg : pkgs) {
6614                        synchronized (ActivityManagerService.this) {
6615                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6616                                    0, "query restart")) {
6617                                setResultCode(Activity.RESULT_OK);
6618                                return;
6619                            }
6620                        }
6621                    }
6622                }
6623            }
6624        }, pkgFilter);
6625
6626        IntentFilter dumpheapFilter = new IntentFilter();
6627        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6628        mContext.registerReceiver(new BroadcastReceiver() {
6629            @Override
6630            public void onReceive(Context context, Intent intent) {
6631                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6632                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6633                } else {
6634                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6635                }
6636            }
6637        }, dumpheapFilter);
6638
6639        // Let system services know.
6640        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6641
6642        synchronized (this) {
6643            // Ensure that any processes we had put on hold are now started
6644            // up.
6645            final int NP = mProcessesOnHold.size();
6646            if (NP > 0) {
6647                ArrayList<ProcessRecord> procs =
6648                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6649                for (int ip=0; ip<NP; ip++) {
6650                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6651                            + procs.get(ip));
6652                    startProcessLocked(procs.get(ip), "on-hold", null);
6653                }
6654            }
6655
6656            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6657                // Start looking for apps that are abusing wake locks.
6658                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6659                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6660                // Tell anyone interested that we are done booting!
6661                SystemProperties.set("sys.boot_completed", "1");
6662
6663                // And trigger dev.bootcomplete if we are not showing encryption progress
6664                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6665                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6666                    SystemProperties.set("dev.bootcomplete", "1");
6667                }
6668                mUserController.sendBootCompletedLocked(
6669                        new IIntentReceiver.Stub() {
6670                            @Override
6671                            public void performReceive(Intent intent, int resultCode,
6672                                    String data, Bundle extras, boolean ordered,
6673                                    boolean sticky, int sendingUser) {
6674                                synchronized (ActivityManagerService.this) {
6675                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6676                                            true, false);
6677                                }
6678                            }
6679                        });
6680                scheduleStartProfilesLocked();
6681            }
6682        }
6683    }
6684
6685    @Override
6686    public void bootAnimationComplete() {
6687        final boolean callFinishBooting;
6688        synchronized (this) {
6689            callFinishBooting = mCallFinishBooting;
6690            mBootAnimationComplete = true;
6691        }
6692        if (callFinishBooting) {
6693            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6694            finishBooting();
6695            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6696        }
6697    }
6698
6699    final void ensureBootCompleted() {
6700        boolean booting;
6701        boolean enableScreen;
6702        synchronized (this) {
6703            booting = mBooting;
6704            mBooting = false;
6705            enableScreen = !mBooted;
6706            mBooted = true;
6707        }
6708
6709        if (booting) {
6710            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6711            finishBooting();
6712            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6713        }
6714
6715        if (enableScreen) {
6716            enableScreenAfterBoot();
6717        }
6718    }
6719
6720    @Override
6721    public final void activityResumed(IBinder token) {
6722        final long origId = Binder.clearCallingIdentity();
6723        synchronized(this) {
6724            ActivityStack stack = ActivityRecord.getStackLocked(token);
6725            if (stack != null) {
6726                stack.activityResumedLocked(token);
6727            }
6728        }
6729        Binder.restoreCallingIdentity(origId);
6730    }
6731
6732    @Override
6733    public final void activityPaused(IBinder token) {
6734        final long origId = Binder.clearCallingIdentity();
6735        synchronized(this) {
6736            ActivityStack stack = ActivityRecord.getStackLocked(token);
6737            if (stack != null) {
6738                stack.activityPausedLocked(token, false);
6739            }
6740        }
6741        Binder.restoreCallingIdentity(origId);
6742    }
6743
6744    @Override
6745    public final void activityStopped(IBinder token, Bundle icicle,
6746            PersistableBundle persistentState, CharSequence description) {
6747        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6748
6749        // Refuse possible leaked file descriptors
6750        if (icicle != null && icicle.hasFileDescriptors()) {
6751            throw new IllegalArgumentException("File descriptors passed in Bundle");
6752        }
6753
6754        final long origId = Binder.clearCallingIdentity();
6755
6756        synchronized (this) {
6757            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6758            if (r != null) {
6759                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6760            }
6761        }
6762
6763        trimApplications();
6764
6765        Binder.restoreCallingIdentity(origId);
6766    }
6767
6768    @Override
6769    public final void activityDestroyed(IBinder token) {
6770        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6771        synchronized (this) {
6772            ActivityStack stack = ActivityRecord.getStackLocked(token);
6773            if (stack != null) {
6774                stack.activityDestroyedLocked(token, "activityDestroyed");
6775            }
6776        }
6777    }
6778
6779    @Override
6780    public final void activityRelaunched(IBinder token) {
6781        final long origId = Binder.clearCallingIdentity();
6782        synchronized (this) {
6783            mStackSupervisor.activityRelaunchedLocked(token);
6784        }
6785        Binder.restoreCallingIdentity(origId);
6786    }
6787
6788    @Override
6789    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6790            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6791        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6792                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6793        synchronized (this) {
6794            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6795            if (record == null) {
6796                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6797                        + "found for: " + token);
6798            }
6799            record.setSizeConfigurations(horizontalSizeConfiguration,
6800                    verticalSizeConfigurations, smallestSizeConfigurations);
6801        }
6802    }
6803
6804    @Override
6805    public final void backgroundResourcesReleased(IBinder token) {
6806        final long origId = Binder.clearCallingIdentity();
6807        try {
6808            synchronized (this) {
6809                ActivityStack stack = ActivityRecord.getStackLocked(token);
6810                if (stack != null) {
6811                    stack.backgroundResourcesReleased();
6812                }
6813            }
6814        } finally {
6815            Binder.restoreCallingIdentity(origId);
6816        }
6817    }
6818
6819    @Override
6820    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6821        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6822    }
6823
6824    @Override
6825    public final void notifyEnterAnimationComplete(IBinder token) {
6826        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6827    }
6828
6829    @Override
6830    public String getCallingPackage(IBinder token) {
6831        synchronized (this) {
6832            ActivityRecord r = getCallingRecordLocked(token);
6833            return r != null ? r.info.packageName : null;
6834        }
6835    }
6836
6837    @Override
6838    public ComponentName getCallingActivity(IBinder token) {
6839        synchronized (this) {
6840            ActivityRecord r = getCallingRecordLocked(token);
6841            return r != null ? r.intent.getComponent() : null;
6842        }
6843    }
6844
6845    private ActivityRecord getCallingRecordLocked(IBinder token) {
6846        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6847        if (r == null) {
6848            return null;
6849        }
6850        return r.resultTo;
6851    }
6852
6853    @Override
6854    public ComponentName getActivityClassForToken(IBinder token) {
6855        synchronized(this) {
6856            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6857            if (r == null) {
6858                return null;
6859            }
6860            return r.intent.getComponent();
6861        }
6862    }
6863
6864    @Override
6865    public String getPackageForToken(IBinder token) {
6866        synchronized(this) {
6867            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6868            if (r == null) {
6869                return null;
6870            }
6871            return r.packageName;
6872        }
6873    }
6874
6875    @Override
6876    public boolean isRootVoiceInteraction(IBinder token) {
6877        synchronized(this) {
6878            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6879            if (r == null) {
6880                return false;
6881            }
6882            return r.rootVoiceInteraction;
6883        }
6884    }
6885
6886    @Override
6887    public IIntentSender getIntentSender(int type,
6888            String packageName, IBinder token, String resultWho,
6889            int requestCode, Intent[] intents, String[] resolvedTypes,
6890            int flags, Bundle bOptions, int userId) {
6891        enforceNotIsolatedCaller("getIntentSender");
6892        // Refuse possible leaked file descriptors
6893        if (intents != null) {
6894            if (intents.length < 1) {
6895                throw new IllegalArgumentException("Intents array length must be >= 1");
6896            }
6897            for (int i=0; i<intents.length; i++) {
6898                Intent intent = intents[i];
6899                if (intent != null) {
6900                    if (intent.hasFileDescriptors()) {
6901                        throw new IllegalArgumentException("File descriptors passed in Intent");
6902                    }
6903                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6904                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6905                        throw new IllegalArgumentException(
6906                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6907                    }
6908                    intents[i] = new Intent(intent);
6909                }
6910            }
6911            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6912                throw new IllegalArgumentException(
6913                        "Intent array length does not match resolvedTypes length");
6914            }
6915        }
6916        if (bOptions != null) {
6917            if (bOptions.hasFileDescriptors()) {
6918                throw new IllegalArgumentException("File descriptors passed in options");
6919            }
6920        }
6921
6922        synchronized(this) {
6923            int callingUid = Binder.getCallingUid();
6924            int origUserId = userId;
6925            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6926                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6927                    ALLOW_NON_FULL, "getIntentSender", null);
6928            if (origUserId == UserHandle.USER_CURRENT) {
6929                // We don't want to evaluate this until the pending intent is
6930                // actually executed.  However, we do want to always do the
6931                // security checking for it above.
6932                userId = UserHandle.USER_CURRENT;
6933            }
6934            try {
6935                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6936                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6937                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6938                    if (!UserHandle.isSameApp(callingUid, uid)) {
6939                        String msg = "Permission Denial: getIntentSender() from pid="
6940                            + Binder.getCallingPid()
6941                            + ", uid=" + Binder.getCallingUid()
6942                            + ", (need uid=" + uid + ")"
6943                            + " is not allowed to send as package " + packageName;
6944                        Slog.w(TAG, msg);
6945                        throw new SecurityException(msg);
6946                    }
6947                }
6948
6949                return getIntentSenderLocked(type, packageName, callingUid, userId,
6950                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6951
6952            } catch (RemoteException e) {
6953                throw new SecurityException(e);
6954            }
6955        }
6956    }
6957
6958    IIntentSender getIntentSenderLocked(int type, String packageName,
6959            int callingUid, int userId, IBinder token, String resultWho,
6960            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6961            Bundle bOptions) {
6962        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6963        ActivityRecord activity = null;
6964        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6965            activity = ActivityRecord.isInStackLocked(token);
6966            if (activity == null) {
6967                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6968                return null;
6969            }
6970            if (activity.finishing) {
6971                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6972                return null;
6973            }
6974        }
6975
6976        // We're going to be splicing together extras before sending, so we're
6977        // okay poking into any contained extras.
6978        if (intents != null) {
6979            for (int i = 0; i < intents.length; i++) {
6980                intents[i].setDefusable(true);
6981            }
6982        }
6983        Bundle.setDefusable(bOptions, true);
6984
6985        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6986        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6987        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6988        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6989                |PendingIntent.FLAG_UPDATE_CURRENT);
6990
6991        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6992                type, packageName, activity, resultWho,
6993                requestCode, intents, resolvedTypes, flags, bOptions, userId);
6994        WeakReference<PendingIntentRecord> ref;
6995        ref = mIntentSenderRecords.get(key);
6996        PendingIntentRecord rec = ref != null ? ref.get() : null;
6997        if (rec != null) {
6998            if (!cancelCurrent) {
6999                if (updateCurrent) {
7000                    if (rec.key.requestIntent != null) {
7001                        rec.key.requestIntent.replaceExtras(intents != null ?
7002                                intents[intents.length - 1] : null);
7003                    }
7004                    if (intents != null) {
7005                        intents[intents.length-1] = rec.key.requestIntent;
7006                        rec.key.allIntents = intents;
7007                        rec.key.allResolvedTypes = resolvedTypes;
7008                    } else {
7009                        rec.key.allIntents = null;
7010                        rec.key.allResolvedTypes = null;
7011                    }
7012                }
7013                return rec;
7014            }
7015            rec.canceled = true;
7016            mIntentSenderRecords.remove(key);
7017        }
7018        if (noCreate) {
7019            return rec;
7020        }
7021        rec = new PendingIntentRecord(this, key, callingUid);
7022        mIntentSenderRecords.put(key, rec.ref);
7023        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7024            if (activity.pendingResults == null) {
7025                activity.pendingResults
7026                        = new HashSet<WeakReference<PendingIntentRecord>>();
7027            }
7028            activity.pendingResults.add(rec.ref);
7029        }
7030        return rec;
7031    }
7032
7033    @Override
7034    public void cancelIntentSender(IIntentSender sender) {
7035        if (!(sender instanceof PendingIntentRecord)) {
7036            return;
7037        }
7038        synchronized(this) {
7039            PendingIntentRecord rec = (PendingIntentRecord)sender;
7040            try {
7041                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7042                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7043                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7044                    String msg = "Permission Denial: cancelIntentSender() from pid="
7045                        + Binder.getCallingPid()
7046                        + ", uid=" + Binder.getCallingUid()
7047                        + " is not allowed to cancel packges "
7048                        + rec.key.packageName;
7049                    Slog.w(TAG, msg);
7050                    throw new SecurityException(msg);
7051                }
7052            } catch (RemoteException e) {
7053                throw new SecurityException(e);
7054            }
7055            cancelIntentSenderLocked(rec, true);
7056        }
7057    }
7058
7059    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7060        rec.canceled = true;
7061        mIntentSenderRecords.remove(rec.key);
7062        if (cleanActivity && rec.key.activity != null) {
7063            rec.key.activity.pendingResults.remove(rec.ref);
7064        }
7065    }
7066
7067    @Override
7068    public String getPackageForIntentSender(IIntentSender pendingResult) {
7069        if (!(pendingResult instanceof PendingIntentRecord)) {
7070            return null;
7071        }
7072        try {
7073            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7074            return res.key.packageName;
7075        } catch (ClassCastException e) {
7076        }
7077        return null;
7078    }
7079
7080    @Override
7081    public int getUidForIntentSender(IIntentSender sender) {
7082        if (sender instanceof PendingIntentRecord) {
7083            try {
7084                PendingIntentRecord res = (PendingIntentRecord)sender;
7085                return res.uid;
7086            } catch (ClassCastException e) {
7087            }
7088        }
7089        return -1;
7090    }
7091
7092    @Override
7093    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7094        if (!(pendingResult instanceof PendingIntentRecord)) {
7095            return false;
7096        }
7097        try {
7098            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7099            if (res.key.allIntents == null) {
7100                return false;
7101            }
7102            for (int i=0; i<res.key.allIntents.length; i++) {
7103                Intent intent = res.key.allIntents[i];
7104                if (intent.getPackage() != null && intent.getComponent() != null) {
7105                    return false;
7106                }
7107            }
7108            return true;
7109        } catch (ClassCastException e) {
7110        }
7111        return false;
7112    }
7113
7114    @Override
7115    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7116        if (!(pendingResult instanceof PendingIntentRecord)) {
7117            return false;
7118        }
7119        try {
7120            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7121            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7122                return true;
7123            }
7124            return false;
7125        } catch (ClassCastException e) {
7126        }
7127        return false;
7128    }
7129
7130    @Override
7131    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7132        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7133                "getIntentForIntentSender()");
7134        if (!(pendingResult instanceof PendingIntentRecord)) {
7135            return null;
7136        }
7137        try {
7138            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7139            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7140        } catch (ClassCastException e) {
7141        }
7142        return null;
7143    }
7144
7145    @Override
7146    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7147        if (!(pendingResult instanceof PendingIntentRecord)) {
7148            return null;
7149        }
7150        try {
7151            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7152            synchronized (this) {
7153                return getTagForIntentSenderLocked(res, prefix);
7154            }
7155        } catch (ClassCastException e) {
7156        }
7157        return null;
7158    }
7159
7160    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7161        final Intent intent = res.key.requestIntent;
7162        if (intent != null) {
7163            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7164                    || res.lastTagPrefix.equals(prefix))) {
7165                return res.lastTag;
7166            }
7167            res.lastTagPrefix = prefix;
7168            final StringBuilder sb = new StringBuilder(128);
7169            if (prefix != null) {
7170                sb.append(prefix);
7171            }
7172            if (intent.getAction() != null) {
7173                sb.append(intent.getAction());
7174            } else if (intent.getComponent() != null) {
7175                intent.getComponent().appendShortString(sb);
7176            } else {
7177                sb.append("?");
7178            }
7179            return res.lastTag = sb.toString();
7180        }
7181        return null;
7182    }
7183
7184    @Override
7185    public void setProcessLimit(int max) {
7186        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7187                "setProcessLimit()");
7188        synchronized (this) {
7189            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7190            mProcessLimitOverride = max;
7191        }
7192        trimApplications();
7193    }
7194
7195    @Override
7196    public int getProcessLimit() {
7197        synchronized (this) {
7198            return mProcessLimitOverride;
7199        }
7200    }
7201
7202    void foregroundTokenDied(ForegroundToken token) {
7203        synchronized (ActivityManagerService.this) {
7204            synchronized (mPidsSelfLocked) {
7205                ForegroundToken cur
7206                    = mForegroundProcesses.get(token.pid);
7207                if (cur != token) {
7208                    return;
7209                }
7210                mForegroundProcesses.remove(token.pid);
7211                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7212                if (pr == null) {
7213                    return;
7214                }
7215                pr.forcingToForeground = null;
7216                updateProcessForegroundLocked(pr, false, false);
7217            }
7218            updateOomAdjLocked();
7219        }
7220    }
7221
7222    @Override
7223    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7224        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7225                "setProcessForeground()");
7226        synchronized(this) {
7227            boolean changed = false;
7228
7229            synchronized (mPidsSelfLocked) {
7230                ProcessRecord pr = mPidsSelfLocked.get(pid);
7231                if (pr == null && isForeground) {
7232                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7233                    return;
7234                }
7235                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7236                if (oldToken != null) {
7237                    oldToken.token.unlinkToDeath(oldToken, 0);
7238                    mForegroundProcesses.remove(pid);
7239                    if (pr != null) {
7240                        pr.forcingToForeground = null;
7241                    }
7242                    changed = true;
7243                }
7244                if (isForeground && token != null) {
7245                    ForegroundToken newToken = new ForegroundToken() {
7246                        @Override
7247                        public void binderDied() {
7248                            foregroundTokenDied(this);
7249                        }
7250                    };
7251                    newToken.pid = pid;
7252                    newToken.token = token;
7253                    try {
7254                        token.linkToDeath(newToken, 0);
7255                        mForegroundProcesses.put(pid, newToken);
7256                        pr.forcingToForeground = token;
7257                        changed = true;
7258                    } catch (RemoteException e) {
7259                        // If the process died while doing this, we will later
7260                        // do the cleanup with the process death link.
7261                    }
7262                }
7263            }
7264
7265            if (changed) {
7266                updateOomAdjLocked();
7267            }
7268        }
7269    }
7270
7271    @Override
7272    public boolean isAppForeground(int uid) throws RemoteException {
7273        synchronized (this) {
7274            UidRecord uidRec = mActiveUids.get(uid);
7275            if (uidRec == null || uidRec.idle) {
7276                return false;
7277            }
7278            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7279        }
7280    }
7281
7282    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7283    // be guarded by permission checking.
7284    int getUidState(int uid) {
7285        synchronized (this) {
7286            UidRecord uidRec = mActiveUids.get(uid);
7287            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7288        }
7289    }
7290
7291    @Override
7292    public boolean isInMultiWindowMode(IBinder token) {
7293        final long origId = Binder.clearCallingIdentity();
7294        try {
7295            synchronized(this) {
7296                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7297                if (r == null) {
7298                    return false;
7299                }
7300                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7301                return !r.task.mFullscreen;
7302            }
7303        } finally {
7304            Binder.restoreCallingIdentity(origId);
7305        }
7306    }
7307
7308    @Override
7309    public boolean isInPictureInPictureMode(IBinder token) {
7310        final long origId = Binder.clearCallingIdentity();
7311        try {
7312            synchronized(this) {
7313                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7314                if (stack == null) {
7315                    return false;
7316                }
7317                return stack.mStackId == PINNED_STACK_ID;
7318            }
7319        } finally {
7320            Binder.restoreCallingIdentity(origId);
7321        }
7322    }
7323
7324    @Override
7325    public void enterPictureInPictureMode(IBinder token) {
7326        final long origId = Binder.clearCallingIdentity();
7327        try {
7328            synchronized(this) {
7329                if (!mSupportsPictureInPicture) {
7330                    throw new IllegalStateException("enterPictureInPictureMode: "
7331                            + "Device doesn't support picture-in-picture mode.");
7332                }
7333
7334                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7335
7336                if (r == null) {
7337                    throw new IllegalStateException("enterPictureInPictureMode: "
7338                            + "Can't find activity for token=" + token);
7339                }
7340
7341                if (!r.supportsPictureInPicture()) {
7342                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7343                            + "Picture-In-Picture not supported for r=" + r);
7344                }
7345
7346                // Use the default launch bounds for pinned stack if it doesn't exist yet.
7347                final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7348                        ? mDefaultPinnedStackBounds : null;
7349
7350                mStackSupervisor.moveActivityToPinnedStackLocked(
7351                        r, "enterPictureInPictureMode", bounds);
7352            }
7353        } finally {
7354            Binder.restoreCallingIdentity(origId);
7355        }
7356    }
7357
7358    // =========================================================
7359    // PROCESS INFO
7360    // =========================================================
7361
7362    static class ProcessInfoService extends IProcessInfoService.Stub {
7363        final ActivityManagerService mActivityManagerService;
7364        ProcessInfoService(ActivityManagerService activityManagerService) {
7365            mActivityManagerService = activityManagerService;
7366        }
7367
7368        @Override
7369        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7370            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7371                    /*in*/ pids, /*out*/ states, null);
7372        }
7373
7374        @Override
7375        public void getProcessStatesAndOomScoresFromPids(
7376                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7377            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7378                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7379        }
7380    }
7381
7382    /**
7383     * For each PID in the given input array, write the current process state
7384     * for that process into the states array, or -1 to indicate that no
7385     * process with the given PID exists. If scores array is provided, write
7386     * the oom score for the process into the scores array, with INVALID_ADJ
7387     * indicating the PID doesn't exist.
7388     */
7389    public void getProcessStatesAndOomScoresForPIDs(
7390            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7391        if (scores != null) {
7392            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7393                    "getProcessStatesAndOomScoresForPIDs()");
7394        }
7395
7396        if (pids == null) {
7397            throw new NullPointerException("pids");
7398        } else if (states == null) {
7399            throw new NullPointerException("states");
7400        } else if (pids.length != states.length) {
7401            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7402        } else if (scores != null && pids.length != scores.length) {
7403            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7404        }
7405
7406        synchronized (mPidsSelfLocked) {
7407            for (int i = 0; i < pids.length; i++) {
7408                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7409                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7410                        pr.curProcState;
7411                if (scores != null) {
7412                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7413                }
7414            }
7415        }
7416    }
7417
7418    // =========================================================
7419    // PERMISSIONS
7420    // =========================================================
7421
7422    static class PermissionController extends IPermissionController.Stub {
7423        ActivityManagerService mActivityManagerService;
7424        PermissionController(ActivityManagerService activityManagerService) {
7425            mActivityManagerService = activityManagerService;
7426        }
7427
7428        @Override
7429        public boolean checkPermission(String permission, int pid, int uid) {
7430            return mActivityManagerService.checkPermission(permission, pid,
7431                    uid) == PackageManager.PERMISSION_GRANTED;
7432        }
7433
7434        @Override
7435        public String[] getPackagesForUid(int uid) {
7436            return mActivityManagerService.mContext.getPackageManager()
7437                    .getPackagesForUid(uid);
7438        }
7439
7440        @Override
7441        public boolean isRuntimePermission(String permission) {
7442            try {
7443                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7444                        .getPermissionInfo(permission, 0);
7445                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7446            } catch (NameNotFoundException nnfe) {
7447                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7448            }
7449            return false;
7450        }
7451    }
7452
7453    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7454        @Override
7455        public int checkComponentPermission(String permission, int pid, int uid,
7456                int owningUid, boolean exported) {
7457            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7458                    owningUid, exported);
7459        }
7460
7461        @Override
7462        public Object getAMSLock() {
7463            return ActivityManagerService.this;
7464        }
7465    }
7466
7467    /**
7468     * This can be called with or without the global lock held.
7469     */
7470    int checkComponentPermission(String permission, int pid, int uid,
7471            int owningUid, boolean exported) {
7472        if (pid == MY_PID) {
7473            return PackageManager.PERMISSION_GRANTED;
7474        }
7475        return ActivityManager.checkComponentPermission(permission, uid,
7476                owningUid, exported);
7477    }
7478
7479    /**
7480     * As the only public entry point for permissions checking, this method
7481     * can enforce the semantic that requesting a check on a null global
7482     * permission is automatically denied.  (Internally a null permission
7483     * string is used when calling {@link #checkComponentPermission} in cases
7484     * when only uid-based security is needed.)
7485     *
7486     * This can be called with or without the global lock held.
7487     */
7488    @Override
7489    public int checkPermission(String permission, int pid, int uid) {
7490        if (permission == null) {
7491            return PackageManager.PERMISSION_DENIED;
7492        }
7493        return checkComponentPermission(permission, pid, uid, -1, true);
7494    }
7495
7496    @Override
7497    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7498        if (permission == null) {
7499            return PackageManager.PERMISSION_DENIED;
7500        }
7501
7502        // We might be performing an operation on behalf of an indirect binder
7503        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7504        // client identity accordingly before proceeding.
7505        Identity tlsIdentity = sCallerIdentity.get();
7506        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7507            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7508                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7509            uid = tlsIdentity.uid;
7510            pid = tlsIdentity.pid;
7511        }
7512
7513        return checkComponentPermission(permission, pid, uid, -1, true);
7514    }
7515
7516    /**
7517     * Binder IPC calls go through the public entry point.
7518     * This can be called with or without the global lock held.
7519     */
7520    int checkCallingPermission(String permission) {
7521        return checkPermission(permission,
7522                Binder.getCallingPid(),
7523                UserHandle.getAppId(Binder.getCallingUid()));
7524    }
7525
7526    /**
7527     * This can be called with or without the global lock held.
7528     */
7529    void enforceCallingPermission(String permission, String func) {
7530        if (checkCallingPermission(permission)
7531                == PackageManager.PERMISSION_GRANTED) {
7532            return;
7533        }
7534
7535        String msg = "Permission Denial: " + func + " from pid="
7536                + Binder.getCallingPid()
7537                + ", uid=" + Binder.getCallingUid()
7538                + " requires " + permission;
7539        Slog.w(TAG, msg);
7540        throw new SecurityException(msg);
7541    }
7542
7543    /**
7544     * Determine if UID is holding permissions required to access {@link Uri} in
7545     * the given {@link ProviderInfo}. Final permission checking is always done
7546     * in {@link ContentProvider}.
7547     */
7548    private final boolean checkHoldingPermissionsLocked(
7549            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7550        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7551                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7552        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7553            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7554                    != PERMISSION_GRANTED) {
7555                return false;
7556            }
7557        }
7558        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7559    }
7560
7561    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7562            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7563        if (pi.applicationInfo.uid == uid) {
7564            return true;
7565        } else if (!pi.exported) {
7566            return false;
7567        }
7568
7569        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7570        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7571        try {
7572            // check if target holds top-level <provider> permissions
7573            if (!readMet && pi.readPermission != null && considerUidPermissions
7574                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7575                readMet = true;
7576            }
7577            if (!writeMet && pi.writePermission != null && considerUidPermissions
7578                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7579                writeMet = true;
7580            }
7581
7582            // track if unprotected read/write is allowed; any denied
7583            // <path-permission> below removes this ability
7584            boolean allowDefaultRead = pi.readPermission == null;
7585            boolean allowDefaultWrite = pi.writePermission == null;
7586
7587            // check if target holds any <path-permission> that match uri
7588            final PathPermission[] pps = pi.pathPermissions;
7589            if (pps != null) {
7590                final String path = grantUri.uri.getPath();
7591                int i = pps.length;
7592                while (i > 0 && (!readMet || !writeMet)) {
7593                    i--;
7594                    PathPermission pp = pps[i];
7595                    if (pp.match(path)) {
7596                        if (!readMet) {
7597                            final String pprperm = pp.getReadPermission();
7598                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7599                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7600                                    + ": match=" + pp.match(path)
7601                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7602                            if (pprperm != null) {
7603                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7604                                        == PERMISSION_GRANTED) {
7605                                    readMet = true;
7606                                } else {
7607                                    allowDefaultRead = false;
7608                                }
7609                            }
7610                        }
7611                        if (!writeMet) {
7612                            final String ppwperm = pp.getWritePermission();
7613                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7614                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7615                                    + ": match=" + pp.match(path)
7616                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7617                            if (ppwperm != null) {
7618                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7619                                        == PERMISSION_GRANTED) {
7620                                    writeMet = true;
7621                                } else {
7622                                    allowDefaultWrite = false;
7623                                }
7624                            }
7625                        }
7626                    }
7627                }
7628            }
7629
7630            // grant unprotected <provider> read/write, if not blocked by
7631            // <path-permission> above
7632            if (allowDefaultRead) readMet = true;
7633            if (allowDefaultWrite) writeMet = true;
7634
7635        } catch (RemoteException e) {
7636            return false;
7637        }
7638
7639        return readMet && writeMet;
7640    }
7641
7642    public int getAppStartMode(int uid, String packageName) {
7643        synchronized (this) {
7644            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7645        }
7646    }
7647
7648    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7649            boolean allowWhenForeground) {
7650        UidRecord uidRec = mActiveUids.get(uid);
7651        if (!mLenientBackgroundCheck) {
7652            if (!allowWhenForeground || uidRec == null
7653                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7654                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7655                        packageName) != AppOpsManager.MODE_ALLOWED) {
7656                    return ActivityManager.APP_START_MODE_DELAYED;
7657                }
7658            }
7659
7660        } else if (uidRec == null || uidRec.idle) {
7661            if (callingPid >= 0) {
7662                ProcessRecord proc;
7663                synchronized (mPidsSelfLocked) {
7664                    proc = mPidsSelfLocked.get(callingPid);
7665                }
7666                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7667                    // Whoever is instigating this is in the foreground, so we will allow it
7668                    // to go through.
7669                    return ActivityManager.APP_START_MODE_NORMAL;
7670                }
7671            }
7672            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7673                    != AppOpsManager.MODE_ALLOWED) {
7674                return ActivityManager.APP_START_MODE_DELAYED;
7675            }
7676        }
7677        return ActivityManager.APP_START_MODE_NORMAL;
7678    }
7679
7680    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7681        ProviderInfo pi = null;
7682        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7683        if (cpr != null) {
7684            pi = cpr.info;
7685        } else {
7686            try {
7687                pi = AppGlobals.getPackageManager().resolveContentProvider(
7688                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7689            } catch (RemoteException ex) {
7690            }
7691        }
7692        return pi;
7693    }
7694
7695    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7696        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7697        if (targetUris != null) {
7698            return targetUris.get(grantUri);
7699        }
7700        return null;
7701    }
7702
7703    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7704            String targetPkg, int targetUid, GrantUri grantUri) {
7705        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7706        if (targetUris == null) {
7707            targetUris = Maps.newArrayMap();
7708            mGrantedUriPermissions.put(targetUid, targetUris);
7709        }
7710
7711        UriPermission perm = targetUris.get(grantUri);
7712        if (perm == null) {
7713            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7714            targetUris.put(grantUri, perm);
7715        }
7716
7717        return perm;
7718    }
7719
7720    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7721            final int modeFlags) {
7722        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7723        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7724                : UriPermission.STRENGTH_OWNED;
7725
7726        // Root gets to do everything.
7727        if (uid == 0) {
7728            return true;
7729        }
7730
7731        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7732        if (perms == null) return false;
7733
7734        // First look for exact match
7735        final UriPermission exactPerm = perms.get(grantUri);
7736        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7737            return true;
7738        }
7739
7740        // No exact match, look for prefixes
7741        final int N = perms.size();
7742        for (int i = 0; i < N; i++) {
7743            final UriPermission perm = perms.valueAt(i);
7744            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7745                    && perm.getStrength(modeFlags) >= minStrength) {
7746                return true;
7747            }
7748        }
7749
7750        return false;
7751    }
7752
7753    /**
7754     * @param uri This uri must NOT contain an embedded userId.
7755     * @param userId The userId in which the uri is to be resolved.
7756     */
7757    @Override
7758    public int checkUriPermission(Uri uri, int pid, int uid,
7759            final int modeFlags, int userId, IBinder callerToken) {
7760        enforceNotIsolatedCaller("checkUriPermission");
7761
7762        // Another redirected-binder-call permissions check as in
7763        // {@link checkPermissionWithToken}.
7764        Identity tlsIdentity = sCallerIdentity.get();
7765        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7766            uid = tlsIdentity.uid;
7767            pid = tlsIdentity.pid;
7768        }
7769
7770        // Our own process gets to do everything.
7771        if (pid == MY_PID) {
7772            return PackageManager.PERMISSION_GRANTED;
7773        }
7774        synchronized (this) {
7775            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7776                    ? PackageManager.PERMISSION_GRANTED
7777                    : PackageManager.PERMISSION_DENIED;
7778        }
7779    }
7780
7781    /**
7782     * Check if the targetPkg can be granted permission to access uri by
7783     * the callingUid using the given modeFlags.  Throws a security exception
7784     * if callingUid is not allowed to do this.  Returns the uid of the target
7785     * if the URI permission grant should be performed; returns -1 if it is not
7786     * needed (for example targetPkg already has permission to access the URI).
7787     * If you already know the uid of the target, you can supply it in
7788     * lastTargetUid else set that to -1.
7789     */
7790    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7791            final int modeFlags, int lastTargetUid) {
7792        if (!Intent.isAccessUriMode(modeFlags)) {
7793            return -1;
7794        }
7795
7796        if (targetPkg != null) {
7797            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7798                    "Checking grant " + targetPkg + " permission to " + grantUri);
7799        }
7800
7801        final IPackageManager pm = AppGlobals.getPackageManager();
7802
7803        // If this is not a content: uri, we can't do anything with it.
7804        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7805            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7806                    "Can't grant URI permission for non-content URI: " + grantUri);
7807            return -1;
7808        }
7809
7810        final String authority = grantUri.uri.getAuthority();
7811        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7812        if (pi == null) {
7813            Slog.w(TAG, "No content provider found for permission check: " +
7814                    grantUri.uri.toSafeString());
7815            return -1;
7816        }
7817
7818        int targetUid = lastTargetUid;
7819        if (targetUid < 0 && targetPkg != null) {
7820            try {
7821                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7822                        UserHandle.getUserId(callingUid));
7823                if (targetUid < 0) {
7824                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7825                            "Can't grant URI permission no uid for: " + targetPkg);
7826                    return -1;
7827                }
7828            } catch (RemoteException ex) {
7829                return -1;
7830            }
7831        }
7832
7833        if (targetUid >= 0) {
7834            // First...  does the target actually need this permission?
7835            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7836                // No need to grant the target this permission.
7837                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7838                        "Target " + targetPkg + " already has full permission to " + grantUri);
7839                return -1;
7840            }
7841        } else {
7842            // First...  there is no target package, so can anyone access it?
7843            boolean allowed = pi.exported;
7844            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7845                if (pi.readPermission != null) {
7846                    allowed = false;
7847                }
7848            }
7849            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7850                if (pi.writePermission != null) {
7851                    allowed = false;
7852                }
7853            }
7854            if (allowed) {
7855                return -1;
7856            }
7857        }
7858
7859        /* There is a special cross user grant if:
7860         * - The target is on another user.
7861         * - Apps on the current user can access the uri without any uid permissions.
7862         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7863         * grant uri permissions.
7864         */
7865        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7866                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7867                modeFlags, false /*without considering the uid permissions*/);
7868
7869        // Second...  is the provider allowing granting of URI permissions?
7870        if (!specialCrossUserGrant) {
7871            if (!pi.grantUriPermissions) {
7872                throw new SecurityException("Provider " + pi.packageName
7873                        + "/" + pi.name
7874                        + " does not allow granting of Uri permissions (uri "
7875                        + grantUri + ")");
7876            }
7877            if (pi.uriPermissionPatterns != null) {
7878                final int N = pi.uriPermissionPatterns.length;
7879                boolean allowed = false;
7880                for (int i=0; i<N; i++) {
7881                    if (pi.uriPermissionPatterns[i] != null
7882                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7883                        allowed = true;
7884                        break;
7885                    }
7886                }
7887                if (!allowed) {
7888                    throw new SecurityException("Provider " + pi.packageName
7889                            + "/" + pi.name
7890                            + " does not allow granting of permission to path of Uri "
7891                            + grantUri);
7892                }
7893            }
7894        }
7895
7896        // Third...  does the caller itself have permission to access
7897        // this uri?
7898        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7899            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7900                // Require they hold a strong enough Uri permission
7901                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7902                    throw new SecurityException("Uid " + callingUid
7903                            + " does not have permission to uri " + grantUri);
7904                }
7905            }
7906        }
7907        return targetUid;
7908    }
7909
7910    /**
7911     * @param uri This uri must NOT contain an embedded userId.
7912     * @param userId The userId in which the uri is to be resolved.
7913     */
7914    @Override
7915    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7916            final int modeFlags, int userId) {
7917        enforceNotIsolatedCaller("checkGrantUriPermission");
7918        synchronized(this) {
7919            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7920                    new GrantUri(userId, uri, false), modeFlags, -1);
7921        }
7922    }
7923
7924    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7925            final int modeFlags, UriPermissionOwner owner) {
7926        if (!Intent.isAccessUriMode(modeFlags)) {
7927            return;
7928        }
7929
7930        // So here we are: the caller has the assumed permission
7931        // to the uri, and the target doesn't.  Let's now give this to
7932        // the target.
7933
7934        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7935                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7936
7937        final String authority = grantUri.uri.getAuthority();
7938        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7939        if (pi == null) {
7940            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7941            return;
7942        }
7943
7944        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7945            grantUri.prefix = true;
7946        }
7947        final UriPermission perm = findOrCreateUriPermissionLocked(
7948                pi.packageName, targetPkg, targetUid, grantUri);
7949        perm.grantModes(modeFlags, owner);
7950    }
7951
7952    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7953            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7954        if (targetPkg == null) {
7955            throw new NullPointerException("targetPkg");
7956        }
7957        int targetUid;
7958        final IPackageManager pm = AppGlobals.getPackageManager();
7959        try {
7960            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7961        } catch (RemoteException ex) {
7962            return;
7963        }
7964
7965        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7966                targetUid);
7967        if (targetUid < 0) {
7968            return;
7969        }
7970
7971        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7972                owner);
7973    }
7974
7975    static class NeededUriGrants extends ArrayList<GrantUri> {
7976        final String targetPkg;
7977        final int targetUid;
7978        final int flags;
7979
7980        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7981            this.targetPkg = targetPkg;
7982            this.targetUid = targetUid;
7983            this.flags = flags;
7984        }
7985    }
7986
7987    /**
7988     * Like checkGrantUriPermissionLocked, but takes an Intent.
7989     */
7990    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7991            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7992        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7993                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7994                + " clip=" + (intent != null ? intent.getClipData() : null)
7995                + " from " + intent + "; flags=0x"
7996                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7997
7998        if (targetPkg == null) {
7999            throw new NullPointerException("targetPkg");
8000        }
8001
8002        if (intent == null) {
8003            return null;
8004        }
8005        Uri data = intent.getData();
8006        ClipData clip = intent.getClipData();
8007        if (data == null && clip == null) {
8008            return null;
8009        }
8010        // Default userId for uris in the intent (if they don't specify it themselves)
8011        int contentUserHint = intent.getContentUserHint();
8012        if (contentUserHint == UserHandle.USER_CURRENT) {
8013            contentUserHint = UserHandle.getUserId(callingUid);
8014        }
8015        final IPackageManager pm = AppGlobals.getPackageManager();
8016        int targetUid;
8017        if (needed != null) {
8018            targetUid = needed.targetUid;
8019        } else {
8020            try {
8021                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8022                        targetUserId);
8023            } catch (RemoteException ex) {
8024                return null;
8025            }
8026            if (targetUid < 0) {
8027                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8028                        "Can't grant URI permission no uid for: " + targetPkg
8029                        + " on user " + targetUserId);
8030                return null;
8031            }
8032        }
8033        if (data != null) {
8034            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8035            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8036                    targetUid);
8037            if (targetUid > 0) {
8038                if (needed == null) {
8039                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8040                }
8041                needed.add(grantUri);
8042            }
8043        }
8044        if (clip != null) {
8045            for (int i=0; i<clip.getItemCount(); i++) {
8046                Uri uri = clip.getItemAt(i).getUri();
8047                if (uri != null) {
8048                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8049                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8050                            targetUid);
8051                    if (targetUid > 0) {
8052                        if (needed == null) {
8053                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8054                        }
8055                        needed.add(grantUri);
8056                    }
8057                } else {
8058                    Intent clipIntent = clip.getItemAt(i).getIntent();
8059                    if (clipIntent != null) {
8060                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8061                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8062                        if (newNeeded != null) {
8063                            needed = newNeeded;
8064                        }
8065                    }
8066                }
8067            }
8068        }
8069
8070        return needed;
8071    }
8072
8073    /**
8074     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8075     */
8076    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8077            UriPermissionOwner owner) {
8078        if (needed != null) {
8079            for (int i=0; i<needed.size(); i++) {
8080                GrantUri grantUri = needed.get(i);
8081                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8082                        grantUri, needed.flags, owner);
8083            }
8084        }
8085    }
8086
8087    void grantUriPermissionFromIntentLocked(int callingUid,
8088            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8089        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8090                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8091        if (needed == null) {
8092            return;
8093        }
8094
8095        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8096    }
8097
8098    /**
8099     * @param uri This uri must NOT contain an embedded userId.
8100     * @param userId The userId in which the uri is to be resolved.
8101     */
8102    @Override
8103    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8104            final int modeFlags, int userId) {
8105        enforceNotIsolatedCaller("grantUriPermission");
8106        GrantUri grantUri = new GrantUri(userId, uri, false);
8107        synchronized(this) {
8108            final ProcessRecord r = getRecordForAppLocked(caller);
8109            if (r == null) {
8110                throw new SecurityException("Unable to find app for caller "
8111                        + caller
8112                        + " when granting permission to uri " + grantUri);
8113            }
8114            if (targetPkg == null) {
8115                throw new IllegalArgumentException("null target");
8116            }
8117            if (grantUri == null) {
8118                throw new IllegalArgumentException("null uri");
8119            }
8120
8121            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8122                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8123                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8124                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8125
8126            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8127                    UserHandle.getUserId(r.uid));
8128        }
8129    }
8130
8131    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8132        if (perm.modeFlags == 0) {
8133            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8134                    perm.targetUid);
8135            if (perms != null) {
8136                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8137                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8138
8139                perms.remove(perm.uri);
8140                if (perms.isEmpty()) {
8141                    mGrantedUriPermissions.remove(perm.targetUid);
8142                }
8143            }
8144        }
8145    }
8146
8147    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8148        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8149                "Revoking all granted permissions to " + grantUri);
8150
8151        final IPackageManager pm = AppGlobals.getPackageManager();
8152        final String authority = grantUri.uri.getAuthority();
8153        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8154        if (pi == null) {
8155            Slog.w(TAG, "No content provider found for permission revoke: "
8156                    + grantUri.toSafeString());
8157            return;
8158        }
8159
8160        // Does the caller have this permission on the URI?
8161        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8162            // If they don't have direct access to the URI, then revoke any
8163            // ownerless URI permissions that have been granted to them.
8164            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8165            if (perms != null) {
8166                boolean persistChanged = false;
8167                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8168                    final UriPermission perm = it.next();
8169                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8170                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8171                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8172                                "Revoking non-owned " + perm.targetUid
8173                                + " permission to " + perm.uri);
8174                        persistChanged |= perm.revokeModes(
8175                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8176                        if (perm.modeFlags == 0) {
8177                            it.remove();
8178                        }
8179                    }
8180                }
8181                if (perms.isEmpty()) {
8182                    mGrantedUriPermissions.remove(callingUid);
8183                }
8184                if (persistChanged) {
8185                    schedulePersistUriGrants();
8186                }
8187            }
8188            return;
8189        }
8190
8191        boolean persistChanged = false;
8192
8193        // Go through all of the permissions and remove any that match.
8194        int N = mGrantedUriPermissions.size();
8195        for (int i = 0; i < N; i++) {
8196            final int targetUid = mGrantedUriPermissions.keyAt(i);
8197            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8198
8199            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8200                final UriPermission perm = it.next();
8201                if (perm.uri.sourceUserId == grantUri.sourceUserId
8202                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8203                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8204                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8205                    persistChanged |= perm.revokeModes(
8206                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8207                    if (perm.modeFlags == 0) {
8208                        it.remove();
8209                    }
8210                }
8211            }
8212
8213            if (perms.isEmpty()) {
8214                mGrantedUriPermissions.remove(targetUid);
8215                N--;
8216                i--;
8217            }
8218        }
8219
8220        if (persistChanged) {
8221            schedulePersistUriGrants();
8222        }
8223    }
8224
8225    /**
8226     * @param uri This uri must NOT contain an embedded userId.
8227     * @param userId The userId in which the uri is to be resolved.
8228     */
8229    @Override
8230    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8231            int userId) {
8232        enforceNotIsolatedCaller("revokeUriPermission");
8233        synchronized(this) {
8234            final ProcessRecord r = getRecordForAppLocked(caller);
8235            if (r == null) {
8236                throw new SecurityException("Unable to find app for caller "
8237                        + caller
8238                        + " when revoking permission to uri " + uri);
8239            }
8240            if (uri == null) {
8241                Slog.w(TAG, "revokeUriPermission: null uri");
8242                return;
8243            }
8244
8245            if (!Intent.isAccessUriMode(modeFlags)) {
8246                return;
8247            }
8248
8249            final String authority = uri.getAuthority();
8250            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8251            if (pi == null) {
8252                Slog.w(TAG, "No content provider found for permission revoke: "
8253                        + uri.toSafeString());
8254                return;
8255            }
8256
8257            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8258        }
8259    }
8260
8261    /**
8262     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8263     * given package.
8264     *
8265     * @param packageName Package name to match, or {@code null} to apply to all
8266     *            packages.
8267     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8268     *            to all users.
8269     * @param persistable If persistable grants should be removed.
8270     */
8271    private void removeUriPermissionsForPackageLocked(
8272            String packageName, int userHandle, boolean persistable) {
8273        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8274            throw new IllegalArgumentException("Must narrow by either package or user");
8275        }
8276
8277        boolean persistChanged = false;
8278
8279        int N = mGrantedUriPermissions.size();
8280        for (int i = 0; i < N; i++) {
8281            final int targetUid = mGrantedUriPermissions.keyAt(i);
8282            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8283
8284            // Only inspect grants matching user
8285            if (userHandle == UserHandle.USER_ALL
8286                    || userHandle == UserHandle.getUserId(targetUid)) {
8287                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8288                    final UriPermission perm = it.next();
8289
8290                    // Only inspect grants matching package
8291                    if (packageName == null || perm.sourcePkg.equals(packageName)
8292                            || perm.targetPkg.equals(packageName)) {
8293                        persistChanged |= perm.revokeModes(persistable
8294                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8295
8296                        // Only remove when no modes remain; any persisted grants
8297                        // will keep this alive.
8298                        if (perm.modeFlags == 0) {
8299                            it.remove();
8300                        }
8301                    }
8302                }
8303
8304                if (perms.isEmpty()) {
8305                    mGrantedUriPermissions.remove(targetUid);
8306                    N--;
8307                    i--;
8308                }
8309            }
8310        }
8311
8312        if (persistChanged) {
8313            schedulePersistUriGrants();
8314        }
8315    }
8316
8317    @Override
8318    public IBinder newUriPermissionOwner(String name) {
8319        enforceNotIsolatedCaller("newUriPermissionOwner");
8320        synchronized(this) {
8321            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8322            return owner.getExternalTokenLocked();
8323        }
8324    }
8325
8326    @Override
8327    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8328        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8329        synchronized(this) {
8330            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8331            if (r == null) {
8332                throw new IllegalArgumentException("Activity does not exist; token="
8333                        + activityToken);
8334            }
8335            return r.getUriPermissionsLocked().getExternalTokenLocked();
8336        }
8337    }
8338    /**
8339     * @param uri This uri must NOT contain an embedded userId.
8340     * @param sourceUserId The userId in which the uri is to be resolved.
8341     * @param targetUserId The userId of the app that receives the grant.
8342     */
8343    @Override
8344    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8345            final int modeFlags, int sourceUserId, int targetUserId) {
8346        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8347                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8348                "grantUriPermissionFromOwner", null);
8349        synchronized(this) {
8350            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8351            if (owner == null) {
8352                throw new IllegalArgumentException("Unknown owner: " + token);
8353            }
8354            if (fromUid != Binder.getCallingUid()) {
8355                if (Binder.getCallingUid() != Process.myUid()) {
8356                    // Only system code can grant URI permissions on behalf
8357                    // of other users.
8358                    throw new SecurityException("nice try");
8359                }
8360            }
8361            if (targetPkg == null) {
8362                throw new IllegalArgumentException("null target");
8363            }
8364            if (uri == null) {
8365                throw new IllegalArgumentException("null uri");
8366            }
8367
8368            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8369                    modeFlags, owner, targetUserId);
8370        }
8371    }
8372
8373    /**
8374     * @param uri This uri must NOT contain an embedded userId.
8375     * @param userId The userId in which the uri is to be resolved.
8376     */
8377    @Override
8378    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8379        synchronized(this) {
8380            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8381            if (owner == null) {
8382                throw new IllegalArgumentException("Unknown owner: " + token);
8383            }
8384
8385            if (uri == null) {
8386                owner.removeUriPermissionsLocked(mode);
8387            } else {
8388                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8389            }
8390        }
8391    }
8392
8393    private void schedulePersistUriGrants() {
8394        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8395            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8396                    10 * DateUtils.SECOND_IN_MILLIS);
8397        }
8398    }
8399
8400    private void writeGrantedUriPermissions() {
8401        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8402
8403        // Snapshot permissions so we can persist without lock
8404        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8405        synchronized (this) {
8406            final int size = mGrantedUriPermissions.size();
8407            for (int i = 0; i < size; i++) {
8408                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8409                for (UriPermission perm : perms.values()) {
8410                    if (perm.persistedModeFlags != 0) {
8411                        persist.add(perm.snapshot());
8412                    }
8413                }
8414            }
8415        }
8416
8417        FileOutputStream fos = null;
8418        try {
8419            fos = mGrantFile.startWrite();
8420
8421            XmlSerializer out = new FastXmlSerializer();
8422            out.setOutput(fos, StandardCharsets.UTF_8.name());
8423            out.startDocument(null, true);
8424            out.startTag(null, TAG_URI_GRANTS);
8425            for (UriPermission.Snapshot perm : persist) {
8426                out.startTag(null, TAG_URI_GRANT);
8427                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8428                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8429                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8430                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8431                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8432                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8433                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8434                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8435                out.endTag(null, TAG_URI_GRANT);
8436            }
8437            out.endTag(null, TAG_URI_GRANTS);
8438            out.endDocument();
8439
8440            mGrantFile.finishWrite(fos);
8441        } catch (IOException e) {
8442            if (fos != null) {
8443                mGrantFile.failWrite(fos);
8444            }
8445        }
8446    }
8447
8448    private void readGrantedUriPermissionsLocked() {
8449        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8450
8451        final long now = System.currentTimeMillis();
8452
8453        FileInputStream fis = null;
8454        try {
8455            fis = mGrantFile.openRead();
8456            final XmlPullParser in = Xml.newPullParser();
8457            in.setInput(fis, StandardCharsets.UTF_8.name());
8458
8459            int type;
8460            while ((type = in.next()) != END_DOCUMENT) {
8461                final String tag = in.getName();
8462                if (type == START_TAG) {
8463                    if (TAG_URI_GRANT.equals(tag)) {
8464                        final int sourceUserId;
8465                        final int targetUserId;
8466                        final int userHandle = readIntAttribute(in,
8467                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8468                        if (userHandle != UserHandle.USER_NULL) {
8469                            // For backwards compatibility.
8470                            sourceUserId = userHandle;
8471                            targetUserId = userHandle;
8472                        } else {
8473                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8474                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8475                        }
8476                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8477                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8478                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8479                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8480                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8481                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8482
8483                        // Sanity check that provider still belongs to source package
8484                        final ProviderInfo pi = getProviderInfoLocked(
8485                                uri.getAuthority(), sourceUserId);
8486                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8487                            int targetUid = -1;
8488                            try {
8489                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8490                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8491                            } catch (RemoteException e) {
8492                            }
8493                            if (targetUid != -1) {
8494                                final UriPermission perm = findOrCreateUriPermissionLocked(
8495                                        sourcePkg, targetPkg, targetUid,
8496                                        new GrantUri(sourceUserId, uri, prefix));
8497                                perm.initPersistedModes(modeFlags, createdTime);
8498                            }
8499                        } else {
8500                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8501                                    + " but instead found " + pi);
8502                        }
8503                    }
8504                }
8505            }
8506        } catch (FileNotFoundException e) {
8507            // Missing grants is okay
8508        } catch (IOException e) {
8509            Slog.wtf(TAG, "Failed reading Uri grants", e);
8510        } catch (XmlPullParserException e) {
8511            Slog.wtf(TAG, "Failed reading Uri grants", e);
8512        } finally {
8513            IoUtils.closeQuietly(fis);
8514        }
8515    }
8516
8517    /**
8518     * @param uri This uri must NOT contain an embedded userId.
8519     * @param userId The userId in which the uri is to be resolved.
8520     */
8521    @Override
8522    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8523        enforceNotIsolatedCaller("takePersistableUriPermission");
8524
8525        Preconditions.checkFlagsArgument(modeFlags,
8526                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8527
8528        synchronized (this) {
8529            final int callingUid = Binder.getCallingUid();
8530            boolean persistChanged = false;
8531            GrantUri grantUri = new GrantUri(userId, uri, false);
8532
8533            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8534                    new GrantUri(userId, uri, false));
8535            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8536                    new GrantUri(userId, uri, true));
8537
8538            final boolean exactValid = (exactPerm != null)
8539                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8540            final boolean prefixValid = (prefixPerm != null)
8541                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8542
8543            if (!(exactValid || prefixValid)) {
8544                throw new SecurityException("No persistable permission grants found for UID "
8545                        + callingUid + " and Uri " + grantUri.toSafeString());
8546            }
8547
8548            if (exactValid) {
8549                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8550            }
8551            if (prefixValid) {
8552                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8553            }
8554
8555            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8556
8557            if (persistChanged) {
8558                schedulePersistUriGrants();
8559            }
8560        }
8561    }
8562
8563    /**
8564     * @param uri This uri must NOT contain an embedded userId.
8565     * @param userId The userId in which the uri is to be resolved.
8566     */
8567    @Override
8568    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8569        enforceNotIsolatedCaller("releasePersistableUriPermission");
8570
8571        Preconditions.checkFlagsArgument(modeFlags,
8572                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8573
8574        synchronized (this) {
8575            final int callingUid = Binder.getCallingUid();
8576            boolean persistChanged = false;
8577
8578            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8579                    new GrantUri(userId, uri, false));
8580            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8581                    new GrantUri(userId, uri, true));
8582            if (exactPerm == null && prefixPerm == null) {
8583                throw new SecurityException("No permission grants found for UID " + callingUid
8584                        + " and Uri " + uri.toSafeString());
8585            }
8586
8587            if (exactPerm != null) {
8588                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8589                removeUriPermissionIfNeededLocked(exactPerm);
8590            }
8591            if (prefixPerm != null) {
8592                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8593                removeUriPermissionIfNeededLocked(prefixPerm);
8594            }
8595
8596            if (persistChanged) {
8597                schedulePersistUriGrants();
8598            }
8599        }
8600    }
8601
8602    /**
8603     * Prune any older {@link UriPermission} for the given UID until outstanding
8604     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8605     *
8606     * @return if any mutations occured that require persisting.
8607     */
8608    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8609        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8610        if (perms == null) return false;
8611        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8612
8613        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8614        for (UriPermission perm : perms.values()) {
8615            if (perm.persistedModeFlags != 0) {
8616                persisted.add(perm);
8617            }
8618        }
8619
8620        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8621        if (trimCount <= 0) return false;
8622
8623        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8624        for (int i = 0; i < trimCount; i++) {
8625            final UriPermission perm = persisted.get(i);
8626
8627            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8628                    "Trimming grant created at " + perm.persistedCreateTime);
8629
8630            perm.releasePersistableModes(~0);
8631            removeUriPermissionIfNeededLocked(perm);
8632        }
8633
8634        return true;
8635    }
8636
8637    @Override
8638    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8639            String packageName, boolean incoming) {
8640        enforceNotIsolatedCaller("getPersistedUriPermissions");
8641        Preconditions.checkNotNull(packageName, "packageName");
8642
8643        final int callingUid = Binder.getCallingUid();
8644        final IPackageManager pm = AppGlobals.getPackageManager();
8645        try {
8646            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8647                    UserHandle.getUserId(callingUid));
8648            if (packageUid != callingUid) {
8649                throw new SecurityException(
8650                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8651            }
8652        } catch (RemoteException e) {
8653            throw new SecurityException("Failed to verify package name ownership");
8654        }
8655
8656        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8657        synchronized (this) {
8658            if (incoming) {
8659                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8660                        callingUid);
8661                if (perms == null) {
8662                    Slog.w(TAG, "No permission grants found for " + packageName);
8663                } else {
8664                    for (UriPermission perm : perms.values()) {
8665                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8666                            result.add(perm.buildPersistedPublicApiObject());
8667                        }
8668                    }
8669                }
8670            } else {
8671                final int size = mGrantedUriPermissions.size();
8672                for (int i = 0; i < size; i++) {
8673                    final ArrayMap<GrantUri, UriPermission> perms =
8674                            mGrantedUriPermissions.valueAt(i);
8675                    for (UriPermission perm : perms.values()) {
8676                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8677                            result.add(perm.buildPersistedPublicApiObject());
8678                        }
8679                    }
8680                }
8681            }
8682        }
8683        return new ParceledListSlice<android.content.UriPermission>(result);
8684    }
8685
8686    @Override
8687    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8688            String packageName, int userId) {
8689        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8690                "getGrantedUriPermissions");
8691
8692        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8693        synchronized (this) {
8694            final int size = mGrantedUriPermissions.size();
8695            for (int i = 0; i < size; i++) {
8696                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8697                for (UriPermission perm : perms.values()) {
8698                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8699                            && perm.persistedModeFlags != 0) {
8700                        result.add(perm.buildPersistedPublicApiObject());
8701                    }
8702                }
8703            }
8704        }
8705        return new ParceledListSlice<android.content.UriPermission>(result);
8706    }
8707
8708    @Override
8709    public void clearGrantedUriPermissions(String packageName, int userId) {
8710        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8711                "clearGrantedUriPermissions");
8712        removeUriPermissionsForPackageLocked(packageName, userId, true);
8713    }
8714
8715    @Override
8716    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8717        synchronized (this) {
8718            ProcessRecord app =
8719                who != null ? getRecordForAppLocked(who) : null;
8720            if (app == null) return;
8721
8722            Message msg = Message.obtain();
8723            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8724            msg.obj = app;
8725            msg.arg1 = waiting ? 1 : 0;
8726            mUiHandler.sendMessage(msg);
8727        }
8728    }
8729
8730    @Override
8731    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8732        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8733        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8734        outInfo.availMem = Process.getFreeMemory();
8735        outInfo.totalMem = Process.getTotalMemory();
8736        outInfo.threshold = homeAppMem;
8737        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8738        outInfo.hiddenAppThreshold = cachedAppMem;
8739        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8740                ProcessList.SERVICE_ADJ);
8741        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8742                ProcessList.VISIBLE_APP_ADJ);
8743        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8744                ProcessList.FOREGROUND_APP_ADJ);
8745    }
8746
8747    // =========================================================
8748    // TASK MANAGEMENT
8749    // =========================================================
8750
8751    @Override
8752    public List<IAppTask> getAppTasks(String callingPackage) {
8753        int callingUid = Binder.getCallingUid();
8754        long ident = Binder.clearCallingIdentity();
8755
8756        synchronized(this) {
8757            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8758            try {
8759                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8760
8761                final int N = mRecentTasks.size();
8762                for (int i = 0; i < N; i++) {
8763                    TaskRecord tr = mRecentTasks.get(i);
8764                    // Skip tasks that do not match the caller.  We don't need to verify
8765                    // callingPackage, because we are also limiting to callingUid and know
8766                    // that will limit to the correct security sandbox.
8767                    if (tr.effectiveUid != callingUid) {
8768                        continue;
8769                    }
8770                    Intent intent = tr.getBaseIntent();
8771                    if (intent == null ||
8772                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8773                        continue;
8774                    }
8775                    ActivityManager.RecentTaskInfo taskInfo =
8776                            createRecentTaskInfoFromTaskRecord(tr);
8777                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8778                    list.add(taskImpl);
8779                }
8780            } finally {
8781                Binder.restoreCallingIdentity(ident);
8782            }
8783            return list;
8784        }
8785    }
8786
8787    @Override
8788    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8789        final int callingUid = Binder.getCallingUid();
8790        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8791
8792        synchronized(this) {
8793            if (DEBUG_ALL) Slog.v(
8794                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8795
8796            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8797                    callingUid);
8798
8799            // TODO: Improve with MRU list from all ActivityStacks.
8800            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8801        }
8802
8803        return list;
8804    }
8805
8806    /**
8807     * Creates a new RecentTaskInfo from a TaskRecord.
8808     */
8809    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8810        // Update the task description to reflect any changes in the task stack
8811        tr.updateTaskDescription();
8812
8813        // Compose the recent task info
8814        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8815        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8816        rti.persistentId = tr.taskId;
8817        rti.baseIntent = new Intent(tr.getBaseIntent());
8818        rti.origActivity = tr.origActivity;
8819        rti.realActivity = tr.realActivity;
8820        rti.description = tr.lastDescription;
8821        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8822        rti.userId = tr.userId;
8823        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8824        rti.firstActiveTime = tr.firstActiveTime;
8825        rti.lastActiveTime = tr.lastActiveTime;
8826        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8827        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8828        rti.numActivities = 0;
8829        if (tr.mBounds != null) {
8830            rti.bounds = new Rect(tr.mBounds);
8831        }
8832        rti.isDockable = tr.canGoInDockedStack();
8833        rti.resizeMode = tr.mResizeMode;
8834
8835        ActivityRecord base = null;
8836        ActivityRecord top = null;
8837        ActivityRecord tmp;
8838
8839        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8840            tmp = tr.mActivities.get(i);
8841            if (tmp.finishing) {
8842                continue;
8843            }
8844            base = tmp;
8845            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8846                top = base;
8847            }
8848            rti.numActivities++;
8849        }
8850
8851        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8852        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8853
8854        return rti;
8855    }
8856
8857    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8858        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8859                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8860        if (!allowed) {
8861            if (checkPermission(android.Manifest.permission.GET_TASKS,
8862                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8863                // Temporary compatibility: some existing apps on the system image may
8864                // still be requesting the old permission and not switched to the new
8865                // one; if so, we'll still allow them full access.  This means we need
8866                // to see if they are holding the old permission and are a system app.
8867                try {
8868                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8869                        allowed = true;
8870                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8871                                + " is using old GET_TASKS but privileged; allowing");
8872                    }
8873                } catch (RemoteException e) {
8874                }
8875            }
8876        }
8877        if (!allowed) {
8878            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8879                    + " does not hold REAL_GET_TASKS; limiting output");
8880        }
8881        return allowed;
8882    }
8883
8884    @Override
8885    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8886        final int callingUid = Binder.getCallingUid();
8887        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8888                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8889
8890        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8891        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8892        synchronized (this) {
8893            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8894                    callingUid);
8895            final boolean detailed = checkCallingPermission(
8896                    android.Manifest.permission.GET_DETAILED_TASKS)
8897                    == PackageManager.PERMISSION_GRANTED;
8898
8899            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8900                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8901                return Collections.emptyList();
8902            }
8903            mRecentTasks.loadUserRecentsLocked(userId);
8904
8905            final int recentsCount = mRecentTasks.size();
8906            ArrayList<ActivityManager.RecentTaskInfo> res =
8907                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8908
8909            final Set<Integer> includedUsers;
8910            if (includeProfiles) {
8911                includedUsers = mUserController.getProfileIds(userId);
8912            } else {
8913                includedUsers = new HashSet<>();
8914            }
8915            includedUsers.add(Integer.valueOf(userId));
8916
8917            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8918                TaskRecord tr = mRecentTasks.get(i);
8919                // Only add calling user or related users recent tasks
8920                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8921                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8922                    continue;
8923                }
8924
8925                if (tr.realActivitySuspended) {
8926                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8927                    continue;
8928                }
8929
8930                // Return the entry if desired by the caller.  We always return
8931                // the first entry, because callers always expect this to be the
8932                // foreground app.  We may filter others if the caller has
8933                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8934                // we should exclude the entry.
8935
8936                if (i == 0
8937                        || withExcluded
8938                        || (tr.intent == null)
8939                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8940                                == 0)) {
8941                    if (!allowed) {
8942                        // If the caller doesn't have the GET_TASKS permission, then only
8943                        // allow them to see a small subset of tasks -- their own and home.
8944                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8945                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8946                            continue;
8947                        }
8948                    }
8949                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8950                        if (tr.stack != null && tr.stack.isHomeStack()) {
8951                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8952                                    "Skipping, home stack task: " + tr);
8953                            continue;
8954                        }
8955                    }
8956                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8957                        final ActivityStack stack = tr.stack;
8958                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8959                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8960                                    "Skipping, top task in docked stack: " + tr);
8961                            continue;
8962                        }
8963                    }
8964                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8965                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8966                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8967                                    "Skipping, pinned stack task: " + tr);
8968                            continue;
8969                        }
8970                    }
8971                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8972                        // Don't include auto remove tasks that are finished or finishing.
8973                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8974                                "Skipping, auto-remove without activity: " + tr);
8975                        continue;
8976                    }
8977                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8978                            && !tr.isAvailable) {
8979                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8980                                "Skipping, unavail real act: " + tr);
8981                        continue;
8982                    }
8983
8984                    if (!tr.mUserSetupComplete) {
8985                        // Don't include task launched while user is not done setting-up.
8986                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8987                                "Skipping, user setup not complete: " + tr);
8988                        continue;
8989                    }
8990
8991                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8992                    if (!detailed) {
8993                        rti.baseIntent.replaceExtras((Bundle)null);
8994                    }
8995
8996                    res.add(rti);
8997                    maxNum--;
8998                }
8999            }
9000            return res;
9001        }
9002    }
9003
9004    @Override
9005    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9006        synchronized (this) {
9007            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9008                    "getTaskThumbnail()");
9009            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9010                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9011            if (tr != null) {
9012                return tr.getTaskThumbnailLocked();
9013            }
9014        }
9015        return null;
9016    }
9017
9018    @Override
9019    public int addAppTask(IBinder activityToken, Intent intent,
9020            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9021        final int callingUid = Binder.getCallingUid();
9022        final long callingIdent = Binder.clearCallingIdentity();
9023
9024        try {
9025            synchronized (this) {
9026                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9027                if (r == null) {
9028                    throw new IllegalArgumentException("Activity does not exist; token="
9029                            + activityToken);
9030                }
9031                ComponentName comp = intent.getComponent();
9032                if (comp == null) {
9033                    throw new IllegalArgumentException("Intent " + intent
9034                            + " must specify explicit component");
9035                }
9036                if (thumbnail.getWidth() != mThumbnailWidth
9037                        || thumbnail.getHeight() != mThumbnailHeight) {
9038                    throw new IllegalArgumentException("Bad thumbnail size: got "
9039                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9040                            + mThumbnailWidth + "x" + mThumbnailHeight);
9041                }
9042                if (intent.getSelector() != null) {
9043                    intent.setSelector(null);
9044                }
9045                if (intent.getSourceBounds() != null) {
9046                    intent.setSourceBounds(null);
9047                }
9048                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9049                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9050                        // The caller has added this as an auto-remove task...  that makes no
9051                        // sense, so turn off auto-remove.
9052                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9053                    }
9054                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9055                    // Must be a new task.
9056                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9057                }
9058                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9059                    mLastAddedTaskActivity = null;
9060                }
9061                ActivityInfo ainfo = mLastAddedTaskActivity;
9062                if (ainfo == null) {
9063                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9064                            comp, 0, UserHandle.getUserId(callingUid));
9065                    if (ainfo.applicationInfo.uid != callingUid) {
9066                        throw new SecurityException(
9067                                "Can't add task for another application: target uid="
9068                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9069                    }
9070                }
9071
9072                // Use the full screen as the context for the task thumbnail
9073                final Point displaySize = new Point();
9074                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9075                r.task.stack.getDisplaySize(displaySize);
9076                thumbnailInfo.taskWidth = displaySize.x;
9077                thumbnailInfo.taskHeight = displaySize.y;
9078                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9079
9080                TaskRecord task = new TaskRecord(this,
9081                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9082                        ainfo, intent, description, thumbnailInfo);
9083
9084                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9085                if (trimIdx >= 0) {
9086                    // If this would have caused a trim, then we'll abort because that
9087                    // means it would be added at the end of the list but then just removed.
9088                    return INVALID_TASK_ID;
9089                }
9090
9091                final int N = mRecentTasks.size();
9092                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9093                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9094                    tr.removedFromRecents();
9095                }
9096
9097                task.inRecents = true;
9098                mRecentTasks.add(task);
9099                r.task.stack.addTask(task, false, "addAppTask");
9100
9101                task.setLastThumbnailLocked(thumbnail);
9102                task.freeLastThumbnail();
9103
9104                return task.taskId;
9105            }
9106        } finally {
9107            Binder.restoreCallingIdentity(callingIdent);
9108        }
9109    }
9110
9111    @Override
9112    public Point getAppTaskThumbnailSize() {
9113        synchronized (this) {
9114            return new Point(mThumbnailWidth,  mThumbnailHeight);
9115        }
9116    }
9117
9118    @Override
9119    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9120        synchronized (this) {
9121            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9122            if (r != null) {
9123                r.setTaskDescription(td);
9124                r.task.updateTaskDescription();
9125            }
9126        }
9127    }
9128
9129    @Override
9130    public void setTaskResizeable(int taskId, int resizeableMode) {
9131        synchronized (this) {
9132            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9133                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9134            if (task == null) {
9135                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9136                return;
9137            }
9138            if (task.mResizeMode != resizeableMode) {
9139                task.mResizeMode = resizeableMode;
9140                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9141                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9142                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9143            }
9144        }
9145    }
9146
9147    @Override
9148    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9149        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9150        long ident = Binder.clearCallingIdentity();
9151        try {
9152            synchronized (this) {
9153                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9154                if (task == null) {
9155                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9156                    return;
9157                }
9158                int stackId = task.stack.mStackId;
9159                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9160                // in crop windows resize mode or if the task size is affected by the docked stack
9161                // changing size. No need to update configuration.
9162                if (bounds != null && task.inCropWindowsResizeMode()
9163                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9164                    mWindowManager.scrollTask(task.taskId, bounds);
9165                    return;
9166                }
9167
9168                // Place the task in the right stack if it isn't there already based on
9169                // the requested bounds.
9170                // The stack transition logic is:
9171                // - a null bounds on a freeform task moves that task to fullscreen
9172                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9173                //   that task to freeform
9174                // - otherwise the task is not moved
9175                if (!StackId.isTaskResizeAllowed(stackId)) {
9176                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9177                }
9178                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9179                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9180                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9181                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9182                }
9183                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9184                if (stackId != task.stack.mStackId) {
9185                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9186                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9187                    preserveWindow = false;
9188                }
9189
9190                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9191                        false /* deferResume */);
9192            }
9193        } finally {
9194            Binder.restoreCallingIdentity(ident);
9195        }
9196    }
9197
9198    @Override
9199    public Rect getTaskBounds(int taskId) {
9200        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9201        long ident = Binder.clearCallingIdentity();
9202        Rect rect = new Rect();
9203        try {
9204            synchronized (this) {
9205                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9206                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9207                if (task == null) {
9208                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9209                    return rect;
9210                }
9211                if (task.stack != null) {
9212                    // Return the bounds from window manager since it will be adjusted for various
9213                    // things like the presense of a docked stack for tasks that aren't resizeable.
9214                    mWindowManager.getTaskBounds(task.taskId, rect);
9215                } else {
9216                    // Task isn't in window manager yet since it isn't associated with a stack.
9217                    // Return the persist value from activity manager
9218                    if (task.mBounds != null) {
9219                        rect.set(task.mBounds);
9220                    } else if (task.mLastNonFullscreenBounds != null) {
9221                        rect.set(task.mLastNonFullscreenBounds);
9222                    }
9223                }
9224            }
9225        } finally {
9226            Binder.restoreCallingIdentity(ident);
9227        }
9228        return rect;
9229    }
9230
9231    @Override
9232    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9233        if (userId != UserHandle.getCallingUserId()) {
9234            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9235                    "getTaskDescriptionIcon");
9236        }
9237        final File passedIconFile = new File(filePath);
9238        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9239                passedIconFile.getName());
9240        if (!legitIconFile.getPath().equals(filePath)
9241                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9242            throw new IllegalArgumentException("Bad file path: " + filePath
9243                    + " passed for userId " + userId);
9244        }
9245        return mRecentTasks.getTaskDescriptionIcon(filePath);
9246    }
9247
9248    @Override
9249    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9250            throws RemoteException {
9251        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9252                opts.getCustomInPlaceResId() == 0) {
9253            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9254                    "with valid animation");
9255        }
9256        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9257        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9258                opts.getCustomInPlaceResId());
9259        mWindowManager.executeAppTransition();
9260    }
9261
9262    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9263            boolean removeFromRecents) {
9264        if (removeFromRecents) {
9265            mRecentTasks.remove(tr);
9266            tr.removedFromRecents();
9267        }
9268        ComponentName component = tr.getBaseIntent().getComponent();
9269        if (component == null) {
9270            Slog.w(TAG, "No component for base intent of task: " + tr);
9271            return;
9272        }
9273
9274        // Find any running services associated with this app and stop if needed.
9275        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9276
9277        if (!killProcess) {
9278            return;
9279        }
9280
9281        // Determine if the process(es) for this task should be killed.
9282        final String pkg = component.getPackageName();
9283        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9284        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9285        for (int i = 0; i < pmap.size(); i++) {
9286
9287            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9288            for (int j = 0; j < uids.size(); j++) {
9289                ProcessRecord proc = uids.valueAt(j);
9290                if (proc.userId != tr.userId) {
9291                    // Don't kill process for a different user.
9292                    continue;
9293                }
9294                if (proc == mHomeProcess) {
9295                    // Don't kill the home process along with tasks from the same package.
9296                    continue;
9297                }
9298                if (!proc.pkgList.containsKey(pkg)) {
9299                    // Don't kill process that is not associated with this task.
9300                    continue;
9301                }
9302
9303                for (int k = 0; k < proc.activities.size(); k++) {
9304                    TaskRecord otherTask = proc.activities.get(k).task;
9305                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9306                        // Don't kill process(es) that has an activity in a different task that is
9307                        // also in recents.
9308                        return;
9309                    }
9310                }
9311
9312                if (proc.foregroundServices) {
9313                    // Don't kill process(es) with foreground service.
9314                    return;
9315                }
9316
9317                // Add process to kill list.
9318                procsToKill.add(proc);
9319            }
9320        }
9321
9322        // Kill the running processes.
9323        for (int i = 0; i < procsToKill.size(); i++) {
9324            ProcessRecord pr = procsToKill.get(i);
9325            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9326                    && pr.curReceiver == null) {
9327                pr.kill("remove task", true);
9328            } else {
9329                // We delay killing processes that are not in the background or running a receiver.
9330                pr.waitingToKill = "remove task";
9331            }
9332        }
9333    }
9334
9335    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9336        // Remove all tasks with activities in the specified package from the list of recent tasks
9337        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9338            TaskRecord tr = mRecentTasks.get(i);
9339            if (tr.userId != userId) continue;
9340
9341            ComponentName cn = tr.intent.getComponent();
9342            if (cn != null && cn.getPackageName().equals(packageName)) {
9343                // If the package name matches, remove the task.
9344                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9345            }
9346        }
9347    }
9348
9349    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9350            int userId) {
9351
9352        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9353            TaskRecord tr = mRecentTasks.get(i);
9354            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9355                continue;
9356            }
9357
9358            ComponentName cn = tr.intent.getComponent();
9359            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9360                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9361            if (sameComponent) {
9362                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9363            }
9364        }
9365    }
9366
9367    /**
9368     * Removes the task with the specified task id.
9369     *
9370     * @param taskId Identifier of the task to be removed.
9371     * @param killProcess Kill any process associated with the task if possible.
9372     * @param removeFromRecents Whether to also remove the task from recents.
9373     * @return Returns true if the given task was found and removed.
9374     */
9375    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9376            boolean removeFromRecents) {
9377        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9378                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9379        if (tr != null) {
9380            tr.removeTaskActivitiesLocked();
9381            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9382            if (tr.isPersistable) {
9383                notifyTaskPersisterLocked(null, true);
9384            }
9385            return true;
9386        }
9387        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9388        return false;
9389    }
9390
9391    @Override
9392    public void removeStack(int stackId) {
9393        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9394        if (stackId == HOME_STACK_ID) {
9395            throw new IllegalArgumentException("Removing home stack is not allowed.");
9396        }
9397
9398        synchronized (this) {
9399            final long ident = Binder.clearCallingIdentity();
9400            try {
9401                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9402                if (stack == null) {
9403                    return;
9404                }
9405                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9406                for (int i = tasks.size() - 1; i >= 0; i--) {
9407                    removeTaskByIdLocked(
9408                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9409                }
9410            } finally {
9411                Binder.restoreCallingIdentity(ident);
9412            }
9413        }
9414    }
9415
9416    @Override
9417    public boolean removeTask(int taskId) {
9418        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9419        synchronized (this) {
9420            final long ident = Binder.clearCallingIdentity();
9421            try {
9422                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9423            } finally {
9424                Binder.restoreCallingIdentity(ident);
9425            }
9426        }
9427    }
9428
9429    /**
9430     * TODO: Add mController hook
9431     */
9432    @Override
9433    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9434        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9435
9436        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9437        synchronized(this) {
9438            moveTaskToFrontLocked(taskId, flags, bOptions);
9439        }
9440    }
9441
9442    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9443        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9444
9445        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9446                Binder.getCallingUid(), -1, -1, "Task to front")) {
9447            ActivityOptions.abort(options);
9448            return;
9449        }
9450        final long origId = Binder.clearCallingIdentity();
9451        try {
9452            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9453            if (task == null) {
9454                Slog.d(TAG, "Could not find task for id: "+ taskId);
9455                return;
9456            }
9457            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9458                mStackSupervisor.showLockTaskToast();
9459                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9460                return;
9461            }
9462            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9463            if (prev != null && prev.isRecentsActivity()) {
9464                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9465            }
9466            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9467                    false /* forceNonResizable */);
9468        } finally {
9469            Binder.restoreCallingIdentity(origId);
9470        }
9471        ActivityOptions.abort(options);
9472    }
9473
9474    /**
9475     * Moves an activity, and all of the other activities within the same task, to the bottom
9476     * of the history stack.  The activity's order within the task is unchanged.
9477     *
9478     * @param token A reference to the activity we wish to move
9479     * @param nonRoot If false then this only works if the activity is the root
9480     *                of a task; if true it will work for any activity in a task.
9481     * @return Returns true if the move completed, false if not.
9482     */
9483    @Override
9484    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9485        enforceNotIsolatedCaller("moveActivityTaskToBack");
9486        synchronized(this) {
9487            final long origId = Binder.clearCallingIdentity();
9488            try {
9489                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9490                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9491                if (task != null) {
9492                    if (mStackSupervisor.isLockedTask(task)) {
9493                        mStackSupervisor.showLockTaskToast();
9494                        return false;
9495                    }
9496                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9497                }
9498            } finally {
9499                Binder.restoreCallingIdentity(origId);
9500            }
9501        }
9502        return false;
9503    }
9504
9505    @Override
9506    public void moveTaskBackwards(int task) {
9507        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9508                "moveTaskBackwards()");
9509
9510        synchronized(this) {
9511            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9512                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9513                return;
9514            }
9515            final long origId = Binder.clearCallingIdentity();
9516            moveTaskBackwardsLocked(task);
9517            Binder.restoreCallingIdentity(origId);
9518        }
9519    }
9520
9521    private final void moveTaskBackwardsLocked(int task) {
9522        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9523    }
9524
9525    @Override
9526    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9527            IActivityContainerCallback callback) throws RemoteException {
9528        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9529        synchronized (this) {
9530            if (parentActivityToken == null) {
9531                throw new IllegalArgumentException("parent token must not be null");
9532            }
9533            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9534            if (r == null) {
9535                return null;
9536            }
9537            if (callback == null) {
9538                throw new IllegalArgumentException("callback must not be null");
9539            }
9540            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9541        }
9542    }
9543
9544    @Override
9545    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9546        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9547        synchronized (this) {
9548            mStackSupervisor.deleteActivityContainer(container);
9549        }
9550    }
9551
9552    @Override
9553    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9554        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9555        synchronized (this) {
9556            final int stackId = mStackSupervisor.getNextStackId();
9557            final ActivityStack stack =
9558                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9559            if (stack == null) {
9560                return null;
9561            }
9562            return stack.mActivityContainer;
9563        }
9564    }
9565
9566    @Override
9567    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9568        synchronized (this) {
9569            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9570            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9571                return stack.mActivityContainer.getDisplayId();
9572            }
9573            return Display.DEFAULT_DISPLAY;
9574        }
9575    }
9576
9577    @Override
9578    public int getActivityStackId(IBinder token) throws RemoteException {
9579        synchronized (this) {
9580            ActivityStack stack = ActivityRecord.getStackLocked(token);
9581            if (stack == null) {
9582                return INVALID_STACK_ID;
9583            }
9584            return stack.mStackId;
9585        }
9586    }
9587
9588    @Override
9589    public void exitFreeformMode(IBinder token) throws RemoteException {
9590        synchronized (this) {
9591            long ident = Binder.clearCallingIdentity();
9592            try {
9593                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9594                if (r == null) {
9595                    throw new IllegalArgumentException(
9596                            "exitFreeformMode: No activity record matching token=" + token);
9597                }
9598                final ActivityStack stack = r.getStackLocked(token);
9599                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9600                    throw new IllegalStateException(
9601                            "exitFreeformMode: You can only go fullscreen from freeform.");
9602                }
9603                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9604                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9605                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9606            } finally {
9607                Binder.restoreCallingIdentity(ident);
9608            }
9609        }
9610    }
9611
9612    @Override
9613    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9614        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9615        if (stackId == HOME_STACK_ID) {
9616            throw new IllegalArgumentException(
9617                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9618        }
9619        synchronized (this) {
9620            long ident = Binder.clearCallingIdentity();
9621            try {
9622                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9623                        + " to stackId=" + stackId + " toTop=" + toTop);
9624                if (stackId == DOCKED_STACK_ID) {
9625                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9626                            null /* initialBounds */);
9627                }
9628                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9629                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9630                if (result && stackId == DOCKED_STACK_ID) {
9631                    // If task moved to docked stack - show recents if needed.
9632                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9633                            "moveTaskToDockedStack");
9634                }
9635            } finally {
9636                Binder.restoreCallingIdentity(ident);
9637            }
9638        }
9639    }
9640
9641    @Override
9642    public void swapDockedAndFullscreenStack() throws RemoteException {
9643        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9644        synchronized (this) {
9645            long ident = Binder.clearCallingIdentity();
9646            try {
9647                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9648                        FULLSCREEN_WORKSPACE_STACK_ID);
9649                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9650                        : null;
9651                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9652                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9653                        : null;
9654                if (topTask == null || tasks == null || tasks.size() == 0) {
9655                    Slog.w(TAG,
9656                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9657                    return;
9658                }
9659
9660                // TODO: App transition
9661                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9662
9663                // Defer the resume so resume/pausing while moving stacks is dangerous.
9664                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9665                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9666                        ANIMATE, true /* deferResume */);
9667                final int size = tasks.size();
9668                for (int i = 0; i < size; i++) {
9669                    final int id = tasks.get(i).taskId;
9670                    if (id == topTask.taskId) {
9671                        continue;
9672                    }
9673                    mStackSupervisor.moveTaskToStackLocked(id,
9674                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9675                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9676                }
9677
9678                // Because we deferred the resume, to avoid conflicts with stack switches while
9679                // resuming, we need to do it after all the tasks are moved.
9680                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9681                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9682
9683                mWindowManager.executeAppTransition();
9684            } finally {
9685                Binder.restoreCallingIdentity(ident);
9686            }
9687        }
9688    }
9689
9690    /**
9691     * Moves the input task to the docked stack.
9692     *
9693     * @param taskId Id of task to move.
9694     * @param createMode The mode the docked stack should be created in if it doesn't exist
9695     *                   already. See
9696     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9697     *                   and
9698     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9699     * @param toTop If the task and stack should be moved to the top.
9700     * @param animate Whether we should play an animation for the moving the task
9701     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9702     *                      docked stack. Pass {@code null} to use default bounds.
9703     */
9704    @Override
9705    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9706            Rect initialBounds) {
9707        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9708        synchronized (this) {
9709            long ident = Binder.clearCallingIdentity();
9710            try {
9711                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9712                        + " to createMode=" + createMode + " toTop=" + toTop);
9713                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9714                return mStackSupervisor.moveTaskToStackLocked(
9715                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9716                        "moveTaskToDockedStack", animate);
9717            } finally {
9718                Binder.restoreCallingIdentity(ident);
9719            }
9720        }
9721    }
9722
9723    /**
9724     * Moves the top activity in the input stackId to the pinned stack.
9725     *
9726     * @param stackId Id of stack to move the top activity to pinned stack.
9727     * @param bounds Bounds to use for pinned stack.
9728     *
9729     * @return True if the top activity of the input stack was successfully moved to the pinned
9730     *          stack.
9731     */
9732    @Override
9733    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9734        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9735        synchronized (this) {
9736            if (!mSupportsPictureInPicture) {
9737                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9738                        + "Device doesn't support picture-in-pciture mode");
9739            }
9740
9741            long ident = Binder.clearCallingIdentity();
9742            try {
9743                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9744            } finally {
9745                Binder.restoreCallingIdentity(ident);
9746            }
9747        }
9748    }
9749
9750    @Override
9751    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9752            boolean preserveWindows, boolean animate, int animationDuration) {
9753        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9754        long ident = Binder.clearCallingIdentity();
9755        try {
9756            synchronized (this) {
9757                if (animate) {
9758                    if (stackId == PINNED_STACK_ID) {
9759                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9760                    } else {
9761                        throw new IllegalArgumentException("Stack: " + stackId
9762                                + " doesn't support animated resize.");
9763                    }
9764                } else {
9765                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9766                            null /* tempTaskInsetBounds */, preserveWindows,
9767                            allowResizeInDockedMode, !DEFER_RESUME);
9768                }
9769            }
9770        } finally {
9771            Binder.restoreCallingIdentity(ident);
9772        }
9773    }
9774
9775    @Override
9776    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9777            Rect tempDockedTaskInsetBounds,
9778            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9779        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9780                "resizeDockedStack()");
9781        long ident = Binder.clearCallingIdentity();
9782        try {
9783            synchronized (this) {
9784                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9785                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9786                        PRESERVE_WINDOWS);
9787            }
9788        } finally {
9789            Binder.restoreCallingIdentity(ident);
9790        }
9791    }
9792
9793    @Override
9794    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9795        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9796                "resizePinnedStack()");
9797        final long ident = Binder.clearCallingIdentity();
9798        try {
9799            synchronized (this) {
9800                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9801            }
9802        } finally {
9803            Binder.restoreCallingIdentity(ident);
9804        }
9805    }
9806
9807    @Override
9808    public void positionTaskInStack(int taskId, int stackId, int position) {
9809        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9810        if (stackId == HOME_STACK_ID) {
9811            throw new IllegalArgumentException(
9812                    "positionTaskInStack: Attempt to change the position of task "
9813                    + taskId + " in/to home stack");
9814        }
9815        synchronized (this) {
9816            long ident = Binder.clearCallingIdentity();
9817            try {
9818                if (DEBUG_STACK) Slog.d(TAG_STACK,
9819                        "positionTaskInStack: positioning task=" + taskId
9820                        + " in stackId=" + stackId + " at position=" + position);
9821                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9822            } finally {
9823                Binder.restoreCallingIdentity(ident);
9824            }
9825        }
9826    }
9827
9828    @Override
9829    public List<StackInfo> getAllStackInfos() {
9830        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9831        long ident = Binder.clearCallingIdentity();
9832        try {
9833            synchronized (this) {
9834                return mStackSupervisor.getAllStackInfosLocked();
9835            }
9836        } finally {
9837            Binder.restoreCallingIdentity(ident);
9838        }
9839    }
9840
9841    @Override
9842    public StackInfo getStackInfo(int stackId) {
9843        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9844        long ident = Binder.clearCallingIdentity();
9845        try {
9846            synchronized (this) {
9847                return mStackSupervisor.getStackInfoLocked(stackId);
9848            }
9849        } finally {
9850            Binder.restoreCallingIdentity(ident);
9851        }
9852    }
9853
9854    @Override
9855    public boolean isInHomeStack(int taskId) {
9856        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9857        long ident = Binder.clearCallingIdentity();
9858        try {
9859            synchronized (this) {
9860                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9861                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9862                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9863            }
9864        } finally {
9865            Binder.restoreCallingIdentity(ident);
9866        }
9867    }
9868
9869    @Override
9870    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9871        synchronized(this) {
9872            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9873        }
9874    }
9875
9876    @Override
9877    public void updateDeviceOwner(String packageName) {
9878        final int callingUid = Binder.getCallingUid();
9879        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9880            throw new SecurityException("updateDeviceOwner called from non-system process");
9881        }
9882        synchronized (this) {
9883            mDeviceOwnerName = packageName;
9884        }
9885    }
9886
9887    @Override
9888    public void updateLockTaskPackages(int userId, String[] packages) {
9889        final int callingUid = Binder.getCallingUid();
9890        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9891            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9892                    "updateLockTaskPackages()");
9893        }
9894        synchronized (this) {
9895            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9896                    Arrays.toString(packages));
9897            mLockTaskPackages.put(userId, packages);
9898            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9899        }
9900    }
9901
9902
9903    void startLockTaskModeLocked(TaskRecord task) {
9904        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9905        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9906            return;
9907        }
9908
9909        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9910        // is initiated by system after the pinning request was shown and locked mode is initiated
9911        // by an authorized app directly
9912        final int callingUid = Binder.getCallingUid();
9913        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9914        long ident = Binder.clearCallingIdentity();
9915        try {
9916            if (!isSystemInitiated) {
9917                task.mLockTaskUid = callingUid;
9918                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9919                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9920                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9921                    StatusBarManagerInternal statusBarManager =
9922                            LocalServices.getService(StatusBarManagerInternal.class);
9923                    if (statusBarManager != null) {
9924                        statusBarManager.showScreenPinningRequest(task.taskId);
9925                    }
9926                    return;
9927                }
9928
9929                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9930                if (stack == null || task != stack.topTask()) {
9931                    throw new IllegalArgumentException("Invalid task, not in foreground");
9932                }
9933            }
9934            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9935                    "Locking fully");
9936            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9937                    ActivityManager.LOCK_TASK_MODE_PINNED :
9938                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9939                    "startLockTask", true);
9940        } finally {
9941            Binder.restoreCallingIdentity(ident);
9942        }
9943    }
9944
9945    @Override
9946    public void startLockTaskMode(int taskId) {
9947        synchronized (this) {
9948            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9949            if (task != null) {
9950                startLockTaskModeLocked(task);
9951            }
9952        }
9953    }
9954
9955    @Override
9956    public void startLockTaskMode(IBinder token) {
9957        synchronized (this) {
9958            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9959            if (r == null) {
9960                return;
9961            }
9962            final TaskRecord task = r.task;
9963            if (task != null) {
9964                startLockTaskModeLocked(task);
9965            }
9966        }
9967    }
9968
9969    @Override
9970    public void startSystemLockTaskMode(int taskId) throws RemoteException {
9971        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
9972        // This makes inner call to look as if it was initiated by system.
9973        long ident = Binder.clearCallingIdentity();
9974        try {
9975            synchronized (this) {
9976                startLockTaskMode(taskId);
9977            }
9978        } finally {
9979            Binder.restoreCallingIdentity(ident);
9980        }
9981    }
9982
9983    @Override
9984    public void stopLockTaskMode() {
9985        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9986        if (lockTask == null) {
9987            // Our work here is done.
9988            return;
9989        }
9990
9991        final int callingUid = Binder.getCallingUid();
9992        final int lockTaskUid = lockTask.mLockTaskUid;
9993        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
9994        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
9995            // Done.
9996            return;
9997        } else {
9998            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9999            // It is possible lockTaskMode was started by the system process because
10000            // android:lockTaskMode is set to a locking value in the application manifest
10001            // instead of the app calling startLockTaskMode. In this case
10002            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10003            // {@link TaskRecord.effectiveUid} instead. Also caller with
10004            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10005            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10006                    && callingUid != lockTaskUid
10007                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10008                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10009                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10010            }
10011        }
10012        long ident = Binder.clearCallingIdentity();
10013        try {
10014            Log.d(TAG, "stopLockTaskMode");
10015            // Stop lock task
10016            synchronized (this) {
10017                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10018                        "stopLockTask", true);
10019            }
10020        } finally {
10021            Binder.restoreCallingIdentity(ident);
10022        }
10023    }
10024
10025    /**
10026     * This API should be called by SystemUI only when user perform certain action to dismiss
10027     * lock task mode. We should only dismiss pinned lock task mode in this case.
10028     */
10029    @Override
10030    public void stopSystemLockTaskMode() throws RemoteException {
10031        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10032            stopLockTaskMode();
10033        } else {
10034            mStackSupervisor.showLockTaskToast();
10035        }
10036    }
10037
10038    @Override
10039    public boolean isInLockTaskMode() {
10040        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10041    }
10042
10043    @Override
10044    public int getLockTaskModeState() {
10045        synchronized (this) {
10046            return mStackSupervisor.getLockTaskModeState();
10047        }
10048    }
10049
10050    @Override
10051    public void showLockTaskEscapeMessage(IBinder token) {
10052        synchronized (this) {
10053            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10054            if (r == null) {
10055                return;
10056            }
10057            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10058        }
10059    }
10060
10061    // =========================================================
10062    // CONTENT PROVIDERS
10063    // =========================================================
10064
10065    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10066        List<ProviderInfo> providers = null;
10067        try {
10068            providers = AppGlobals.getPackageManager()
10069                    .queryContentProviders(app.processName, app.uid,
10070                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10071                                    | MATCH_DEBUG_TRIAGED_MISSING)
10072                    .getList();
10073        } catch (RemoteException ex) {
10074        }
10075        if (DEBUG_MU) Slog.v(TAG_MU,
10076                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10077        int userId = app.userId;
10078        if (providers != null) {
10079            int N = providers.size();
10080            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10081            for (int i=0; i<N; i++) {
10082                ProviderInfo cpi =
10083                    (ProviderInfo)providers.get(i);
10084                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10085                        cpi.name, cpi.flags);
10086                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10087                    // This is a singleton provider, but a user besides the
10088                    // default user is asking to initialize a process it runs
10089                    // in...  well, no, it doesn't actually run in this process,
10090                    // it runs in the process of the default user.  Get rid of it.
10091                    providers.remove(i);
10092                    N--;
10093                    i--;
10094                    continue;
10095                }
10096
10097                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10098                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10099                if (cpr == null) {
10100                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10101                    mProviderMap.putProviderByClass(comp, cpr);
10102                }
10103                if (DEBUG_MU) Slog.v(TAG_MU,
10104                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10105                app.pubProviders.put(cpi.name, cpr);
10106                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10107                    // Don't add this if it is a platform component that is marked
10108                    // to run in multiple processes, because this is actually
10109                    // part of the framework so doesn't make sense to track as a
10110                    // separate apk in the process.
10111                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10112                            mProcessStats);
10113                }
10114                notifyPackageUse(cpi.applicationInfo.packageName,
10115                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10116            }
10117        }
10118        return providers;
10119    }
10120
10121    /**
10122     * Check if {@link ProcessRecord} has a possible chance at accessing the
10123     * given {@link ProviderInfo}. Final permission checking is always done
10124     * in {@link ContentProvider}.
10125     */
10126    private final String checkContentProviderPermissionLocked(
10127            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10128        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10129        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10130        boolean checkedGrants = false;
10131        if (checkUser) {
10132            // Looking for cross-user grants before enforcing the typical cross-users permissions
10133            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10134            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10135                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10136                    return null;
10137                }
10138                checkedGrants = true;
10139            }
10140            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10141                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10142            if (userId != tmpTargetUserId) {
10143                // When we actually went to determine the final targer user ID, this ended
10144                // up different than our initial check for the authority.  This is because
10145                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10146                // SELF.  So we need to re-check the grants again.
10147                checkedGrants = false;
10148            }
10149        }
10150        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10151                cpi.applicationInfo.uid, cpi.exported)
10152                == PackageManager.PERMISSION_GRANTED) {
10153            return null;
10154        }
10155        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10156                cpi.applicationInfo.uid, cpi.exported)
10157                == PackageManager.PERMISSION_GRANTED) {
10158            return null;
10159        }
10160
10161        PathPermission[] pps = cpi.pathPermissions;
10162        if (pps != null) {
10163            int i = pps.length;
10164            while (i > 0) {
10165                i--;
10166                PathPermission pp = pps[i];
10167                String pprperm = pp.getReadPermission();
10168                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10169                        cpi.applicationInfo.uid, cpi.exported)
10170                        == PackageManager.PERMISSION_GRANTED) {
10171                    return null;
10172                }
10173                String ppwperm = pp.getWritePermission();
10174                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10175                        cpi.applicationInfo.uid, cpi.exported)
10176                        == PackageManager.PERMISSION_GRANTED) {
10177                    return null;
10178                }
10179            }
10180        }
10181        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10182            return null;
10183        }
10184
10185        String msg;
10186        if (!cpi.exported) {
10187            msg = "Permission Denial: opening provider " + cpi.name
10188                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10189                    + ", uid=" + callingUid + ") that is not exported from uid "
10190                    + cpi.applicationInfo.uid;
10191        } else {
10192            msg = "Permission Denial: opening provider " + cpi.name
10193                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10194                    + ", uid=" + callingUid + ") requires "
10195                    + cpi.readPermission + " or " + cpi.writePermission;
10196        }
10197        Slog.w(TAG, msg);
10198        return msg;
10199    }
10200
10201    /**
10202     * Returns if the ContentProvider has granted a uri to callingUid
10203     */
10204    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10205        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10206        if (perms != null) {
10207            for (int i=perms.size()-1; i>=0; i--) {
10208                GrantUri grantUri = perms.keyAt(i);
10209                if (grantUri.sourceUserId == userId || !checkUser) {
10210                    if (matchesProvider(grantUri.uri, cpi)) {
10211                        return true;
10212                    }
10213                }
10214            }
10215        }
10216        return false;
10217    }
10218
10219    /**
10220     * Returns true if the uri authority is one of the authorities specified in the provider.
10221     */
10222    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10223        String uriAuth = uri.getAuthority();
10224        String cpiAuth = cpi.authority;
10225        if (cpiAuth.indexOf(';') == -1) {
10226            return cpiAuth.equals(uriAuth);
10227        }
10228        String[] cpiAuths = cpiAuth.split(";");
10229        int length = cpiAuths.length;
10230        for (int i = 0; i < length; i++) {
10231            if (cpiAuths[i].equals(uriAuth)) return true;
10232        }
10233        return false;
10234    }
10235
10236    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10237            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10238        if (r != null) {
10239            for (int i=0; i<r.conProviders.size(); i++) {
10240                ContentProviderConnection conn = r.conProviders.get(i);
10241                if (conn.provider == cpr) {
10242                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10243                            "Adding provider requested by "
10244                            + r.processName + " from process "
10245                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10246                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10247                    if (stable) {
10248                        conn.stableCount++;
10249                        conn.numStableIncs++;
10250                    } else {
10251                        conn.unstableCount++;
10252                        conn.numUnstableIncs++;
10253                    }
10254                    return conn;
10255                }
10256            }
10257            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10258            if (stable) {
10259                conn.stableCount = 1;
10260                conn.numStableIncs = 1;
10261            } else {
10262                conn.unstableCount = 1;
10263                conn.numUnstableIncs = 1;
10264            }
10265            cpr.connections.add(conn);
10266            r.conProviders.add(conn);
10267            startAssociationLocked(r.uid, r.processName, r.curProcState,
10268                    cpr.uid, cpr.name, cpr.info.processName);
10269            return conn;
10270        }
10271        cpr.addExternalProcessHandleLocked(externalProcessToken);
10272        return null;
10273    }
10274
10275    boolean decProviderCountLocked(ContentProviderConnection conn,
10276            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10277        if (conn != null) {
10278            cpr = conn.provider;
10279            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10280                    "Removing provider requested by "
10281                    + conn.client.processName + " from process "
10282                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10283                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10284            if (stable) {
10285                conn.stableCount--;
10286            } else {
10287                conn.unstableCount--;
10288            }
10289            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10290                cpr.connections.remove(conn);
10291                conn.client.conProviders.remove(conn);
10292                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10293                    // The client is more important than last activity -- note the time this
10294                    // is happening, so we keep the old provider process around a bit as last
10295                    // activity to avoid thrashing it.
10296                    if (cpr.proc != null) {
10297                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10298                    }
10299                }
10300                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10301                return true;
10302            }
10303            return false;
10304        }
10305        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10306        return false;
10307    }
10308
10309    private void checkTime(long startTime, String where) {
10310        long now = SystemClock.elapsedRealtime();
10311        if ((now-startTime) > 1000) {
10312            // If we are taking more than a second, log about it.
10313            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10314        }
10315    }
10316
10317    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10318            String name, IBinder token, boolean stable, int userId) {
10319        ContentProviderRecord cpr;
10320        ContentProviderConnection conn = null;
10321        ProviderInfo cpi = null;
10322
10323        synchronized(this) {
10324            long startTime = SystemClock.elapsedRealtime();
10325
10326            ProcessRecord r = null;
10327            if (caller != null) {
10328                r = getRecordForAppLocked(caller);
10329                if (r == null) {
10330                    throw new SecurityException(
10331                            "Unable to find app for caller " + caller
10332                          + " (pid=" + Binder.getCallingPid()
10333                          + ") when getting content provider " + name);
10334                }
10335            }
10336
10337            boolean checkCrossUser = true;
10338
10339            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10340
10341            // First check if this content provider has been published...
10342            cpr = mProviderMap.getProviderByName(name, userId);
10343            // If that didn't work, check if it exists for user 0 and then
10344            // verify that it's a singleton provider before using it.
10345            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10346                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10347                if (cpr != null) {
10348                    cpi = cpr.info;
10349                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10350                            cpi.name, cpi.flags)
10351                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10352                        userId = UserHandle.USER_SYSTEM;
10353                        checkCrossUser = false;
10354                    } else {
10355                        cpr = null;
10356                        cpi = null;
10357                    }
10358                }
10359            }
10360
10361            boolean providerRunning = cpr != null;
10362            if (providerRunning) {
10363                cpi = cpr.info;
10364                String msg;
10365                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10366                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10367                        != null) {
10368                    throw new SecurityException(msg);
10369                }
10370                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10371
10372                if (r != null && cpr.canRunHere(r)) {
10373                    // This provider has been published or is in the process
10374                    // of being published...  but it is also allowed to run
10375                    // in the caller's process, so don't make a connection
10376                    // and just let the caller instantiate its own instance.
10377                    ContentProviderHolder holder = cpr.newHolder(null);
10378                    // don't give caller the provider object, it needs
10379                    // to make its own.
10380                    holder.provider = null;
10381                    return holder;
10382                }
10383
10384                final long origId = Binder.clearCallingIdentity();
10385
10386                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10387
10388                // In this case the provider instance already exists, so we can
10389                // return it right away.
10390                conn = incProviderCountLocked(r, cpr, token, stable);
10391                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10392                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10393                        // If this is a perceptible app accessing the provider,
10394                        // make sure to count it as being accessed and thus
10395                        // back up on the LRU list.  This is good because
10396                        // content providers are often expensive to start.
10397                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10398                        updateLruProcessLocked(cpr.proc, false, null);
10399                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10400                    }
10401                }
10402
10403                if (cpr.proc != null) {
10404                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10405                    boolean success = updateOomAdjLocked(cpr.proc);
10406                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10407                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10408                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10409                    // NOTE: there is still a race here where a signal could be
10410                    // pending on the process even though we managed to update its
10411                    // adj level.  Not sure what to do about this, but at least
10412                    // the race is now smaller.
10413                    if (!success) {
10414                        // Uh oh...  it looks like the provider's process
10415                        // has been killed on us.  We need to wait for a new
10416                        // process to be started, and make sure its death
10417                        // doesn't kill our process.
10418                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10419                                + " is crashing; detaching " + r);
10420                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10421                        checkTime(startTime, "getContentProviderImpl: before appDied");
10422                        appDiedLocked(cpr.proc);
10423                        checkTime(startTime, "getContentProviderImpl: after appDied");
10424                        if (!lastRef) {
10425                            // This wasn't the last ref our process had on
10426                            // the provider...  we have now been killed, bail.
10427                            return null;
10428                        }
10429                        providerRunning = false;
10430                        conn = null;
10431                    }
10432                }
10433
10434                Binder.restoreCallingIdentity(origId);
10435            }
10436
10437            if (!providerRunning) {
10438                try {
10439                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10440                    cpi = AppGlobals.getPackageManager().
10441                        resolveContentProvider(name,
10442                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10443                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10444                } catch (RemoteException ex) {
10445                }
10446                if (cpi == null) {
10447                    return null;
10448                }
10449                // If the provider is a singleton AND
10450                // (it's a call within the same user || the provider is a
10451                // privileged app)
10452                // Then allow connecting to the singleton provider
10453                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10454                        cpi.name, cpi.flags)
10455                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10456                if (singleton) {
10457                    userId = UserHandle.USER_SYSTEM;
10458                }
10459                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10460                checkTime(startTime, "getContentProviderImpl: got app info for user");
10461
10462                String msg;
10463                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10464                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10465                        != null) {
10466                    throw new SecurityException(msg);
10467                }
10468                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10469
10470                if (!mProcessesReady
10471                        && !cpi.processName.equals("system")) {
10472                    // If this content provider does not run in the system
10473                    // process, and the system is not yet ready to run other
10474                    // processes, then fail fast instead of hanging.
10475                    throw new IllegalArgumentException(
10476                            "Attempt to launch content provider before system ready");
10477                }
10478
10479                // Make sure that the user who owns this provider is running.  If not,
10480                // we don't want to allow it to run.
10481                if (!mUserController.isUserRunningLocked(userId, 0)) {
10482                    Slog.w(TAG, "Unable to launch app "
10483                            + cpi.applicationInfo.packageName + "/"
10484                            + cpi.applicationInfo.uid + " for provider "
10485                            + name + ": user " + userId + " is stopped");
10486                    return null;
10487                }
10488
10489                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10490                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10491                cpr = mProviderMap.getProviderByClass(comp, userId);
10492                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10493                final boolean firstClass = cpr == null;
10494                if (firstClass) {
10495                    final long ident = Binder.clearCallingIdentity();
10496
10497                    // If permissions need a review before any of the app components can run,
10498                    // we return no provider and launch a review activity if the calling app
10499                    // is in the foreground.
10500                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10501                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10502                            return null;
10503                        }
10504                    }
10505
10506                    try {
10507                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10508                        ApplicationInfo ai =
10509                            AppGlobals.getPackageManager().
10510                                getApplicationInfo(
10511                                        cpi.applicationInfo.packageName,
10512                                        STOCK_PM_FLAGS, userId);
10513                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10514                        if (ai == null) {
10515                            Slog.w(TAG, "No package info for content provider "
10516                                    + cpi.name);
10517                            return null;
10518                        }
10519                        ai = getAppInfoForUser(ai, userId);
10520                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10521                    } catch (RemoteException ex) {
10522                        // pm is in same process, this will never happen.
10523                    } finally {
10524                        Binder.restoreCallingIdentity(ident);
10525                    }
10526                }
10527
10528                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10529
10530                if (r != null && cpr.canRunHere(r)) {
10531                    // If this is a multiprocess provider, then just return its
10532                    // info and allow the caller to instantiate it.  Only do
10533                    // this if the provider is the same user as the caller's
10534                    // process, or can run as root (so can be in any process).
10535                    return cpr.newHolder(null);
10536                }
10537
10538                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10539                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10540                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10541
10542                // This is single process, and our app is now connecting to it.
10543                // See if we are already in the process of launching this
10544                // provider.
10545                final int N = mLaunchingProviders.size();
10546                int i;
10547                for (i = 0; i < N; i++) {
10548                    if (mLaunchingProviders.get(i) == cpr) {
10549                        break;
10550                    }
10551                }
10552
10553                // If the provider is not already being launched, then get it
10554                // started.
10555                if (i >= N) {
10556                    final long origId = Binder.clearCallingIdentity();
10557
10558                    try {
10559                        // Content provider is now in use, its package can't be stopped.
10560                        try {
10561                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10562                            AppGlobals.getPackageManager().setPackageStoppedState(
10563                                    cpr.appInfo.packageName, false, userId);
10564                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10565                        } catch (RemoteException e) {
10566                        } catch (IllegalArgumentException e) {
10567                            Slog.w(TAG, "Failed trying to unstop package "
10568                                    + cpr.appInfo.packageName + ": " + e);
10569                        }
10570
10571                        // Use existing process if already started
10572                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10573                        ProcessRecord proc = getProcessRecordLocked(
10574                                cpi.processName, cpr.appInfo.uid, false);
10575                        if (proc != null && proc.thread != null) {
10576                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10577                                    "Installing in existing process " + proc);
10578                            if (!proc.pubProviders.containsKey(cpi.name)) {
10579                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10580                                proc.pubProviders.put(cpi.name, cpr);
10581                                try {
10582                                    proc.thread.scheduleInstallProvider(cpi);
10583                                } catch (RemoteException e) {
10584                                }
10585                            }
10586                        } else {
10587                            checkTime(startTime, "getContentProviderImpl: before start process");
10588                            proc = startProcessLocked(cpi.processName,
10589                                    cpr.appInfo, false, 0, "content provider",
10590                                    new ComponentName(cpi.applicationInfo.packageName,
10591                                            cpi.name), false, false, false);
10592                            checkTime(startTime, "getContentProviderImpl: after start process");
10593                            if (proc == null) {
10594                                Slog.w(TAG, "Unable to launch app "
10595                                        + cpi.applicationInfo.packageName + "/"
10596                                        + cpi.applicationInfo.uid + " for provider "
10597                                        + name + ": process is bad");
10598                                return null;
10599                            }
10600                        }
10601                        cpr.launchingApp = proc;
10602                        mLaunchingProviders.add(cpr);
10603                    } finally {
10604                        Binder.restoreCallingIdentity(origId);
10605                    }
10606                }
10607
10608                checkTime(startTime, "getContentProviderImpl: updating data structures");
10609
10610                // Make sure the provider is published (the same provider class
10611                // may be published under multiple names).
10612                if (firstClass) {
10613                    mProviderMap.putProviderByClass(comp, cpr);
10614                }
10615
10616                mProviderMap.putProviderByName(name, cpr);
10617                conn = incProviderCountLocked(r, cpr, token, stable);
10618                if (conn != null) {
10619                    conn.waiting = true;
10620                }
10621            }
10622            checkTime(startTime, "getContentProviderImpl: done!");
10623        }
10624
10625        // Wait for the provider to be published...
10626        synchronized (cpr) {
10627            while (cpr.provider == null) {
10628                if (cpr.launchingApp == null) {
10629                    Slog.w(TAG, "Unable to launch app "
10630                            + cpi.applicationInfo.packageName + "/"
10631                            + cpi.applicationInfo.uid + " for provider "
10632                            + name + ": launching app became null");
10633                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10634                            UserHandle.getUserId(cpi.applicationInfo.uid),
10635                            cpi.applicationInfo.packageName,
10636                            cpi.applicationInfo.uid, name);
10637                    return null;
10638                }
10639                try {
10640                    if (DEBUG_MU) Slog.v(TAG_MU,
10641                            "Waiting to start provider " + cpr
10642                            + " launchingApp=" + cpr.launchingApp);
10643                    if (conn != null) {
10644                        conn.waiting = true;
10645                    }
10646                    cpr.wait();
10647                } catch (InterruptedException ex) {
10648                } finally {
10649                    if (conn != null) {
10650                        conn.waiting = false;
10651                    }
10652                }
10653            }
10654        }
10655        return cpr != null ? cpr.newHolder(conn) : null;
10656    }
10657
10658    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10659            ProcessRecord r, final int userId) {
10660        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10661                cpi.packageName, userId)) {
10662
10663            final boolean callerForeground = r == null || r.setSchedGroup
10664                    != ProcessList.SCHED_GROUP_BACKGROUND;
10665
10666            // Show a permission review UI only for starting from a foreground app
10667            if (!callerForeground) {
10668                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10669                        + cpi.packageName + " requires a permissions review");
10670                return false;
10671            }
10672
10673            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10674            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10675                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10676            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10677
10678            if (DEBUG_PERMISSIONS_REVIEW) {
10679                Slog.i(TAG, "u" + userId + " Launching permission review "
10680                        + "for package " + cpi.packageName);
10681            }
10682
10683            final UserHandle userHandle = new UserHandle(userId);
10684            mHandler.post(new Runnable() {
10685                @Override
10686                public void run() {
10687                    mContext.startActivityAsUser(intent, userHandle);
10688                }
10689            });
10690
10691            return false;
10692        }
10693
10694        return true;
10695    }
10696
10697    PackageManagerInternal getPackageManagerInternalLocked() {
10698        if (mPackageManagerInt == null) {
10699            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10700        }
10701        return mPackageManagerInt;
10702    }
10703
10704    @Override
10705    public final ContentProviderHolder getContentProvider(
10706            IApplicationThread caller, String name, int userId, boolean stable) {
10707        enforceNotIsolatedCaller("getContentProvider");
10708        if (caller == null) {
10709            String msg = "null IApplicationThread when getting content provider "
10710                    + name;
10711            Slog.w(TAG, msg);
10712            throw new SecurityException(msg);
10713        }
10714        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10715        // with cross-user grant.
10716        return getContentProviderImpl(caller, name, null, stable, userId);
10717    }
10718
10719    public ContentProviderHolder getContentProviderExternal(
10720            String name, int userId, IBinder token) {
10721        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10722            "Do not have permission in call getContentProviderExternal()");
10723        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10724                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10725        return getContentProviderExternalUnchecked(name, token, userId);
10726    }
10727
10728    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10729            IBinder token, int userId) {
10730        return getContentProviderImpl(null, name, token, true, userId);
10731    }
10732
10733    /**
10734     * Drop a content provider from a ProcessRecord's bookkeeping
10735     */
10736    public void removeContentProvider(IBinder connection, boolean stable) {
10737        enforceNotIsolatedCaller("removeContentProvider");
10738        long ident = Binder.clearCallingIdentity();
10739        try {
10740            synchronized (this) {
10741                ContentProviderConnection conn;
10742                try {
10743                    conn = (ContentProviderConnection)connection;
10744                } catch (ClassCastException e) {
10745                    String msg ="removeContentProvider: " + connection
10746                            + " not a ContentProviderConnection";
10747                    Slog.w(TAG, msg);
10748                    throw new IllegalArgumentException(msg);
10749                }
10750                if (conn == null) {
10751                    throw new NullPointerException("connection is null");
10752                }
10753                if (decProviderCountLocked(conn, null, null, stable)) {
10754                    updateOomAdjLocked();
10755                }
10756            }
10757        } finally {
10758            Binder.restoreCallingIdentity(ident);
10759        }
10760    }
10761
10762    public void removeContentProviderExternal(String name, IBinder token) {
10763        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10764            "Do not have permission in call removeContentProviderExternal()");
10765        int userId = UserHandle.getCallingUserId();
10766        long ident = Binder.clearCallingIdentity();
10767        try {
10768            removeContentProviderExternalUnchecked(name, token, userId);
10769        } finally {
10770            Binder.restoreCallingIdentity(ident);
10771        }
10772    }
10773
10774    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10775        synchronized (this) {
10776            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10777            if(cpr == null) {
10778                //remove from mProvidersByClass
10779                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10780                return;
10781            }
10782
10783            //update content provider record entry info
10784            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10785            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10786            if (localCpr.hasExternalProcessHandles()) {
10787                if (localCpr.removeExternalProcessHandleLocked(token)) {
10788                    updateOomAdjLocked();
10789                } else {
10790                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10791                            + " with no external reference for token: "
10792                            + token + ".");
10793                }
10794            } else {
10795                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10796                        + " with no external references.");
10797            }
10798        }
10799    }
10800
10801    public final void publishContentProviders(IApplicationThread caller,
10802            List<ContentProviderHolder> providers) {
10803        if (providers == null) {
10804            return;
10805        }
10806
10807        enforceNotIsolatedCaller("publishContentProviders");
10808        synchronized (this) {
10809            final ProcessRecord r = getRecordForAppLocked(caller);
10810            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10811            if (r == null) {
10812                throw new SecurityException(
10813                        "Unable to find app for caller " + caller
10814                      + " (pid=" + Binder.getCallingPid()
10815                      + ") when publishing content providers");
10816            }
10817
10818            final long origId = Binder.clearCallingIdentity();
10819
10820            final int N = providers.size();
10821            for (int i = 0; i < N; i++) {
10822                ContentProviderHolder src = providers.get(i);
10823                if (src == null || src.info == null || src.provider == null) {
10824                    continue;
10825                }
10826                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10827                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10828                if (dst != null) {
10829                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10830                    mProviderMap.putProviderByClass(comp, dst);
10831                    String names[] = dst.info.authority.split(";");
10832                    for (int j = 0; j < names.length; j++) {
10833                        mProviderMap.putProviderByName(names[j], dst);
10834                    }
10835
10836                    int launchingCount = mLaunchingProviders.size();
10837                    int j;
10838                    boolean wasInLaunchingProviders = false;
10839                    for (j = 0; j < launchingCount; j++) {
10840                        if (mLaunchingProviders.get(j) == dst) {
10841                            mLaunchingProviders.remove(j);
10842                            wasInLaunchingProviders = true;
10843                            j--;
10844                            launchingCount--;
10845                        }
10846                    }
10847                    if (wasInLaunchingProviders) {
10848                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10849                    }
10850                    synchronized (dst) {
10851                        dst.provider = src.provider;
10852                        dst.proc = r;
10853                        dst.notifyAll();
10854                    }
10855                    updateOomAdjLocked(r);
10856                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10857                            src.info.authority);
10858                }
10859            }
10860
10861            Binder.restoreCallingIdentity(origId);
10862        }
10863    }
10864
10865    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10866        ContentProviderConnection conn;
10867        try {
10868            conn = (ContentProviderConnection)connection;
10869        } catch (ClassCastException e) {
10870            String msg ="refContentProvider: " + connection
10871                    + " not a ContentProviderConnection";
10872            Slog.w(TAG, msg);
10873            throw new IllegalArgumentException(msg);
10874        }
10875        if (conn == null) {
10876            throw new NullPointerException("connection is null");
10877        }
10878
10879        synchronized (this) {
10880            if (stable > 0) {
10881                conn.numStableIncs += stable;
10882            }
10883            stable = conn.stableCount + stable;
10884            if (stable < 0) {
10885                throw new IllegalStateException("stableCount < 0: " + stable);
10886            }
10887
10888            if (unstable > 0) {
10889                conn.numUnstableIncs += unstable;
10890            }
10891            unstable = conn.unstableCount + unstable;
10892            if (unstable < 0) {
10893                throw new IllegalStateException("unstableCount < 0: " + unstable);
10894            }
10895
10896            if ((stable+unstable) <= 0) {
10897                throw new IllegalStateException("ref counts can't go to zero here: stable="
10898                        + stable + " unstable=" + unstable);
10899            }
10900            conn.stableCount = stable;
10901            conn.unstableCount = unstable;
10902            return !conn.dead;
10903        }
10904    }
10905
10906    public void unstableProviderDied(IBinder connection) {
10907        ContentProviderConnection conn;
10908        try {
10909            conn = (ContentProviderConnection)connection;
10910        } catch (ClassCastException e) {
10911            String msg ="refContentProvider: " + connection
10912                    + " not a ContentProviderConnection";
10913            Slog.w(TAG, msg);
10914            throw new IllegalArgumentException(msg);
10915        }
10916        if (conn == null) {
10917            throw new NullPointerException("connection is null");
10918        }
10919
10920        // Safely retrieve the content provider associated with the connection.
10921        IContentProvider provider;
10922        synchronized (this) {
10923            provider = conn.provider.provider;
10924        }
10925
10926        if (provider == null) {
10927            // Um, yeah, we're way ahead of you.
10928            return;
10929        }
10930
10931        // Make sure the caller is being honest with us.
10932        if (provider.asBinder().pingBinder()) {
10933            // Er, no, still looks good to us.
10934            synchronized (this) {
10935                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10936                        + " says " + conn + " died, but we don't agree");
10937                return;
10938            }
10939        }
10940
10941        // Well look at that!  It's dead!
10942        synchronized (this) {
10943            if (conn.provider.provider != provider) {
10944                // But something changed...  good enough.
10945                return;
10946            }
10947
10948            ProcessRecord proc = conn.provider.proc;
10949            if (proc == null || proc.thread == null) {
10950                // Seems like the process is already cleaned up.
10951                return;
10952            }
10953
10954            // As far as we're concerned, this is just like receiving a
10955            // death notification...  just a bit prematurely.
10956            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10957                    + ") early provider death");
10958            final long ident = Binder.clearCallingIdentity();
10959            try {
10960                appDiedLocked(proc);
10961            } finally {
10962                Binder.restoreCallingIdentity(ident);
10963            }
10964        }
10965    }
10966
10967    @Override
10968    public void appNotRespondingViaProvider(IBinder connection) {
10969        enforceCallingPermission(
10970                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10971
10972        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10973        if (conn == null) {
10974            Slog.w(TAG, "ContentProviderConnection is null");
10975            return;
10976        }
10977
10978        final ProcessRecord host = conn.provider.proc;
10979        if (host == null) {
10980            Slog.w(TAG, "Failed to find hosting ProcessRecord");
10981            return;
10982        }
10983
10984        mHandler.post(new Runnable() {
10985            @Override
10986            public void run() {
10987                mAppErrors.appNotResponding(host, null, null, false,
10988                        "ContentProvider not responding");
10989            }
10990        });
10991    }
10992
10993    public final void installSystemProviders() {
10994        List<ProviderInfo> providers;
10995        synchronized (this) {
10996            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10997            providers = generateApplicationProvidersLocked(app);
10998            if (providers != null) {
10999                for (int i=providers.size()-1; i>=0; i--) {
11000                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11001                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11002                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11003                                + ": not system .apk");
11004                        providers.remove(i);
11005                    }
11006                }
11007            }
11008        }
11009        if (providers != null) {
11010            mSystemThread.installSystemProviders(providers);
11011        }
11012
11013        mCoreSettingsObserver = new CoreSettingsObserver(this);
11014        mFontScaleSettingObserver = new FontScaleSettingObserver();
11015
11016        //mUsageStatsService.monitorPackages();
11017    }
11018
11019    private void startPersistentApps(int matchFlags) {
11020        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11021
11022        synchronized (this) {
11023            try {
11024                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11025                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11026                for (ApplicationInfo app : apps) {
11027                    if (!"android".equals(app.packageName)) {
11028                        addAppLocked(app, false, null /* ABI override */);
11029                    }
11030                }
11031            } catch (RemoteException ex) {
11032            }
11033        }
11034    }
11035
11036    /**
11037     * When a user is unlocked, we need to install encryption-unaware providers
11038     * belonging to any running apps.
11039     */
11040    private void installEncryptionUnawareProviders(int userId) {
11041        // We're only interested in providers that are encryption unaware, and
11042        // we don't care about uninstalled apps, since there's no way they're
11043        // running at this point.
11044        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11045
11046        synchronized (this) {
11047            final int NP = mProcessNames.getMap().size();
11048            for (int ip = 0; ip < NP; ip++) {
11049                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11050                final int NA = apps.size();
11051                for (int ia = 0; ia < NA; ia++) {
11052                    final ProcessRecord app = apps.valueAt(ia);
11053                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11054
11055                    final int NG = app.pkgList.size();
11056                    for (int ig = 0; ig < NG; ig++) {
11057                        try {
11058                            final String pkgName = app.pkgList.keyAt(ig);
11059                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11060                                    .getPackageInfo(pkgName, matchFlags, userId);
11061                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11062                                for (ProviderInfo provInfo : pkgInfo.providers) {
11063                                    Log.v(TAG, "Installing " + provInfo);
11064                                    app.thread.scheduleInstallProvider(provInfo);
11065                                }
11066                            }
11067                        } catch (RemoteException ignored) {
11068                        }
11069                    }
11070                }
11071            }
11072        }
11073    }
11074
11075    /**
11076     * Allows apps to retrieve the MIME type of a URI.
11077     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11078     * users, then it does not need permission to access the ContentProvider.
11079     * Either, it needs cross-user uri grants.
11080     *
11081     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11082     *
11083     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11084     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11085     */
11086    public String getProviderMimeType(Uri uri, int userId) {
11087        enforceNotIsolatedCaller("getProviderMimeType");
11088        final String name = uri.getAuthority();
11089        int callingUid = Binder.getCallingUid();
11090        int callingPid = Binder.getCallingPid();
11091        long ident = 0;
11092        boolean clearedIdentity = false;
11093        synchronized (this) {
11094            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11095        }
11096        if (canClearIdentity(callingPid, callingUid, userId)) {
11097            clearedIdentity = true;
11098            ident = Binder.clearCallingIdentity();
11099        }
11100        ContentProviderHolder holder = null;
11101        try {
11102            holder = getContentProviderExternalUnchecked(name, null, userId);
11103            if (holder != null) {
11104                return holder.provider.getType(uri);
11105            }
11106        } catch (RemoteException e) {
11107            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11108            return null;
11109        } finally {
11110            // We need to clear the identity to call removeContentProviderExternalUnchecked
11111            if (!clearedIdentity) {
11112                ident = Binder.clearCallingIdentity();
11113            }
11114            try {
11115                if (holder != null) {
11116                    removeContentProviderExternalUnchecked(name, null, userId);
11117                }
11118            } finally {
11119                Binder.restoreCallingIdentity(ident);
11120            }
11121        }
11122
11123        return null;
11124    }
11125
11126    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11127        if (UserHandle.getUserId(callingUid) == userId) {
11128            return true;
11129        }
11130        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11131                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11132                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11133                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11134                return true;
11135        }
11136        return false;
11137    }
11138
11139    // =========================================================
11140    // GLOBAL MANAGEMENT
11141    // =========================================================
11142
11143    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11144            boolean isolated, int isolatedUid) {
11145        String proc = customProcess != null ? customProcess : info.processName;
11146        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11147        final int userId = UserHandle.getUserId(info.uid);
11148        int uid = info.uid;
11149        if (isolated) {
11150            if (isolatedUid == 0) {
11151                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11152                while (true) {
11153                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11154                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11155                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11156                    }
11157                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11158                    mNextIsolatedProcessUid++;
11159                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11160                        // No process for this uid, use it.
11161                        break;
11162                    }
11163                    stepsLeft--;
11164                    if (stepsLeft <= 0) {
11165                        return null;
11166                    }
11167                }
11168            } else {
11169                // Special case for startIsolatedProcess (internal only), where
11170                // the uid of the isolated process is specified by the caller.
11171                uid = isolatedUid;
11172            }
11173        }
11174        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11175        if (!mBooted && !mBooting
11176                && userId == UserHandle.USER_SYSTEM
11177                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11178            r.persistent = true;
11179        }
11180        addProcessNameLocked(r);
11181        return r;
11182    }
11183
11184    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11185            String abiOverride) {
11186        ProcessRecord app;
11187        if (!isolated) {
11188            app = getProcessRecordLocked(info.processName, info.uid, true);
11189        } else {
11190            app = null;
11191        }
11192
11193        if (app == null) {
11194            app = newProcessRecordLocked(info, null, isolated, 0);
11195            updateLruProcessLocked(app, false, null);
11196            updateOomAdjLocked();
11197        }
11198
11199        // This package really, really can not be stopped.
11200        try {
11201            AppGlobals.getPackageManager().setPackageStoppedState(
11202                    info.packageName, false, UserHandle.getUserId(app.uid));
11203        } catch (RemoteException e) {
11204        } catch (IllegalArgumentException e) {
11205            Slog.w(TAG, "Failed trying to unstop package "
11206                    + info.packageName + ": " + e);
11207        }
11208
11209        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11210            app.persistent = true;
11211            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11212        }
11213        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11214            mPersistentStartingProcesses.add(app);
11215            startProcessLocked(app, "added application", app.processName, abiOverride,
11216                    null /* entryPoint */, null /* entryPointArgs */);
11217        }
11218
11219        return app;
11220    }
11221
11222    public void unhandledBack() {
11223        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11224                "unhandledBack()");
11225
11226        synchronized(this) {
11227            final long origId = Binder.clearCallingIdentity();
11228            try {
11229                getFocusedStack().unhandledBackLocked();
11230            } finally {
11231                Binder.restoreCallingIdentity(origId);
11232            }
11233        }
11234    }
11235
11236    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11237        enforceNotIsolatedCaller("openContentUri");
11238        final int userId = UserHandle.getCallingUserId();
11239        String name = uri.getAuthority();
11240        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11241        ParcelFileDescriptor pfd = null;
11242        if (cph != null) {
11243            // We record the binder invoker's uid in thread-local storage before
11244            // going to the content provider to open the file.  Later, in the code
11245            // that handles all permissions checks, we look for this uid and use
11246            // that rather than the Activity Manager's own uid.  The effect is that
11247            // we do the check against the caller's permissions even though it looks
11248            // to the content provider like the Activity Manager itself is making
11249            // the request.
11250            Binder token = new Binder();
11251            sCallerIdentity.set(new Identity(
11252                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11253            try {
11254                pfd = cph.provider.openFile(null, uri, "r", null, token);
11255            } catch (FileNotFoundException e) {
11256                // do nothing; pfd will be returned null
11257            } finally {
11258                // Ensure that whatever happens, we clean up the identity state
11259                sCallerIdentity.remove();
11260                // Ensure we're done with the provider.
11261                removeContentProviderExternalUnchecked(name, null, userId);
11262            }
11263        } else {
11264            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11265        }
11266        return pfd;
11267    }
11268
11269    // Actually is sleeping or shutting down or whatever else in the future
11270    // is an inactive state.
11271    public boolean isSleepingOrShuttingDown() {
11272        return isSleeping() || mShuttingDown;
11273    }
11274
11275    public boolean isSleeping() {
11276        return mSleeping;
11277    }
11278
11279    void onWakefulnessChanged(int wakefulness) {
11280        synchronized(this) {
11281            mWakefulness = wakefulness;
11282            updateSleepIfNeededLocked();
11283        }
11284    }
11285
11286    void finishRunningVoiceLocked() {
11287        if (mRunningVoice != null) {
11288            mRunningVoice = null;
11289            mVoiceWakeLock.release();
11290            updateSleepIfNeededLocked();
11291        }
11292    }
11293
11294    void startTimeTrackingFocusedActivityLocked() {
11295        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11296            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11297        }
11298    }
11299
11300    void updateSleepIfNeededLocked() {
11301        if (mSleeping && !shouldSleepLocked()) {
11302            mSleeping = false;
11303            startTimeTrackingFocusedActivityLocked();
11304            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11305            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11306            updateOomAdjLocked();
11307        } else if (!mSleeping && shouldSleepLocked()) {
11308            mSleeping = true;
11309            if (mCurAppTimeTracker != null) {
11310                mCurAppTimeTracker.stop();
11311            }
11312            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11313            mStackSupervisor.goingToSleepLocked();
11314            updateOomAdjLocked();
11315
11316            // Initialize the wake times of all processes.
11317            checkExcessivePowerUsageLocked(false);
11318            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11319            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11320            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11321        }
11322    }
11323
11324    private boolean shouldSleepLocked() {
11325        // Resume applications while running a voice interactor.
11326        if (mRunningVoice != null) {
11327            return false;
11328        }
11329
11330        // TODO: Transform the lock screen state into a sleep token instead.
11331        switch (mWakefulness) {
11332            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11333            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11334            case PowerManagerInternal.WAKEFULNESS_DOZING:
11335                // Pause applications whenever the lock screen is shown or any sleep
11336                // tokens have been acquired.
11337                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11338            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11339            default:
11340                // If we're asleep then pause applications unconditionally.
11341                return true;
11342        }
11343    }
11344
11345    /** Pokes the task persister. */
11346    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11347        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11348    }
11349
11350    /** Notifies all listeners when the task stack has changed. */
11351    void notifyTaskStackChangedLocked() {
11352        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11353        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11354        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11355        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11356    }
11357
11358    /** Notifies all listeners when an Activity is pinned. */
11359    void notifyActivityPinnedLocked() {
11360        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11361        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11362    }
11363
11364    /**
11365     * Notifies all listeners when an attempt was made to start an an activity that is already
11366     * running in the pinned stack and the activity was not actually started, but the task is
11367     * either brought to the front or a new Intent is delivered to it.
11368     */
11369    void notifyPinnedActivityRestartAttemptLocked() {
11370        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11371        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11372    }
11373
11374    /** Notifies all listeners when the pinned stack animation ends. */
11375    @Override
11376    public void notifyPinnedStackAnimationEnded() {
11377        synchronized (this) {
11378            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11379            mHandler.obtainMessage(
11380                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11381        }
11382    }
11383
11384    @Override
11385    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11386        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11387    }
11388
11389    @Override
11390    public boolean shutdown(int timeout) {
11391        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11392                != PackageManager.PERMISSION_GRANTED) {
11393            throw new SecurityException("Requires permission "
11394                    + android.Manifest.permission.SHUTDOWN);
11395        }
11396
11397        boolean timedout = false;
11398
11399        synchronized(this) {
11400            mShuttingDown = true;
11401            updateEventDispatchingLocked();
11402            timedout = mStackSupervisor.shutdownLocked(timeout);
11403        }
11404
11405        mAppOpsService.shutdown();
11406        if (mUsageStatsService != null) {
11407            mUsageStatsService.prepareShutdown();
11408        }
11409        mBatteryStatsService.shutdown();
11410        synchronized (this) {
11411            mProcessStats.shutdownLocked();
11412            notifyTaskPersisterLocked(null, true);
11413        }
11414
11415        return timedout;
11416    }
11417
11418    public final void activitySlept(IBinder token) {
11419        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11420
11421        final long origId = Binder.clearCallingIdentity();
11422
11423        synchronized (this) {
11424            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11425            if (r != null) {
11426                mStackSupervisor.activitySleptLocked(r);
11427            }
11428        }
11429
11430        Binder.restoreCallingIdentity(origId);
11431    }
11432
11433    private String lockScreenShownToString() {
11434        switch (mLockScreenShown) {
11435            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11436            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11437            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11438            default: return "Unknown=" + mLockScreenShown;
11439        }
11440    }
11441
11442    void logLockScreen(String msg) {
11443        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11444                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11445                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11446                + " mSleeping=" + mSleeping);
11447    }
11448
11449    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11450        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11451        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11452        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11453            boolean wasRunningVoice = mRunningVoice != null;
11454            mRunningVoice = session;
11455            if (!wasRunningVoice) {
11456                mVoiceWakeLock.acquire();
11457                updateSleepIfNeededLocked();
11458            }
11459        }
11460    }
11461
11462    private void updateEventDispatchingLocked() {
11463        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11464    }
11465
11466    public void setLockScreenShown(boolean shown) {
11467        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11468                != PackageManager.PERMISSION_GRANTED) {
11469            throw new SecurityException("Requires permission "
11470                    + android.Manifest.permission.DEVICE_POWER);
11471        }
11472
11473        synchronized(this) {
11474            long ident = Binder.clearCallingIdentity();
11475            try {
11476                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11477                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11478                updateSleepIfNeededLocked();
11479            } finally {
11480                Binder.restoreCallingIdentity(ident);
11481            }
11482        }
11483    }
11484
11485    @Override
11486    public void notifyLockedProfile(@UserIdInt int userId) {
11487        try {
11488            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11489                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11490            }
11491        } catch (RemoteException ex) {
11492            throw new SecurityException("Fail to check is caller a privileged app", ex);
11493        }
11494
11495        synchronized (this) {
11496            if (mStackSupervisor.isUserLockedProfile(userId)) {
11497                final long ident = Binder.clearCallingIdentity();
11498                try {
11499                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11500                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11501                        // If there is no device lock, we will show the profile's credential page.
11502                        mActivityStarter.showConfirmDeviceCredential(userId);
11503                    } else {
11504                        // Showing launcher to avoid user entering credential twice.
11505                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11506                    }
11507                } finally {
11508                    Binder.restoreCallingIdentity(ident);
11509                }
11510            }
11511        }
11512    }
11513
11514    @Override
11515    public void startConfirmDeviceCredentialIntent(Intent intent) {
11516        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11517        synchronized (this) {
11518            final long ident = Binder.clearCallingIdentity();
11519            try {
11520                mActivityStarter.startConfirmCredentialIntent(intent);
11521            } finally {
11522                Binder.restoreCallingIdentity(ident);
11523            }
11524        }
11525    }
11526
11527    @Override
11528    public void stopAppSwitches() {
11529        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11530                != PackageManager.PERMISSION_GRANTED) {
11531            throw new SecurityException("viewquires permission "
11532                    + android.Manifest.permission.STOP_APP_SWITCHES);
11533        }
11534
11535        synchronized(this) {
11536            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11537                    + APP_SWITCH_DELAY_TIME;
11538            mDidAppSwitch = false;
11539            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11540            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11541            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11542        }
11543    }
11544
11545    public void resumeAppSwitches() {
11546        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11547                != PackageManager.PERMISSION_GRANTED) {
11548            throw new SecurityException("Requires permission "
11549                    + android.Manifest.permission.STOP_APP_SWITCHES);
11550        }
11551
11552        synchronized(this) {
11553            // Note that we don't execute any pending app switches... we will
11554            // let those wait until either the timeout, or the next start
11555            // activity request.
11556            mAppSwitchesAllowedTime = 0;
11557        }
11558    }
11559
11560    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11561            int callingPid, int callingUid, String name) {
11562        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11563            return true;
11564        }
11565
11566        int perm = checkComponentPermission(
11567                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11568                sourceUid, -1, true);
11569        if (perm == PackageManager.PERMISSION_GRANTED) {
11570            return true;
11571        }
11572
11573        // If the actual IPC caller is different from the logical source, then
11574        // also see if they are allowed to control app switches.
11575        if (callingUid != -1 && callingUid != sourceUid) {
11576            perm = checkComponentPermission(
11577                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11578                    callingUid, -1, true);
11579            if (perm == PackageManager.PERMISSION_GRANTED) {
11580                return true;
11581            }
11582        }
11583
11584        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11585        return false;
11586    }
11587
11588    public void setDebugApp(String packageName, boolean waitForDebugger,
11589            boolean persistent) {
11590        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11591                "setDebugApp()");
11592
11593        long ident = Binder.clearCallingIdentity();
11594        try {
11595            // Note that this is not really thread safe if there are multiple
11596            // callers into it at the same time, but that's not a situation we
11597            // care about.
11598            if (persistent) {
11599                final ContentResolver resolver = mContext.getContentResolver();
11600                Settings.Global.putString(
11601                    resolver, Settings.Global.DEBUG_APP,
11602                    packageName);
11603                Settings.Global.putInt(
11604                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11605                    waitForDebugger ? 1 : 0);
11606            }
11607
11608            synchronized (this) {
11609                if (!persistent) {
11610                    mOrigDebugApp = mDebugApp;
11611                    mOrigWaitForDebugger = mWaitForDebugger;
11612                }
11613                mDebugApp = packageName;
11614                mWaitForDebugger = waitForDebugger;
11615                mDebugTransient = !persistent;
11616                if (packageName != null) {
11617                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11618                            false, UserHandle.USER_ALL, "set debug app");
11619                }
11620            }
11621        } finally {
11622            Binder.restoreCallingIdentity(ident);
11623        }
11624    }
11625
11626    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11627        synchronized (this) {
11628            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11629            if (!isDebuggable) {
11630                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11631                    throw new SecurityException("Process not debuggable: " + app.packageName);
11632                }
11633            }
11634
11635            mTrackAllocationApp = processName;
11636        }
11637    }
11638
11639    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11640        synchronized (this) {
11641            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11642            if (!isDebuggable) {
11643                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11644                    throw new SecurityException("Process not debuggable: " + app.packageName);
11645                }
11646            }
11647            mProfileApp = processName;
11648            mProfileFile = profilerInfo.profileFile;
11649            if (mProfileFd != null) {
11650                try {
11651                    mProfileFd.close();
11652                } catch (IOException e) {
11653                }
11654                mProfileFd = null;
11655            }
11656            mProfileFd = profilerInfo.profileFd;
11657            mSamplingInterval = profilerInfo.samplingInterval;
11658            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11659            mProfileType = 0;
11660        }
11661    }
11662
11663    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11664        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11665        if (!isDebuggable) {
11666            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11667                throw new SecurityException("Process not debuggable: " + app.packageName);
11668            }
11669        }
11670        mNativeDebuggingApp = processName;
11671    }
11672
11673    @Override
11674    public void setAlwaysFinish(boolean enabled) {
11675        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11676                "setAlwaysFinish()");
11677
11678        long ident = Binder.clearCallingIdentity();
11679        try {
11680            Settings.Global.putInt(
11681                    mContext.getContentResolver(),
11682                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11683
11684            synchronized (this) {
11685                mAlwaysFinishActivities = enabled;
11686            }
11687        } finally {
11688            Binder.restoreCallingIdentity(ident);
11689        }
11690    }
11691
11692    @Override
11693    public void setLenientBackgroundCheck(boolean enabled) {
11694        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11695                "setLenientBackgroundCheck()");
11696
11697        long ident = Binder.clearCallingIdentity();
11698        try {
11699            Settings.Global.putInt(
11700                    mContext.getContentResolver(),
11701                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11702
11703            synchronized (this) {
11704                mLenientBackgroundCheck = enabled;
11705            }
11706        } finally {
11707            Binder.restoreCallingIdentity(ident);
11708        }
11709    }
11710
11711    @Override
11712    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11713        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11714                "setActivityController()");
11715        synchronized (this) {
11716            mController = controller;
11717            mControllerIsAMonkey = imAMonkey;
11718            Watchdog.getInstance().setActivityController(controller);
11719        }
11720    }
11721
11722    @Override
11723    public void setUserIsMonkey(boolean userIsMonkey) {
11724        synchronized (this) {
11725            synchronized (mPidsSelfLocked) {
11726                final int callingPid = Binder.getCallingPid();
11727                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11728                if (precessRecord == null) {
11729                    throw new SecurityException("Unknown process: " + callingPid);
11730                }
11731                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11732                    throw new SecurityException("Only an instrumentation process "
11733                            + "with a UiAutomation can call setUserIsMonkey");
11734                }
11735            }
11736            mUserIsMonkey = userIsMonkey;
11737        }
11738    }
11739
11740    @Override
11741    public boolean isUserAMonkey() {
11742        synchronized (this) {
11743            // If there is a controller also implies the user is a monkey.
11744            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11745        }
11746    }
11747
11748    public void requestBugReport(int bugreportType) {
11749        String service = null;
11750        switch (bugreportType) {
11751            case ActivityManager.BUGREPORT_OPTION_FULL:
11752                service = "bugreport";
11753                break;
11754            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11755                service = "bugreportplus";
11756                break;
11757            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11758                service = "bugreportremote";
11759                break;
11760        }
11761        if (service == null) {
11762            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11763                    + bugreportType);
11764        }
11765        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11766        SystemProperties.set("ctl.start", service);
11767    }
11768
11769    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11770        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11771    }
11772
11773    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11774        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11775            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11776        }
11777        return KEY_DISPATCHING_TIMEOUT;
11778    }
11779
11780    @Override
11781    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11782        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11783                != PackageManager.PERMISSION_GRANTED) {
11784            throw new SecurityException("Requires permission "
11785                    + android.Manifest.permission.FILTER_EVENTS);
11786        }
11787        ProcessRecord proc;
11788        long timeout;
11789        synchronized (this) {
11790            synchronized (mPidsSelfLocked) {
11791                proc = mPidsSelfLocked.get(pid);
11792            }
11793            timeout = getInputDispatchingTimeoutLocked(proc);
11794        }
11795
11796        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11797            return -1;
11798        }
11799
11800        return timeout;
11801    }
11802
11803    /**
11804     * Handle input dispatching timeouts.
11805     * Returns whether input dispatching should be aborted or not.
11806     */
11807    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11808            final ActivityRecord activity, final ActivityRecord parent,
11809            final boolean aboveSystem, String reason) {
11810        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11811                != PackageManager.PERMISSION_GRANTED) {
11812            throw new SecurityException("Requires permission "
11813                    + android.Manifest.permission.FILTER_EVENTS);
11814        }
11815
11816        final String annotation;
11817        if (reason == null) {
11818            annotation = "Input dispatching timed out";
11819        } else {
11820            annotation = "Input dispatching timed out (" + reason + ")";
11821        }
11822
11823        if (proc != null) {
11824            synchronized (this) {
11825                if (proc.debugging) {
11826                    return false;
11827                }
11828
11829                if (mDidDexOpt) {
11830                    // Give more time since we were dexopting.
11831                    mDidDexOpt = false;
11832                    return false;
11833                }
11834
11835                if (proc.instrumentationClass != null) {
11836                    Bundle info = new Bundle();
11837                    info.putString("shortMsg", "keyDispatchingTimedOut");
11838                    info.putString("longMsg", annotation);
11839                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11840                    return true;
11841                }
11842            }
11843            mHandler.post(new Runnable() {
11844                @Override
11845                public void run() {
11846                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11847                }
11848            });
11849        }
11850
11851        return true;
11852    }
11853
11854    @Override
11855    public Bundle getAssistContextExtras(int requestType) {
11856        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11857                null, null, true, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11858        if (pae == null) {
11859            return null;
11860        }
11861        synchronized (pae) {
11862            while (!pae.haveResult) {
11863                try {
11864                    pae.wait();
11865                } catch (InterruptedException e) {
11866                }
11867            }
11868        }
11869        synchronized (this) {
11870            buildAssistBundleLocked(pae, pae.result);
11871            mPendingAssistExtras.remove(pae);
11872            mUiHandler.removeCallbacks(pae);
11873        }
11874        return pae.extras;
11875    }
11876
11877    @Override
11878    public boolean isAssistDataAllowedOnCurrentActivity() {
11879        int userId;
11880        synchronized (this) {
11881            userId = mUserController.getCurrentUserIdLocked();
11882            ActivityRecord activity = getFocusedStack().topActivity();
11883            if (activity == null) {
11884                return false;
11885            }
11886            userId = activity.userId;
11887        }
11888        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11889                Context.DEVICE_POLICY_SERVICE);
11890        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11891    }
11892
11893    @Override
11894    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11895        long ident = Binder.clearCallingIdentity();
11896        try {
11897            synchronized (this) {
11898                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11899                ActivityRecord top = getFocusedStack().topActivity();
11900                if (top != caller) {
11901                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11902                            + " is not current top " + top);
11903                    return false;
11904                }
11905                if (!top.nowVisible) {
11906                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11907                            + " is not visible");
11908                    return false;
11909                }
11910            }
11911            AssistUtils utils = new AssistUtils(mContext);
11912            return utils.showSessionForActiveService(args,
11913                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11914        } finally {
11915            Binder.restoreCallingIdentity(ident);
11916        }
11917    }
11918
11919    @Override
11920    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11921            Bundle receiverExtras,
11922            IBinder activityToken, boolean focused) {
11923        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11924                activityToken, focused,
11925                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11926                != null;
11927    }
11928
11929    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11930            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused,
11931            int userHandle, Bundle args, long timeout) {
11932        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11933                "enqueueAssistContext()");
11934        synchronized (this) {
11935            ActivityRecord activity = getFocusedStack().topActivity();
11936            if (activity == null) {
11937                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11938                return null;
11939            }
11940            if (activity.app == null || activity.app.thread == null) {
11941                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11942                return null;
11943            }
11944            if (focused) {
11945                if (activityToken != null) {
11946                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11947                    if (activity != caller) {
11948                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11949                                + " is not current top " + activity);
11950                        return null;
11951                    }
11952                }
11953            } else {
11954                activity = ActivityRecord.forTokenLocked(activityToken);
11955                if (activity == null) {
11956                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
11957                            + " couldn't be found");
11958                    return null;
11959                }
11960            }
11961
11962            PendingAssistExtras pae;
11963            Bundle extras = new Bundle();
11964            if (args != null) {
11965                extras.putAll(args);
11966            }
11967            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11968            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11969            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
11970                    userHandle);
11971            try {
11972                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11973                        requestType);
11974                mPendingAssistExtras.add(pae);
11975                mUiHandler.postDelayed(pae, timeout);
11976            } catch (RemoteException e) {
11977                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11978                return null;
11979            }
11980            return pae;
11981        }
11982    }
11983
11984    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11985        IResultReceiver receiver;
11986        synchronized (this) {
11987            mPendingAssistExtras.remove(pae);
11988            receiver = pae.receiver;
11989        }
11990        if (receiver != null) {
11991            // Caller wants result sent back to them.
11992            Bundle sendBundle = new Bundle();
11993            // At least return the receiver extras
11994            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
11995                    pae.receiverExtras);
11996            try {
11997                pae.receiver.send(0, sendBundle);
11998            } catch (RemoteException e) {
11999            }
12000        }
12001    }
12002
12003    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12004        if (result != null) {
12005            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12006        }
12007        if (pae.hint != null) {
12008            pae.extras.putBoolean(pae.hint, true);
12009        }
12010    }
12011
12012    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12013            AssistContent content, Uri referrer) {
12014        PendingAssistExtras pae = (PendingAssistExtras)token;
12015        synchronized (pae) {
12016            pae.result = extras;
12017            pae.structure = structure;
12018            pae.content = content;
12019            if (referrer != null) {
12020                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12021            }
12022            pae.haveResult = true;
12023            pae.notifyAll();
12024            if (pae.intent == null && pae.receiver == null) {
12025                // Caller is just waiting for the result.
12026                return;
12027            }
12028        }
12029
12030        // We are now ready to launch the assist activity.
12031        IResultReceiver sendReceiver = null;
12032        Bundle sendBundle = null;
12033        synchronized (this) {
12034            buildAssistBundleLocked(pae, extras);
12035            boolean exists = mPendingAssistExtras.remove(pae);
12036            mUiHandler.removeCallbacks(pae);
12037            if (!exists) {
12038                // Timed out.
12039                return;
12040            }
12041            if ((sendReceiver=pae.receiver) != null) {
12042                // Caller wants result sent back to them.
12043                sendBundle = new Bundle();
12044                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12045                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12046                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12047                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12048                        pae.receiverExtras);
12049            }
12050        }
12051        if (sendReceiver != null) {
12052            try {
12053                sendReceiver.send(0, sendBundle);
12054            } catch (RemoteException e) {
12055            }
12056            return;
12057        }
12058
12059        long ident = Binder.clearCallingIdentity();
12060        try {
12061            pae.intent.replaceExtras(pae.extras);
12062            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12063                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12064                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12065            closeSystemDialogs("assist");
12066            try {
12067                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12068            } catch (ActivityNotFoundException e) {
12069                Slog.w(TAG, "No activity to handle assist action.", e);
12070            }
12071        } finally {
12072            Binder.restoreCallingIdentity(ident);
12073        }
12074    }
12075
12076    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12077            Bundle args) {
12078        return enqueueAssistContext(requestType, intent, hint, null, null, null, true,
12079                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12080    }
12081
12082    public void registerProcessObserver(IProcessObserver observer) {
12083        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12084                "registerProcessObserver()");
12085        synchronized (this) {
12086            mProcessObservers.register(observer);
12087        }
12088    }
12089
12090    @Override
12091    public void unregisterProcessObserver(IProcessObserver observer) {
12092        synchronized (this) {
12093            mProcessObservers.unregister(observer);
12094        }
12095    }
12096
12097    @Override
12098    public void registerUidObserver(IUidObserver observer, int which) {
12099        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12100                "registerUidObserver()");
12101        synchronized (this) {
12102            mUidObservers.register(observer, which);
12103        }
12104    }
12105
12106    @Override
12107    public void unregisterUidObserver(IUidObserver observer) {
12108        synchronized (this) {
12109            mUidObservers.unregister(observer);
12110        }
12111    }
12112
12113    @Override
12114    public boolean convertFromTranslucent(IBinder token) {
12115        final long origId = Binder.clearCallingIdentity();
12116        try {
12117            synchronized (this) {
12118                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12119                if (r == null) {
12120                    return false;
12121                }
12122                final boolean translucentChanged = r.changeWindowTranslucency(true);
12123                if (translucentChanged) {
12124                    r.task.stack.releaseBackgroundResources(r);
12125                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12126                }
12127                mWindowManager.setAppFullscreen(token, true);
12128                return translucentChanged;
12129            }
12130        } finally {
12131            Binder.restoreCallingIdentity(origId);
12132        }
12133    }
12134
12135    @Override
12136    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12137        final long origId = Binder.clearCallingIdentity();
12138        try {
12139            synchronized (this) {
12140                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12141                if (r == null) {
12142                    return false;
12143                }
12144                int index = r.task.mActivities.lastIndexOf(r);
12145                if (index > 0) {
12146                    ActivityRecord under = r.task.mActivities.get(index - 1);
12147                    under.returningOptions = options;
12148                }
12149                final boolean translucentChanged = r.changeWindowTranslucency(false);
12150                if (translucentChanged) {
12151                    r.task.stack.convertActivityToTranslucent(r);
12152                }
12153                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12154                mWindowManager.setAppFullscreen(token, false);
12155                return translucentChanged;
12156            }
12157        } finally {
12158            Binder.restoreCallingIdentity(origId);
12159        }
12160    }
12161
12162    @Override
12163    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12164        final long origId = Binder.clearCallingIdentity();
12165        try {
12166            synchronized (this) {
12167                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12168                if (r != null) {
12169                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12170                }
12171            }
12172            return false;
12173        } finally {
12174            Binder.restoreCallingIdentity(origId);
12175        }
12176    }
12177
12178    @Override
12179    public boolean isBackgroundVisibleBehind(IBinder token) {
12180        final long origId = Binder.clearCallingIdentity();
12181        try {
12182            synchronized (this) {
12183                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12184                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12185                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12186                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12187                return visible;
12188            }
12189        } finally {
12190            Binder.restoreCallingIdentity(origId);
12191        }
12192    }
12193
12194    @Override
12195    public ActivityOptions getActivityOptions(IBinder token) {
12196        final long origId = Binder.clearCallingIdentity();
12197        try {
12198            synchronized (this) {
12199                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12200                if (r != null) {
12201                    final ActivityOptions activityOptions = r.pendingOptions;
12202                    r.pendingOptions = null;
12203                    return activityOptions;
12204                }
12205                return null;
12206            }
12207        } finally {
12208            Binder.restoreCallingIdentity(origId);
12209        }
12210    }
12211
12212    @Override
12213    public void setImmersive(IBinder token, boolean immersive) {
12214        synchronized(this) {
12215            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12216            if (r == null) {
12217                throw new IllegalArgumentException();
12218            }
12219            r.immersive = immersive;
12220
12221            // update associated state if we're frontmost
12222            if (r == mFocusedActivity) {
12223                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12224                applyUpdateLockStateLocked(r);
12225            }
12226        }
12227    }
12228
12229    @Override
12230    public boolean isImmersive(IBinder token) {
12231        synchronized (this) {
12232            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12233            if (r == null) {
12234                throw new IllegalArgumentException();
12235            }
12236            return r.immersive;
12237        }
12238    }
12239
12240    @Override
12241    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12242        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12243            throw new UnsupportedOperationException("VR mode not supported on this device!");
12244        }
12245
12246        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12247
12248        ActivityRecord r;
12249        synchronized (this) {
12250            r = ActivityRecord.isInStackLocked(token);
12251        }
12252
12253        if (r == null) {
12254            throw new IllegalArgumentException();
12255        }
12256
12257        int err;
12258        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12259                VrManagerInternal.NO_ERROR) {
12260            return err;
12261        }
12262
12263        synchronized(this) {
12264            r.requestedVrComponent = (enabled) ? packageName : null;
12265
12266            // Update associated state if this activity is currently focused
12267            if (r == mFocusedActivity) {
12268                applyUpdateVrModeLocked(r);
12269            }
12270            return 0;
12271        }
12272    }
12273
12274    @Override
12275    public boolean isVrModePackageEnabled(ComponentName packageName) {
12276        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12277            throw new UnsupportedOperationException("VR mode not supported on this device!");
12278        }
12279
12280        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12281
12282        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12283                VrManagerInternal.NO_ERROR;
12284    }
12285
12286    public boolean isTopActivityImmersive() {
12287        enforceNotIsolatedCaller("startActivity");
12288        synchronized (this) {
12289            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12290            return (r != null) ? r.immersive : false;
12291        }
12292    }
12293
12294    @Override
12295    public boolean isTopOfTask(IBinder token) {
12296        synchronized (this) {
12297            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12298            if (r == null) {
12299                throw new IllegalArgumentException();
12300            }
12301            return r.task.getTopActivity() == r;
12302        }
12303    }
12304
12305    public final void enterSafeMode() {
12306        synchronized(this) {
12307            // It only makes sense to do this before the system is ready
12308            // and started launching other packages.
12309            if (!mSystemReady) {
12310                try {
12311                    AppGlobals.getPackageManager().enterSafeMode();
12312                } catch (RemoteException e) {
12313                }
12314            }
12315
12316            mSafeMode = true;
12317        }
12318    }
12319
12320    public final void showSafeModeOverlay() {
12321        View v = LayoutInflater.from(mContext).inflate(
12322                com.android.internal.R.layout.safe_mode, null);
12323        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12324        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12325        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12326        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12327        lp.gravity = Gravity.BOTTOM | Gravity.START;
12328        lp.format = v.getBackground().getOpacity();
12329        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12330                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12331        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12332        ((WindowManager)mContext.getSystemService(
12333                Context.WINDOW_SERVICE)).addView(v, lp);
12334    }
12335
12336    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12337        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12338            return;
12339        }
12340        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12341        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12342        synchronized (stats) {
12343            if (mBatteryStatsService.isOnBattery()) {
12344                mBatteryStatsService.enforceCallingPermission();
12345                int MY_UID = Binder.getCallingUid();
12346                final int uid;
12347                if (sender == null) {
12348                    uid = sourceUid;
12349                } else {
12350                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12351                }
12352                BatteryStatsImpl.Uid.Pkg pkg =
12353                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12354                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12355                pkg.noteWakeupAlarmLocked(tag);
12356            }
12357        }
12358    }
12359
12360    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12361        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12362            return;
12363        }
12364        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12365        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12366        synchronized (stats) {
12367            mBatteryStatsService.enforceCallingPermission();
12368            int MY_UID = Binder.getCallingUid();
12369            final int uid;
12370            if (sender == null) {
12371                uid = sourceUid;
12372            } else {
12373                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12374            }
12375            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12376        }
12377    }
12378
12379    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12380        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12381            return;
12382        }
12383        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12384        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12385        synchronized (stats) {
12386            mBatteryStatsService.enforceCallingPermission();
12387            int MY_UID = Binder.getCallingUid();
12388            final int uid;
12389            if (sender == null) {
12390                uid = sourceUid;
12391            } else {
12392                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12393            }
12394            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12395        }
12396    }
12397
12398    public boolean killPids(int[] pids, String pReason, boolean secure) {
12399        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12400            throw new SecurityException("killPids only available to the system");
12401        }
12402        String reason = (pReason == null) ? "Unknown" : pReason;
12403        // XXX Note: don't acquire main activity lock here, because the window
12404        // manager calls in with its locks held.
12405
12406        boolean killed = false;
12407        synchronized (mPidsSelfLocked) {
12408            int worstType = 0;
12409            for (int i=0; i<pids.length; i++) {
12410                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12411                if (proc != null) {
12412                    int type = proc.setAdj;
12413                    if (type > worstType) {
12414                        worstType = type;
12415                    }
12416                }
12417            }
12418
12419            // If the worst oom_adj is somewhere in the cached proc LRU range,
12420            // then constrain it so we will kill all cached procs.
12421            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12422                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12423                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12424            }
12425
12426            // If this is not a secure call, don't let it kill processes that
12427            // are important.
12428            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12429                worstType = ProcessList.SERVICE_ADJ;
12430            }
12431
12432            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12433            for (int i=0; i<pids.length; i++) {
12434                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12435                if (proc == null) {
12436                    continue;
12437                }
12438                int adj = proc.setAdj;
12439                if (adj >= worstType && !proc.killedByAm) {
12440                    proc.kill(reason, true);
12441                    killed = true;
12442                }
12443            }
12444        }
12445        return killed;
12446    }
12447
12448    @Override
12449    public void killUid(int appId, int userId, String reason) {
12450        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12451        synchronized (this) {
12452            final long identity = Binder.clearCallingIdentity();
12453            try {
12454                killPackageProcessesLocked(null, appId, userId,
12455                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12456                        reason != null ? reason : "kill uid");
12457            } finally {
12458                Binder.restoreCallingIdentity(identity);
12459            }
12460        }
12461    }
12462
12463    @Override
12464    public boolean killProcessesBelowForeground(String reason) {
12465        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12466            throw new SecurityException("killProcessesBelowForeground() only available to system");
12467        }
12468
12469        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12470    }
12471
12472    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12473        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12474            throw new SecurityException("killProcessesBelowAdj() only available to system");
12475        }
12476
12477        boolean killed = false;
12478        synchronized (mPidsSelfLocked) {
12479            final int size = mPidsSelfLocked.size();
12480            for (int i = 0; i < size; i++) {
12481                final int pid = mPidsSelfLocked.keyAt(i);
12482                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12483                if (proc == null) continue;
12484
12485                final int adj = proc.setAdj;
12486                if (adj > belowAdj && !proc.killedByAm) {
12487                    proc.kill(reason, true);
12488                    killed = true;
12489                }
12490            }
12491        }
12492        return killed;
12493    }
12494
12495    @Override
12496    public void hang(final IBinder who, boolean allowRestart) {
12497        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12498                != PackageManager.PERMISSION_GRANTED) {
12499            throw new SecurityException("Requires permission "
12500                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12501        }
12502
12503        final IBinder.DeathRecipient death = new DeathRecipient() {
12504            @Override
12505            public void binderDied() {
12506                synchronized (this) {
12507                    notifyAll();
12508                }
12509            }
12510        };
12511
12512        try {
12513            who.linkToDeath(death, 0);
12514        } catch (RemoteException e) {
12515            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12516            return;
12517        }
12518
12519        synchronized (this) {
12520            Watchdog.getInstance().setAllowRestart(allowRestart);
12521            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12522            synchronized (death) {
12523                while (who.isBinderAlive()) {
12524                    try {
12525                        death.wait();
12526                    } catch (InterruptedException e) {
12527                    }
12528                }
12529            }
12530            Watchdog.getInstance().setAllowRestart(true);
12531        }
12532    }
12533
12534    @Override
12535    public void restart() {
12536        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12537                != PackageManager.PERMISSION_GRANTED) {
12538            throw new SecurityException("Requires permission "
12539                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12540        }
12541
12542        Log.i(TAG, "Sending shutdown broadcast...");
12543
12544        BroadcastReceiver br = new BroadcastReceiver() {
12545            @Override public void onReceive(Context context, Intent intent) {
12546                // Now the broadcast is done, finish up the low-level shutdown.
12547                Log.i(TAG, "Shutting down activity manager...");
12548                shutdown(10000);
12549                Log.i(TAG, "Shutdown complete, restarting!");
12550                Process.killProcess(Process.myPid());
12551                System.exit(10);
12552            }
12553        };
12554
12555        // First send the high-level shut down broadcast.
12556        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12557        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12558        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12559        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12560        mContext.sendOrderedBroadcastAsUser(intent,
12561                UserHandle.ALL, null, br, mHandler, 0, null, null);
12562        */
12563        br.onReceive(mContext, intent);
12564    }
12565
12566    private long getLowRamTimeSinceIdle(long now) {
12567        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12568    }
12569
12570    @Override
12571    public void performIdleMaintenance() {
12572        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12573                != PackageManager.PERMISSION_GRANTED) {
12574            throw new SecurityException("Requires permission "
12575                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12576        }
12577
12578        synchronized (this) {
12579            final long now = SystemClock.uptimeMillis();
12580            final long timeSinceLastIdle = now - mLastIdleTime;
12581            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12582            mLastIdleTime = now;
12583            mLowRamTimeSinceLastIdle = 0;
12584            if (mLowRamStartTime != 0) {
12585                mLowRamStartTime = now;
12586            }
12587
12588            StringBuilder sb = new StringBuilder(128);
12589            sb.append("Idle maintenance over ");
12590            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12591            sb.append(" low RAM for ");
12592            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12593            Slog.i(TAG, sb.toString());
12594
12595            // If at least 1/3 of our time since the last idle period has been spent
12596            // with RAM low, then we want to kill processes.
12597            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12598
12599            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12600                ProcessRecord proc = mLruProcesses.get(i);
12601                if (proc.notCachedSinceIdle) {
12602                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12603                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12604                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12605                        if (doKilling && proc.initialIdlePss != 0
12606                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12607                            sb = new StringBuilder(128);
12608                            sb.append("Kill");
12609                            sb.append(proc.processName);
12610                            sb.append(" in idle maint: pss=");
12611                            sb.append(proc.lastPss);
12612                            sb.append(", swapPss=");
12613                            sb.append(proc.lastSwapPss);
12614                            sb.append(", initialPss=");
12615                            sb.append(proc.initialIdlePss);
12616                            sb.append(", period=");
12617                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12618                            sb.append(", lowRamPeriod=");
12619                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12620                            Slog.wtfQuiet(TAG, sb.toString());
12621                            proc.kill("idle maint (pss " + proc.lastPss
12622                                    + " from " + proc.initialIdlePss + ")", true);
12623                        }
12624                    }
12625                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12626                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12627                    proc.notCachedSinceIdle = true;
12628                    proc.initialIdlePss = 0;
12629                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12630                            mTestPssMode, isSleeping(), now);
12631                }
12632            }
12633
12634            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12635            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12636        }
12637    }
12638
12639    private void retrieveSettings() {
12640        final ContentResolver resolver = mContext.getContentResolver();
12641        final boolean freeformWindowManagement =
12642                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12643                        || Settings.Global.getInt(
12644                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12645        final boolean supportsPictureInPicture =
12646                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12647
12648        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12649        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12650        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12651        final boolean alwaysFinishActivities =
12652                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12653        final boolean lenientBackgroundCheck =
12654                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12655        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12656        final boolean forceResizable = Settings.Global.getInt(
12657                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12658        // Transfer any global setting for forcing RTL layout, into a System Property
12659        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12660
12661        final Configuration configuration = new Configuration();
12662        Settings.System.getConfiguration(resolver, configuration);
12663        if (forceRtl) {
12664            // This will take care of setting the correct layout direction flags
12665            configuration.setLayoutDirection(configuration.locale);
12666        }
12667
12668        synchronized (this) {
12669            mDebugApp = mOrigDebugApp = debugApp;
12670            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12671            mAlwaysFinishActivities = alwaysFinishActivities;
12672            mLenientBackgroundCheck = lenientBackgroundCheck;
12673            mForceResizableActivities = forceResizable;
12674            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12675            if (supportsMultiWindow || forceResizable) {
12676                mSupportsMultiWindow = true;
12677                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12678                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12679            } else {
12680                mSupportsMultiWindow = false;
12681                mSupportsFreeformWindowManagement = false;
12682                mSupportsPictureInPicture = false;
12683            }
12684            // This happens before any activities are started, so we can
12685            // change mConfiguration in-place.
12686            updateConfigurationLocked(configuration, null, true);
12687            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12688                    "Initial config: " + mConfiguration);
12689
12690            // Load resources only after the current configuration has been set.
12691            final Resources res = mContext.getResources();
12692            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12693            mThumbnailWidth = res.getDimensionPixelSize(
12694                    com.android.internal.R.dimen.thumbnail_width);
12695            mThumbnailHeight = res.getDimensionPixelSize(
12696                    com.android.internal.R.dimen.thumbnail_height);
12697            mFullscreenThumbnailScale = res.getFraction(
12698                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12699            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12700                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12701            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12702                    com.android.internal.R.string.config_appsNotReportingCrashes));
12703        }
12704    }
12705
12706    public boolean testIsSystemReady() {
12707        // no need to synchronize(this) just to read & return the value
12708        return mSystemReady;
12709    }
12710
12711    public void systemReady(final Runnable goingCallback) {
12712        synchronized(this) {
12713            if (mSystemReady) {
12714                // If we're done calling all the receivers, run the next "boot phase" passed in
12715                // by the SystemServer
12716                if (goingCallback != null) {
12717                    goingCallback.run();
12718                }
12719                return;
12720            }
12721
12722            mLocalDeviceIdleController
12723                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12724
12725            // Make sure we have the current profile info, since it is needed for security checks.
12726            mUserController.onSystemReady();
12727            mRecentTasks.onSystemReadyLocked();
12728            mAppOpsService.systemReady();
12729            mSystemReady = true;
12730        }
12731
12732        ArrayList<ProcessRecord> procsToKill = null;
12733        synchronized(mPidsSelfLocked) {
12734            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12735                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12736                if (!isAllowedWhileBooting(proc.info)){
12737                    if (procsToKill == null) {
12738                        procsToKill = new ArrayList<ProcessRecord>();
12739                    }
12740                    procsToKill.add(proc);
12741                }
12742            }
12743        }
12744
12745        synchronized(this) {
12746            if (procsToKill != null) {
12747                for (int i=procsToKill.size()-1; i>=0; i--) {
12748                    ProcessRecord proc = procsToKill.get(i);
12749                    Slog.i(TAG, "Removing system update proc: " + proc);
12750                    removeProcessLocked(proc, true, false, "system update done");
12751                }
12752            }
12753
12754            // Now that we have cleaned up any update processes, we
12755            // are ready to start launching real processes and know that
12756            // we won't trample on them any more.
12757            mProcessesReady = true;
12758        }
12759
12760        Slog.i(TAG, "System now ready");
12761        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12762            SystemClock.uptimeMillis());
12763
12764        synchronized(this) {
12765            // Make sure we have no pre-ready processes sitting around.
12766
12767            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12768                ResolveInfo ri = mContext.getPackageManager()
12769                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12770                                STOCK_PM_FLAGS);
12771                CharSequence errorMsg = null;
12772                if (ri != null) {
12773                    ActivityInfo ai = ri.activityInfo;
12774                    ApplicationInfo app = ai.applicationInfo;
12775                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12776                        mTopAction = Intent.ACTION_FACTORY_TEST;
12777                        mTopData = null;
12778                        mTopComponent = new ComponentName(app.packageName,
12779                                ai.name);
12780                    } else {
12781                        errorMsg = mContext.getResources().getText(
12782                                com.android.internal.R.string.factorytest_not_system);
12783                    }
12784                } else {
12785                    errorMsg = mContext.getResources().getText(
12786                            com.android.internal.R.string.factorytest_no_action);
12787                }
12788                if (errorMsg != null) {
12789                    mTopAction = null;
12790                    mTopData = null;
12791                    mTopComponent = null;
12792                    Message msg = Message.obtain();
12793                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12794                    msg.getData().putCharSequence("msg", errorMsg);
12795                    mUiHandler.sendMessage(msg);
12796                }
12797            }
12798        }
12799
12800        retrieveSettings();
12801        final int currentUserId;
12802        synchronized (this) {
12803            currentUserId = mUserController.getCurrentUserIdLocked();
12804            readGrantedUriPermissionsLocked();
12805        }
12806
12807        if (goingCallback != null) goingCallback.run();
12808
12809        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12810                Integer.toString(currentUserId), currentUserId);
12811        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12812                Integer.toString(currentUserId), currentUserId);
12813        mSystemServiceManager.startUser(currentUserId);
12814
12815        synchronized (this) {
12816            // Only start up encryption-aware persistent apps; once user is
12817            // unlocked we'll come back around and start unaware apps
12818            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12819
12820            // Start up initial activity.
12821            mBooting = true;
12822            // Enable home activity for system user, so that the system can always boot
12823            if (UserManager.isSplitSystemUser()) {
12824                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12825                try {
12826                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12827                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12828                            UserHandle.USER_SYSTEM);
12829                } catch (RemoteException e) {
12830                    throw e.rethrowAsRuntimeException();
12831                }
12832            }
12833            startHomeActivityLocked(currentUserId, "systemReady");
12834
12835            try {
12836                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12837                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12838                            + " data partition or your device will be unstable.");
12839                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12840                }
12841            } catch (RemoteException e) {
12842            }
12843
12844            if (!Build.isBuildConsistent()) {
12845                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12846                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12847            }
12848
12849            long ident = Binder.clearCallingIdentity();
12850            try {
12851                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12852                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12853                        | Intent.FLAG_RECEIVER_FOREGROUND);
12854                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12855                broadcastIntentLocked(null, null, intent,
12856                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12857                        null, false, false, MY_PID, Process.SYSTEM_UID,
12858                        currentUserId);
12859                intent = new Intent(Intent.ACTION_USER_STARTING);
12860                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12861                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12862                broadcastIntentLocked(null, null, intent,
12863                        null, new IIntentReceiver.Stub() {
12864                            @Override
12865                            public void performReceive(Intent intent, int resultCode, String data,
12866                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12867                                    throws RemoteException {
12868                            }
12869                        }, 0, null, null,
12870                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12871                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12872            } catch (Throwable t) {
12873                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12874            } finally {
12875                Binder.restoreCallingIdentity(ident);
12876            }
12877            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12878            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12879        }
12880    }
12881
12882    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12883        synchronized (this) {
12884            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12885        }
12886    }
12887
12888    void skipCurrentReceiverLocked(ProcessRecord app) {
12889        for (BroadcastQueue queue : mBroadcastQueues) {
12890            queue.skipCurrentReceiverLocked(app);
12891        }
12892    }
12893
12894    /**
12895     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12896     * The application process will exit immediately after this call returns.
12897     * @param app object of the crashing app, null for the system server
12898     * @param crashInfo describing the exception
12899     */
12900    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12901        ProcessRecord r = findAppProcess(app, "Crash");
12902        final String processName = app == null ? "system_server"
12903                : (r == null ? "unknown" : r.processName);
12904
12905        handleApplicationCrashInner("crash", r, processName, crashInfo);
12906    }
12907
12908    /* Native crash reporting uses this inner version because it needs to be somewhat
12909     * decoupled from the AM-managed cleanup lifecycle
12910     */
12911    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12912            ApplicationErrorReport.CrashInfo crashInfo) {
12913        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12914                UserHandle.getUserId(Binder.getCallingUid()), processName,
12915                r == null ? -1 : r.info.flags,
12916                crashInfo.exceptionClassName,
12917                crashInfo.exceptionMessage,
12918                crashInfo.throwFileName,
12919                crashInfo.throwLineNumber);
12920
12921        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12922
12923        mAppErrors.crashApplication(r, crashInfo);
12924    }
12925
12926    public void handleApplicationStrictModeViolation(
12927            IBinder app,
12928            int violationMask,
12929            StrictMode.ViolationInfo info) {
12930        ProcessRecord r = findAppProcess(app, "StrictMode");
12931        if (r == null) {
12932            return;
12933        }
12934
12935        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12936            Integer stackFingerprint = info.hashCode();
12937            boolean logIt = true;
12938            synchronized (mAlreadyLoggedViolatedStacks) {
12939                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12940                    logIt = false;
12941                    // TODO: sub-sample into EventLog for these, with
12942                    // the info.durationMillis?  Then we'd get
12943                    // the relative pain numbers, without logging all
12944                    // the stack traces repeatedly.  We'd want to do
12945                    // likewise in the client code, which also does
12946                    // dup suppression, before the Binder call.
12947                } else {
12948                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12949                        mAlreadyLoggedViolatedStacks.clear();
12950                    }
12951                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12952                }
12953            }
12954            if (logIt) {
12955                logStrictModeViolationToDropBox(r, info);
12956            }
12957        }
12958
12959        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12960            AppErrorResult result = new AppErrorResult();
12961            synchronized (this) {
12962                final long origId = Binder.clearCallingIdentity();
12963
12964                Message msg = Message.obtain();
12965                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12966                HashMap<String, Object> data = new HashMap<String, Object>();
12967                data.put("result", result);
12968                data.put("app", r);
12969                data.put("violationMask", violationMask);
12970                data.put("info", info);
12971                msg.obj = data;
12972                mUiHandler.sendMessage(msg);
12973
12974                Binder.restoreCallingIdentity(origId);
12975            }
12976            int res = result.get();
12977            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12978        }
12979    }
12980
12981    // Depending on the policy in effect, there could be a bunch of
12982    // these in quick succession so we try to batch these together to
12983    // minimize disk writes, number of dropbox entries, and maximize
12984    // compression, by having more fewer, larger records.
12985    private void logStrictModeViolationToDropBox(
12986            ProcessRecord process,
12987            StrictMode.ViolationInfo info) {
12988        if (info == null) {
12989            return;
12990        }
12991        final boolean isSystemApp = process == null ||
12992                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12993                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12994        final String processName = process == null ? "unknown" : process.processName;
12995        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12996        final DropBoxManager dbox = (DropBoxManager)
12997                mContext.getSystemService(Context.DROPBOX_SERVICE);
12998
12999        // Exit early if the dropbox isn't configured to accept this report type.
13000        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13001
13002        boolean bufferWasEmpty;
13003        boolean needsFlush;
13004        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13005        synchronized (sb) {
13006            bufferWasEmpty = sb.length() == 0;
13007            appendDropBoxProcessHeaders(process, processName, sb);
13008            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13009            sb.append("System-App: ").append(isSystemApp).append("\n");
13010            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13011            if (info.violationNumThisLoop != 0) {
13012                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13013            }
13014            if (info.numAnimationsRunning != 0) {
13015                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13016            }
13017            if (info.broadcastIntentAction != null) {
13018                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13019            }
13020            if (info.durationMillis != -1) {
13021                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13022            }
13023            if (info.numInstances != -1) {
13024                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13025            }
13026            if (info.tags != null) {
13027                for (String tag : info.tags) {
13028                    sb.append("Span-Tag: ").append(tag).append("\n");
13029                }
13030            }
13031            sb.append("\n");
13032            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13033                sb.append(info.crashInfo.stackTrace);
13034                sb.append("\n");
13035            }
13036            if (info.message != null) {
13037                sb.append(info.message);
13038                sb.append("\n");
13039            }
13040
13041            // Only buffer up to ~64k.  Various logging bits truncate
13042            // things at 128k.
13043            needsFlush = (sb.length() > 64 * 1024);
13044        }
13045
13046        // Flush immediately if the buffer's grown too large, or this
13047        // is a non-system app.  Non-system apps are isolated with a
13048        // different tag & policy and not batched.
13049        //
13050        // Batching is useful during internal testing with
13051        // StrictMode settings turned up high.  Without batching,
13052        // thousands of separate files could be created on boot.
13053        if (!isSystemApp || needsFlush) {
13054            new Thread("Error dump: " + dropboxTag) {
13055                @Override
13056                public void run() {
13057                    String report;
13058                    synchronized (sb) {
13059                        report = sb.toString();
13060                        sb.delete(0, sb.length());
13061                        sb.trimToSize();
13062                    }
13063                    if (report.length() != 0) {
13064                        dbox.addText(dropboxTag, report);
13065                    }
13066                }
13067            }.start();
13068            return;
13069        }
13070
13071        // System app batching:
13072        if (!bufferWasEmpty) {
13073            // An existing dropbox-writing thread is outstanding, so
13074            // we don't need to start it up.  The existing thread will
13075            // catch the buffer appends we just did.
13076            return;
13077        }
13078
13079        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13080        // (After this point, we shouldn't access AMS internal data structures.)
13081        new Thread("Error dump: " + dropboxTag) {
13082            @Override
13083            public void run() {
13084                // 5 second sleep to let stacks arrive and be batched together
13085                try {
13086                    Thread.sleep(5000);  // 5 seconds
13087                } catch (InterruptedException e) {}
13088
13089                String errorReport;
13090                synchronized (mStrictModeBuffer) {
13091                    errorReport = mStrictModeBuffer.toString();
13092                    if (errorReport.length() == 0) {
13093                        return;
13094                    }
13095                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13096                    mStrictModeBuffer.trimToSize();
13097                }
13098                dbox.addText(dropboxTag, errorReport);
13099            }
13100        }.start();
13101    }
13102
13103    /**
13104     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13105     * @param app object of the crashing app, null for the system server
13106     * @param tag reported by the caller
13107     * @param system whether this wtf is coming from the system
13108     * @param crashInfo describing the context of the error
13109     * @return true if the process should exit immediately (WTF is fatal)
13110     */
13111    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13112            final ApplicationErrorReport.CrashInfo crashInfo) {
13113        final int callingUid = Binder.getCallingUid();
13114        final int callingPid = Binder.getCallingPid();
13115
13116        if (system) {
13117            // If this is coming from the system, we could very well have low-level
13118            // system locks held, so we want to do this all asynchronously.  And we
13119            // never want this to become fatal, so there is that too.
13120            mHandler.post(new Runnable() {
13121                @Override public void run() {
13122                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13123                }
13124            });
13125            return false;
13126        }
13127
13128        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13129                crashInfo);
13130
13131        if (r != null && r.pid != Process.myPid() &&
13132                Settings.Global.getInt(mContext.getContentResolver(),
13133                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13134            mAppErrors.crashApplication(r, crashInfo);
13135            return true;
13136        } else {
13137            return false;
13138        }
13139    }
13140
13141    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13142            final ApplicationErrorReport.CrashInfo crashInfo) {
13143        final ProcessRecord r = findAppProcess(app, "WTF");
13144        final String processName = app == null ? "system_server"
13145                : (r == null ? "unknown" : r.processName);
13146
13147        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13148                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13149
13150        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13151
13152        return r;
13153    }
13154
13155    /**
13156     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13157     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13158     */
13159    private ProcessRecord findAppProcess(IBinder app, String reason) {
13160        if (app == null) {
13161            return null;
13162        }
13163
13164        synchronized (this) {
13165            final int NP = mProcessNames.getMap().size();
13166            for (int ip=0; ip<NP; ip++) {
13167                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13168                final int NA = apps.size();
13169                for (int ia=0; ia<NA; ia++) {
13170                    ProcessRecord p = apps.valueAt(ia);
13171                    if (p.thread != null && p.thread.asBinder() == app) {
13172                        return p;
13173                    }
13174                }
13175            }
13176
13177            Slog.w(TAG, "Can't find mystery application for " + reason
13178                    + " from pid=" + Binder.getCallingPid()
13179                    + " uid=" + Binder.getCallingUid() + ": " + app);
13180            return null;
13181        }
13182    }
13183
13184    /**
13185     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13186     * to append various headers to the dropbox log text.
13187     */
13188    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13189            StringBuilder sb) {
13190        // Watchdog thread ends up invoking this function (with
13191        // a null ProcessRecord) to add the stack file to dropbox.
13192        // Do not acquire a lock on this (am) in such cases, as it
13193        // could cause a potential deadlock, if and when watchdog
13194        // is invoked due to unavailability of lock on am and it
13195        // would prevent watchdog from killing system_server.
13196        if (process == null) {
13197            sb.append("Process: ").append(processName).append("\n");
13198            return;
13199        }
13200        // Note: ProcessRecord 'process' is guarded by the service
13201        // instance.  (notably process.pkgList, which could otherwise change
13202        // concurrently during execution of this method)
13203        synchronized (this) {
13204            sb.append("Process: ").append(processName).append("\n");
13205            int flags = process.info.flags;
13206            IPackageManager pm = AppGlobals.getPackageManager();
13207            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13208            for (int ip=0; ip<process.pkgList.size(); ip++) {
13209                String pkg = process.pkgList.keyAt(ip);
13210                sb.append("Package: ").append(pkg);
13211                try {
13212                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13213                    if (pi != null) {
13214                        sb.append(" v").append(pi.versionCode);
13215                        if (pi.versionName != null) {
13216                            sb.append(" (").append(pi.versionName).append(")");
13217                        }
13218                    }
13219                } catch (RemoteException e) {
13220                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13221                }
13222                sb.append("\n");
13223            }
13224        }
13225    }
13226
13227    private static String processClass(ProcessRecord process) {
13228        if (process == null || process.pid == MY_PID) {
13229            return "system_server";
13230        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13231            return "system_app";
13232        } else {
13233            return "data_app";
13234        }
13235    }
13236
13237    private volatile long mWtfClusterStart;
13238    private volatile int mWtfClusterCount;
13239
13240    /**
13241     * Write a description of an error (crash, WTF, ANR) to the drop box.
13242     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13243     * @param process which caused the error, null means the system server
13244     * @param activity which triggered the error, null if unknown
13245     * @param parent activity related to the error, null if unknown
13246     * @param subject line related to the error, null if absent
13247     * @param report in long form describing the error, null if absent
13248     * @param logFile to include in the report, null if none
13249     * @param crashInfo giving an application stack trace, null if absent
13250     */
13251    public void addErrorToDropBox(String eventType,
13252            ProcessRecord process, String processName, ActivityRecord activity,
13253            ActivityRecord parent, String subject,
13254            final String report, final File logFile,
13255            final ApplicationErrorReport.CrashInfo crashInfo) {
13256        // NOTE -- this must never acquire the ActivityManagerService lock,
13257        // otherwise the watchdog may be prevented from resetting the system.
13258
13259        final String dropboxTag = processClass(process) + "_" + eventType;
13260        final DropBoxManager dbox = (DropBoxManager)
13261                mContext.getSystemService(Context.DROPBOX_SERVICE);
13262
13263        // Exit early if the dropbox isn't configured to accept this report type.
13264        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13265
13266        // Rate-limit how often we're willing to do the heavy lifting below to
13267        // collect and record logs; currently 5 logs per 10 second period.
13268        final long now = SystemClock.elapsedRealtime();
13269        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13270            mWtfClusterStart = now;
13271            mWtfClusterCount = 1;
13272        } else {
13273            if (mWtfClusterCount++ >= 5) return;
13274        }
13275
13276        final StringBuilder sb = new StringBuilder(1024);
13277        appendDropBoxProcessHeaders(process, processName, sb);
13278        if (process != null) {
13279            sb.append("Foreground: ")
13280                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13281                    .append("\n");
13282        }
13283        if (activity != null) {
13284            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13285        }
13286        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13287            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13288        }
13289        if (parent != null && parent != activity) {
13290            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13291        }
13292        if (subject != null) {
13293            sb.append("Subject: ").append(subject).append("\n");
13294        }
13295        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13296        if (Debug.isDebuggerConnected()) {
13297            sb.append("Debugger: Connected\n");
13298        }
13299        sb.append("\n");
13300
13301        // Do the rest in a worker thread to avoid blocking the caller on I/O
13302        // (After this point, we shouldn't access AMS internal data structures.)
13303        Thread worker = new Thread("Error dump: " + dropboxTag) {
13304            @Override
13305            public void run() {
13306                if (report != null) {
13307                    sb.append(report);
13308                }
13309                if (logFile != null) {
13310                    try {
13311                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13312                                    "\n\n[[TRUNCATED]]"));
13313                    } catch (IOException e) {
13314                        Slog.e(TAG, "Error reading " + logFile, e);
13315                    }
13316                }
13317                if (crashInfo != null && crashInfo.stackTrace != null) {
13318                    sb.append(crashInfo.stackTrace);
13319                }
13320
13321                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13322                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13323                if (lines > 0) {
13324                    sb.append("\n");
13325
13326                    // Merge several logcat streams, and take the last N lines
13327                    InputStreamReader input = null;
13328                    try {
13329                        java.lang.Process logcat = new ProcessBuilder(
13330                                "/system/bin/timeout", "-k", "15s", "10s",
13331                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13332                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13333                                        .redirectErrorStream(true).start();
13334
13335                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13336                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13337                        input = new InputStreamReader(logcat.getInputStream());
13338
13339                        int num;
13340                        char[] buf = new char[8192];
13341                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13342                    } catch (IOException e) {
13343                        Slog.e(TAG, "Error running logcat", e);
13344                    } finally {
13345                        if (input != null) try { input.close(); } catch (IOException e) {}
13346                    }
13347                }
13348
13349                dbox.addText(dropboxTag, sb.toString());
13350            }
13351        };
13352
13353        if (process == null) {
13354            // If process is null, we are being called from some internal code
13355            // and may be about to die -- run this synchronously.
13356            worker.run();
13357        } else {
13358            worker.start();
13359        }
13360    }
13361
13362    @Override
13363    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13364        enforceNotIsolatedCaller("getProcessesInErrorState");
13365        // assume our apps are happy - lazy create the list
13366        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13367
13368        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13369                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13370        int userId = UserHandle.getUserId(Binder.getCallingUid());
13371
13372        synchronized (this) {
13373
13374            // iterate across all processes
13375            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13376                ProcessRecord app = mLruProcesses.get(i);
13377                if (!allUsers && app.userId != userId) {
13378                    continue;
13379                }
13380                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13381                    // This one's in trouble, so we'll generate a report for it
13382                    // crashes are higher priority (in case there's a crash *and* an anr)
13383                    ActivityManager.ProcessErrorStateInfo report = null;
13384                    if (app.crashing) {
13385                        report = app.crashingReport;
13386                    } else if (app.notResponding) {
13387                        report = app.notRespondingReport;
13388                    }
13389
13390                    if (report != null) {
13391                        if (errList == null) {
13392                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13393                        }
13394                        errList.add(report);
13395                    } else {
13396                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13397                                " crashing = " + app.crashing +
13398                                " notResponding = " + app.notResponding);
13399                    }
13400                }
13401            }
13402        }
13403
13404        return errList;
13405    }
13406
13407    static int procStateToImportance(int procState, int memAdj,
13408            ActivityManager.RunningAppProcessInfo currApp) {
13409        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13410        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13411            currApp.lru = memAdj;
13412        } else {
13413            currApp.lru = 0;
13414        }
13415        return imp;
13416    }
13417
13418    private void fillInProcMemInfo(ProcessRecord app,
13419            ActivityManager.RunningAppProcessInfo outInfo) {
13420        outInfo.pid = app.pid;
13421        outInfo.uid = app.info.uid;
13422        if (mHeavyWeightProcess == app) {
13423            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13424        }
13425        if (app.persistent) {
13426            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13427        }
13428        if (app.activities.size() > 0) {
13429            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13430        }
13431        outInfo.lastTrimLevel = app.trimMemoryLevel;
13432        int adj = app.curAdj;
13433        int procState = app.curProcState;
13434        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13435        outInfo.importanceReasonCode = app.adjTypeCode;
13436        outInfo.processState = app.curProcState;
13437    }
13438
13439    @Override
13440    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13441        enforceNotIsolatedCaller("getRunningAppProcesses");
13442
13443        final int callingUid = Binder.getCallingUid();
13444
13445        // Lazy instantiation of list
13446        List<ActivityManager.RunningAppProcessInfo> runList = null;
13447        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13448                callingUid) == PackageManager.PERMISSION_GRANTED;
13449        final int userId = UserHandle.getUserId(callingUid);
13450        final boolean allUids = isGetTasksAllowed(
13451                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13452
13453        synchronized (this) {
13454            // Iterate across all processes
13455            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13456                ProcessRecord app = mLruProcesses.get(i);
13457                if ((!allUsers && app.userId != userId)
13458                        || (!allUids && app.uid != callingUid)) {
13459                    continue;
13460                }
13461                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13462                    // Generate process state info for running application
13463                    ActivityManager.RunningAppProcessInfo currApp =
13464                        new ActivityManager.RunningAppProcessInfo(app.processName,
13465                                app.pid, app.getPackageList());
13466                    fillInProcMemInfo(app, currApp);
13467                    if (app.adjSource instanceof ProcessRecord) {
13468                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13469                        currApp.importanceReasonImportance =
13470                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13471                                        app.adjSourceProcState);
13472                    } else if (app.adjSource instanceof ActivityRecord) {
13473                        ActivityRecord r = (ActivityRecord)app.adjSource;
13474                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13475                    }
13476                    if (app.adjTarget instanceof ComponentName) {
13477                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13478                    }
13479                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13480                    //        + " lru=" + currApp.lru);
13481                    if (runList == null) {
13482                        runList = new ArrayList<>();
13483                    }
13484                    runList.add(currApp);
13485                }
13486            }
13487        }
13488        return runList;
13489    }
13490
13491    @Override
13492    public List<ApplicationInfo> getRunningExternalApplications() {
13493        enforceNotIsolatedCaller("getRunningExternalApplications");
13494        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13495        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13496        if (runningApps != null && runningApps.size() > 0) {
13497            Set<String> extList = new HashSet<String>();
13498            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13499                if (app.pkgList != null) {
13500                    for (String pkg : app.pkgList) {
13501                        extList.add(pkg);
13502                    }
13503                }
13504            }
13505            IPackageManager pm = AppGlobals.getPackageManager();
13506            for (String pkg : extList) {
13507                try {
13508                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13509                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13510                        retList.add(info);
13511                    }
13512                } catch (RemoteException e) {
13513                }
13514            }
13515        }
13516        return retList;
13517    }
13518
13519    @Override
13520    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13521        enforceNotIsolatedCaller("getMyMemoryState");
13522        synchronized (this) {
13523            ProcessRecord proc;
13524            synchronized (mPidsSelfLocked) {
13525                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13526            }
13527            fillInProcMemInfo(proc, outInfo);
13528        }
13529    }
13530
13531    @Override
13532    public int getMemoryTrimLevel() {
13533        enforceNotIsolatedCaller("getMyMemoryState");
13534        synchronized (this) {
13535            return mLastMemoryLevel;
13536        }
13537    }
13538
13539    @Override
13540    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13541            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13542        (new ActivityManagerShellCommand(this, false)).exec(
13543                this, in, out, err, args, resultReceiver);
13544    }
13545
13546    @Override
13547    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13548        if (checkCallingPermission(android.Manifest.permission.DUMP)
13549                != PackageManager.PERMISSION_GRANTED) {
13550            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13551                    + Binder.getCallingPid()
13552                    + ", uid=" + Binder.getCallingUid()
13553                    + " without permission "
13554                    + android.Manifest.permission.DUMP);
13555            return;
13556        }
13557
13558        boolean dumpAll = false;
13559        boolean dumpClient = false;
13560        String dumpPackage = null;
13561
13562        int opti = 0;
13563        while (opti < args.length) {
13564            String opt = args[opti];
13565            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13566                break;
13567            }
13568            opti++;
13569            if ("-a".equals(opt)) {
13570                dumpAll = true;
13571            } else if ("-c".equals(opt)) {
13572                dumpClient = true;
13573            } else if ("-p".equals(opt)) {
13574                if (opti < args.length) {
13575                    dumpPackage = args[opti];
13576                    opti++;
13577                } else {
13578                    pw.println("Error: -p option requires package argument");
13579                    return;
13580                }
13581                dumpClient = true;
13582            } else if ("-h".equals(opt)) {
13583                ActivityManagerShellCommand.dumpHelp(pw, true);
13584                return;
13585            } else {
13586                pw.println("Unknown argument: " + opt + "; use -h for help");
13587            }
13588        }
13589
13590        long origId = Binder.clearCallingIdentity();
13591        boolean more = false;
13592        // Is the caller requesting to dump a particular piece of data?
13593        if (opti < args.length) {
13594            String cmd = args[opti];
13595            opti++;
13596            if ("activities".equals(cmd) || "a".equals(cmd)) {
13597                synchronized (this) {
13598                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13599                }
13600            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13601                synchronized (this) {
13602                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13603                }
13604            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13605                String[] newArgs;
13606                String name;
13607                if (opti >= args.length) {
13608                    name = null;
13609                    newArgs = EMPTY_STRING_ARRAY;
13610                } else {
13611                    dumpPackage = args[opti];
13612                    opti++;
13613                    newArgs = new String[args.length - opti];
13614                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13615                            args.length - opti);
13616                }
13617                synchronized (this) {
13618                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13619                }
13620            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13621                String[] newArgs;
13622                String name;
13623                if (opti >= args.length) {
13624                    name = null;
13625                    newArgs = EMPTY_STRING_ARRAY;
13626                } else {
13627                    dumpPackage = args[opti];
13628                    opti++;
13629                    newArgs = new String[args.length - opti];
13630                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13631                            args.length - opti);
13632                }
13633                synchronized (this) {
13634                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13635                }
13636            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13637                String[] newArgs;
13638                String name;
13639                if (opti >= args.length) {
13640                    name = null;
13641                    newArgs = EMPTY_STRING_ARRAY;
13642                } else {
13643                    dumpPackage = args[opti];
13644                    opti++;
13645                    newArgs = new String[args.length - opti];
13646                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13647                            args.length - opti);
13648                }
13649                synchronized (this) {
13650                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13651                }
13652            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13653                synchronized (this) {
13654                    dumpOomLocked(fd, pw, args, opti, true);
13655                }
13656            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13657                synchronized (this) {
13658                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13659                }
13660            } else if ("provider".equals(cmd)) {
13661                String[] newArgs;
13662                String name;
13663                if (opti >= args.length) {
13664                    name = null;
13665                    newArgs = EMPTY_STRING_ARRAY;
13666                } else {
13667                    name = args[opti];
13668                    opti++;
13669                    newArgs = new String[args.length - opti];
13670                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13671                }
13672                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13673                    pw.println("No providers match: " + name);
13674                    pw.println("Use -h for help.");
13675                }
13676            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13677                synchronized (this) {
13678                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13679                }
13680            } else if ("service".equals(cmd)) {
13681                String[] newArgs;
13682                String name;
13683                if (opti >= args.length) {
13684                    name = null;
13685                    newArgs = EMPTY_STRING_ARRAY;
13686                } else {
13687                    name = args[opti];
13688                    opti++;
13689                    newArgs = new String[args.length - opti];
13690                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13691                            args.length - opti);
13692                }
13693                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13694                    pw.println("No services match: " + name);
13695                    pw.println("Use -h for help.");
13696                }
13697            } else if ("package".equals(cmd)) {
13698                String[] newArgs;
13699                if (opti >= args.length) {
13700                    pw.println("package: no package name specified");
13701                    pw.println("Use -h for help.");
13702                } else {
13703                    dumpPackage = args[opti];
13704                    opti++;
13705                    newArgs = new String[args.length - opti];
13706                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13707                            args.length - opti);
13708                    args = newArgs;
13709                    opti = 0;
13710                    more = true;
13711                }
13712            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13713                synchronized (this) {
13714                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13715                }
13716            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13717                synchronized (this) {
13718                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13719                }
13720            } else if ("locks".equals(cmd)) {
13721                LockGuard.dump(fd, pw, args);
13722            } else {
13723                // Dumping a single activity?
13724                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13725                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13726                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13727                    if (res < 0) {
13728                        pw.println("Bad activity command, or no activities match: " + cmd);
13729                        pw.println("Use -h for help.");
13730                    }
13731                }
13732            }
13733            if (!more) {
13734                Binder.restoreCallingIdentity(origId);
13735                return;
13736            }
13737        }
13738
13739        // No piece of data specified, dump everything.
13740        synchronized (this) {
13741            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13742            pw.println();
13743            if (dumpAll) {
13744                pw.println("-------------------------------------------------------------------------------");
13745            }
13746            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13747            pw.println();
13748            if (dumpAll) {
13749                pw.println("-------------------------------------------------------------------------------");
13750            }
13751            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13752            pw.println();
13753            if (dumpAll) {
13754                pw.println("-------------------------------------------------------------------------------");
13755            }
13756            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13757            pw.println();
13758            if (dumpAll) {
13759                pw.println("-------------------------------------------------------------------------------");
13760            }
13761            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13762            pw.println();
13763            if (dumpAll) {
13764                pw.println("-------------------------------------------------------------------------------");
13765            }
13766            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13767            pw.println();
13768            if (dumpAll) {
13769                pw.println("-------------------------------------------------------------------------------");
13770            }
13771            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13772            if (mAssociations.size() > 0) {
13773                pw.println();
13774                if (dumpAll) {
13775                    pw.println("-------------------------------------------------------------------------------");
13776                }
13777                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13778            }
13779            pw.println();
13780            if (dumpAll) {
13781                pw.println("-------------------------------------------------------------------------------");
13782            }
13783            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13784        }
13785        Binder.restoreCallingIdentity(origId);
13786    }
13787
13788    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13789            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13790        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13791
13792        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13793                dumpPackage);
13794        boolean needSep = printedAnything;
13795
13796        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13797                dumpPackage, needSep, "  mFocusedActivity: ");
13798        if (printed) {
13799            printedAnything = true;
13800            needSep = false;
13801        }
13802
13803        if (dumpPackage == null) {
13804            if (needSep) {
13805                pw.println();
13806            }
13807            needSep = true;
13808            printedAnything = true;
13809            mStackSupervisor.dump(pw, "  ");
13810        }
13811
13812        if (!printedAnything) {
13813            pw.println("  (nothing)");
13814        }
13815    }
13816
13817    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13818            int opti, boolean dumpAll, String dumpPackage) {
13819        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13820
13821        boolean printedAnything = false;
13822
13823        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13824            boolean printedHeader = false;
13825
13826            final int N = mRecentTasks.size();
13827            for (int i=0; i<N; i++) {
13828                TaskRecord tr = mRecentTasks.get(i);
13829                if (dumpPackage != null) {
13830                    if (tr.realActivity == null ||
13831                            !dumpPackage.equals(tr.realActivity)) {
13832                        continue;
13833                    }
13834                }
13835                if (!printedHeader) {
13836                    pw.println("  Recent tasks:");
13837                    printedHeader = true;
13838                    printedAnything = true;
13839                }
13840                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13841                        pw.println(tr);
13842                if (dumpAll) {
13843                    mRecentTasks.get(i).dump(pw, "    ");
13844                }
13845            }
13846        }
13847
13848        if (!printedAnything) {
13849            pw.println("  (nothing)");
13850        }
13851    }
13852
13853    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13854            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13855        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13856
13857        int dumpUid = 0;
13858        if (dumpPackage != null) {
13859            IPackageManager pm = AppGlobals.getPackageManager();
13860            try {
13861                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13862            } catch (RemoteException e) {
13863            }
13864        }
13865
13866        boolean printedAnything = false;
13867
13868        final long now = SystemClock.uptimeMillis();
13869
13870        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13871            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13872                    = mAssociations.valueAt(i1);
13873            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13874                SparseArray<ArrayMap<String, Association>> sourceUids
13875                        = targetComponents.valueAt(i2);
13876                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13877                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13878                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13879                        Association ass = sourceProcesses.valueAt(i4);
13880                        if (dumpPackage != null) {
13881                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13882                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13883                                continue;
13884                            }
13885                        }
13886                        printedAnything = true;
13887                        pw.print("  ");
13888                        pw.print(ass.mTargetProcess);
13889                        pw.print("/");
13890                        UserHandle.formatUid(pw, ass.mTargetUid);
13891                        pw.print(" <- ");
13892                        pw.print(ass.mSourceProcess);
13893                        pw.print("/");
13894                        UserHandle.formatUid(pw, ass.mSourceUid);
13895                        pw.println();
13896                        pw.print("    via ");
13897                        pw.print(ass.mTargetComponent.flattenToShortString());
13898                        pw.println();
13899                        pw.print("    ");
13900                        long dur = ass.mTime;
13901                        if (ass.mNesting > 0) {
13902                            dur += now - ass.mStartTime;
13903                        }
13904                        TimeUtils.formatDuration(dur, pw);
13905                        pw.print(" (");
13906                        pw.print(ass.mCount);
13907                        pw.print(" times)");
13908                        pw.print("  ");
13909                        for (int i=0; i<ass.mStateTimes.length; i++) {
13910                            long amt = ass.mStateTimes[i];
13911                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13912                                amt += now - ass.mLastStateUptime;
13913                            }
13914                            if (amt != 0) {
13915                                pw.print(" ");
13916                                pw.print(ProcessList.makeProcStateString(
13917                                            i + ActivityManager.MIN_PROCESS_STATE));
13918                                pw.print("=");
13919                                TimeUtils.formatDuration(amt, pw);
13920                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13921                                    pw.print("*");
13922                                }
13923                            }
13924                        }
13925                        pw.println();
13926                        if (ass.mNesting > 0) {
13927                            pw.print("    Currently active: ");
13928                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13929                            pw.println();
13930                        }
13931                    }
13932                }
13933            }
13934
13935        }
13936
13937        if (!printedAnything) {
13938            pw.println("  (nothing)");
13939        }
13940    }
13941
13942    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13943            String header, boolean needSep) {
13944        boolean printed = false;
13945        int whichAppId = -1;
13946        if (dumpPackage != null) {
13947            try {
13948                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13949                        dumpPackage, 0);
13950                whichAppId = UserHandle.getAppId(info.uid);
13951            } catch (NameNotFoundException e) {
13952                e.printStackTrace();
13953            }
13954        }
13955        for (int i=0; i<uids.size(); i++) {
13956            UidRecord uidRec = uids.valueAt(i);
13957            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13958                continue;
13959            }
13960            if (!printed) {
13961                printed = true;
13962                if (needSep) {
13963                    pw.println();
13964                }
13965                pw.print("  ");
13966                pw.println(header);
13967                needSep = true;
13968            }
13969            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
13970            pw.print(": "); pw.println(uidRec);
13971        }
13972        return printed;
13973    }
13974
13975    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13976            int opti, boolean dumpAll, String dumpPackage) {
13977        boolean needSep = false;
13978        boolean printedAnything = false;
13979        int numPers = 0;
13980
13981        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13982
13983        if (dumpAll) {
13984            final int NP = mProcessNames.getMap().size();
13985            for (int ip=0; ip<NP; ip++) {
13986                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13987                final int NA = procs.size();
13988                for (int ia=0; ia<NA; ia++) {
13989                    ProcessRecord r = procs.valueAt(ia);
13990                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13991                        continue;
13992                    }
13993                    if (!needSep) {
13994                        pw.println("  All known processes:");
13995                        needSep = true;
13996                        printedAnything = true;
13997                    }
13998                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
13999                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14000                        pw.print(" "); pw.println(r);
14001                    r.dump(pw, "    ");
14002                    if (r.persistent) {
14003                        numPers++;
14004                    }
14005                }
14006            }
14007        }
14008
14009        if (mIsolatedProcesses.size() > 0) {
14010            boolean printed = false;
14011            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14012                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14013                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14014                    continue;
14015                }
14016                if (!printed) {
14017                    if (needSep) {
14018                        pw.println();
14019                    }
14020                    pw.println("  Isolated process list (sorted by uid):");
14021                    printedAnything = true;
14022                    printed = true;
14023                    needSep = true;
14024                }
14025                pw.println(String.format("%sIsolated #%2d: %s",
14026                        "    ", i, r.toString()));
14027            }
14028        }
14029
14030        if (mActiveUids.size() > 0) {
14031            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14032                printedAnything = needSep = true;
14033            }
14034        }
14035        if (mValidateUids.size() > 0) {
14036            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14037                printedAnything = needSep = true;
14038            }
14039        }
14040
14041        if (mLruProcesses.size() > 0) {
14042            if (needSep) {
14043                pw.println();
14044            }
14045            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14046                    pw.print(" total, non-act at ");
14047                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14048                    pw.print(", non-svc at ");
14049                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14050                    pw.println("):");
14051            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14052            needSep = true;
14053            printedAnything = true;
14054        }
14055
14056        if (dumpAll || dumpPackage != null) {
14057            synchronized (mPidsSelfLocked) {
14058                boolean printed = false;
14059                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14060                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14061                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14062                        continue;
14063                    }
14064                    if (!printed) {
14065                        if (needSep) pw.println();
14066                        needSep = true;
14067                        pw.println("  PID mappings:");
14068                        printed = true;
14069                        printedAnything = true;
14070                    }
14071                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14072                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14073                }
14074            }
14075        }
14076
14077        if (mForegroundProcesses.size() > 0) {
14078            synchronized (mPidsSelfLocked) {
14079                boolean printed = false;
14080                for (int i=0; i<mForegroundProcesses.size(); i++) {
14081                    ProcessRecord r = mPidsSelfLocked.get(
14082                            mForegroundProcesses.valueAt(i).pid);
14083                    if (dumpPackage != null && (r == null
14084                            || !r.pkgList.containsKey(dumpPackage))) {
14085                        continue;
14086                    }
14087                    if (!printed) {
14088                        if (needSep) pw.println();
14089                        needSep = true;
14090                        pw.println("  Foreground Processes:");
14091                        printed = true;
14092                        printedAnything = true;
14093                    }
14094                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14095                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14096                }
14097            }
14098        }
14099
14100        if (mPersistentStartingProcesses.size() > 0) {
14101            if (needSep) pw.println();
14102            needSep = true;
14103            printedAnything = true;
14104            pw.println("  Persisent processes that are starting:");
14105            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14106                    "Starting Norm", "Restarting PERS", dumpPackage);
14107        }
14108
14109        if (mRemovedProcesses.size() > 0) {
14110            if (needSep) pw.println();
14111            needSep = true;
14112            printedAnything = true;
14113            pw.println("  Processes that are being removed:");
14114            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14115                    "Removed Norm", "Removed PERS", dumpPackage);
14116        }
14117
14118        if (mProcessesOnHold.size() > 0) {
14119            if (needSep) pw.println();
14120            needSep = true;
14121            printedAnything = true;
14122            pw.println("  Processes that are on old until the system is ready:");
14123            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14124                    "OnHold Norm", "OnHold PERS", dumpPackage);
14125        }
14126
14127        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14128
14129        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14130        if (needSep) {
14131            printedAnything = true;
14132        }
14133
14134        if (dumpPackage == null) {
14135            pw.println();
14136            needSep = false;
14137            mUserController.dump(pw, dumpAll);
14138        }
14139        if (mHomeProcess != null && (dumpPackage == null
14140                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14141            if (needSep) {
14142                pw.println();
14143                needSep = false;
14144            }
14145            pw.println("  mHomeProcess: " + mHomeProcess);
14146        }
14147        if (mPreviousProcess != null && (dumpPackage == null
14148                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14149            if (needSep) {
14150                pw.println();
14151                needSep = false;
14152            }
14153            pw.println("  mPreviousProcess: " + mPreviousProcess);
14154        }
14155        if (dumpAll) {
14156            StringBuilder sb = new StringBuilder(128);
14157            sb.append("  mPreviousProcessVisibleTime: ");
14158            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14159            pw.println(sb);
14160        }
14161        if (mHeavyWeightProcess != null && (dumpPackage == null
14162                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14163            if (needSep) {
14164                pw.println();
14165                needSep = false;
14166            }
14167            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14168        }
14169        if (dumpPackage == null) {
14170            pw.println("  mConfiguration: " + mConfiguration);
14171        }
14172        if (dumpAll) {
14173            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14174            if (mCompatModePackages.getPackages().size() > 0) {
14175                boolean printed = false;
14176                for (Map.Entry<String, Integer> entry
14177                        : mCompatModePackages.getPackages().entrySet()) {
14178                    String pkg = entry.getKey();
14179                    int mode = entry.getValue();
14180                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14181                        continue;
14182                    }
14183                    if (!printed) {
14184                        pw.println("  mScreenCompatPackages:");
14185                        printed = true;
14186                    }
14187                    pw.print("    "); pw.print(pkg); pw.print(": ");
14188                            pw.print(mode); pw.println();
14189                }
14190            }
14191        }
14192        if (dumpPackage == null) {
14193            pw.println("  mWakefulness="
14194                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14195            pw.println("  mSleepTokens=" + mSleepTokens);
14196            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14197                    + lockScreenShownToString());
14198            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14199            if (mRunningVoice != null) {
14200                pw.println("  mRunningVoice=" + mRunningVoice);
14201                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14202            }
14203        }
14204        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14205                || mOrigWaitForDebugger) {
14206            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14207                    || dumpPackage.equals(mOrigDebugApp)) {
14208                if (needSep) {
14209                    pw.println();
14210                    needSep = false;
14211                }
14212                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14213                        + " mDebugTransient=" + mDebugTransient
14214                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14215            }
14216        }
14217        if (mCurAppTimeTracker != null) {
14218            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14219        }
14220        if (mMemWatchProcesses.getMap().size() > 0) {
14221            pw.println("  Mem watch processes:");
14222            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14223                    = mMemWatchProcesses.getMap();
14224            for (int i=0; i<procs.size(); i++) {
14225                final String proc = procs.keyAt(i);
14226                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14227                for (int j=0; j<uids.size(); j++) {
14228                    if (needSep) {
14229                        pw.println();
14230                        needSep = false;
14231                    }
14232                    StringBuilder sb = new StringBuilder();
14233                    sb.append("    ").append(proc).append('/');
14234                    UserHandle.formatUid(sb, uids.keyAt(j));
14235                    Pair<Long, String> val = uids.valueAt(j);
14236                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14237                    if (val.second != null) {
14238                        sb.append(", report to ").append(val.second);
14239                    }
14240                    pw.println(sb.toString());
14241                }
14242            }
14243            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14244            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14245            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14246                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14247        }
14248        if (mTrackAllocationApp != null) {
14249            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14250                if (needSep) {
14251                    pw.println();
14252                    needSep = false;
14253                }
14254                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14255            }
14256        }
14257        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14258                || mProfileFd != null) {
14259            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14260                if (needSep) {
14261                    pw.println();
14262                    needSep = false;
14263                }
14264                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14265                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14266                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14267                        + mAutoStopProfiler);
14268                pw.println("  mProfileType=" + mProfileType);
14269            }
14270        }
14271        if (mNativeDebuggingApp != null) {
14272            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14273                if (needSep) {
14274                    pw.println();
14275                    needSep = false;
14276                }
14277                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14278            }
14279        }
14280        if (dumpPackage == null) {
14281            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14282                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14283                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14284            }
14285            if (mController != null) {
14286                pw.println("  mController=" + mController
14287                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14288            }
14289            if (dumpAll) {
14290                pw.println("  Total persistent processes: " + numPers);
14291                pw.println("  mProcessesReady=" + mProcessesReady
14292                        + " mSystemReady=" + mSystemReady
14293                        + " mBooted=" + mBooted
14294                        + " mFactoryTest=" + mFactoryTest);
14295                pw.println("  mBooting=" + mBooting
14296                        + " mCallFinishBooting=" + mCallFinishBooting
14297                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14298                pw.print("  mLastPowerCheckRealtime=");
14299                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14300                        pw.println("");
14301                pw.print("  mLastPowerCheckUptime=");
14302                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14303                        pw.println("");
14304                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14305                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14306                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14307                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14308                        + " (" + mLruProcesses.size() + " total)"
14309                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14310                        + " mNumServiceProcs=" + mNumServiceProcs
14311                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14312                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14313                        + " mLastMemoryLevel=" + mLastMemoryLevel
14314                        + " mLastNumProcesses=" + mLastNumProcesses);
14315                long now = SystemClock.uptimeMillis();
14316                pw.print("  mLastIdleTime=");
14317                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14318                        pw.print(" mLowRamSinceLastIdle=");
14319                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14320                        pw.println();
14321            }
14322        }
14323
14324        if (!printedAnything) {
14325            pw.println("  (nothing)");
14326        }
14327    }
14328
14329    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14330            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14331        if (mProcessesToGc.size() > 0) {
14332            boolean printed = false;
14333            long now = SystemClock.uptimeMillis();
14334            for (int i=0; i<mProcessesToGc.size(); i++) {
14335                ProcessRecord proc = mProcessesToGc.get(i);
14336                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14337                    continue;
14338                }
14339                if (!printed) {
14340                    if (needSep) pw.println();
14341                    needSep = true;
14342                    pw.println("  Processes that are waiting to GC:");
14343                    printed = true;
14344                }
14345                pw.print("    Process "); pw.println(proc);
14346                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14347                        pw.print(", last gced=");
14348                        pw.print(now-proc.lastRequestedGc);
14349                        pw.print(" ms ago, last lowMem=");
14350                        pw.print(now-proc.lastLowMemory);
14351                        pw.println(" ms ago");
14352
14353            }
14354        }
14355        return needSep;
14356    }
14357
14358    void printOomLevel(PrintWriter pw, String name, int adj) {
14359        pw.print("    ");
14360        if (adj >= 0) {
14361            pw.print(' ');
14362            if (adj < 10) pw.print(' ');
14363        } else {
14364            if (adj > -10) pw.print(' ');
14365        }
14366        pw.print(adj);
14367        pw.print(": ");
14368        pw.print(name);
14369        pw.print(" (");
14370        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14371        pw.println(")");
14372    }
14373
14374    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14375            int opti, boolean dumpAll) {
14376        boolean needSep = false;
14377
14378        if (mLruProcesses.size() > 0) {
14379            if (needSep) pw.println();
14380            needSep = true;
14381            pw.println("  OOM levels:");
14382            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14383            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14384            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14385            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14386            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14387            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14388            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14389            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14390            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14391            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14392            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14393            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14394            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14395            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14396
14397            if (needSep) pw.println();
14398            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14399                    pw.print(" total, non-act at ");
14400                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14401                    pw.print(", non-svc at ");
14402                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14403                    pw.println("):");
14404            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14405            needSep = true;
14406        }
14407
14408        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14409
14410        pw.println();
14411        pw.println("  mHomeProcess: " + mHomeProcess);
14412        pw.println("  mPreviousProcess: " + mPreviousProcess);
14413        if (mHeavyWeightProcess != null) {
14414            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14415        }
14416
14417        return true;
14418    }
14419
14420    /**
14421     * There are three ways to call this:
14422     *  - no provider specified: dump all the providers
14423     *  - a flattened component name that matched an existing provider was specified as the
14424     *    first arg: dump that one provider
14425     *  - the first arg isn't the flattened component name of an existing provider:
14426     *    dump all providers whose component contains the first arg as a substring
14427     */
14428    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14429            int opti, boolean dumpAll) {
14430        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14431    }
14432
14433    static class ItemMatcher {
14434        ArrayList<ComponentName> components;
14435        ArrayList<String> strings;
14436        ArrayList<Integer> objects;
14437        boolean all;
14438
14439        ItemMatcher() {
14440            all = true;
14441        }
14442
14443        void build(String name) {
14444            ComponentName componentName = ComponentName.unflattenFromString(name);
14445            if (componentName != null) {
14446                if (components == null) {
14447                    components = new ArrayList<ComponentName>();
14448                }
14449                components.add(componentName);
14450                all = false;
14451            } else {
14452                int objectId = 0;
14453                // Not a '/' separated full component name; maybe an object ID?
14454                try {
14455                    objectId = Integer.parseInt(name, 16);
14456                    if (objects == null) {
14457                        objects = new ArrayList<Integer>();
14458                    }
14459                    objects.add(objectId);
14460                    all = false;
14461                } catch (RuntimeException e) {
14462                    // Not an integer; just do string match.
14463                    if (strings == null) {
14464                        strings = new ArrayList<String>();
14465                    }
14466                    strings.add(name);
14467                    all = false;
14468                }
14469            }
14470        }
14471
14472        int build(String[] args, int opti) {
14473            for (; opti<args.length; opti++) {
14474                String name = args[opti];
14475                if ("--".equals(name)) {
14476                    return opti+1;
14477                }
14478                build(name);
14479            }
14480            return opti;
14481        }
14482
14483        boolean match(Object object, ComponentName comp) {
14484            if (all) {
14485                return true;
14486            }
14487            if (components != null) {
14488                for (int i=0; i<components.size(); i++) {
14489                    if (components.get(i).equals(comp)) {
14490                        return true;
14491                    }
14492                }
14493            }
14494            if (objects != null) {
14495                for (int i=0; i<objects.size(); i++) {
14496                    if (System.identityHashCode(object) == objects.get(i)) {
14497                        return true;
14498                    }
14499                }
14500            }
14501            if (strings != null) {
14502                String flat = comp.flattenToString();
14503                for (int i=0; i<strings.size(); i++) {
14504                    if (flat.contains(strings.get(i))) {
14505                        return true;
14506                    }
14507                }
14508            }
14509            return false;
14510        }
14511    }
14512
14513    /**
14514     * There are three things that cmd can be:
14515     *  - a flattened component name that matches an existing activity
14516     *  - the cmd arg isn't the flattened component name of an existing activity:
14517     *    dump all activity whose component contains the cmd as a substring
14518     *  - A hex number of the ActivityRecord object instance.
14519     */
14520    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14521            int opti, boolean dumpAll) {
14522        ArrayList<ActivityRecord> activities;
14523
14524        synchronized (this) {
14525            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14526        }
14527
14528        if (activities.size() <= 0) {
14529            return false;
14530        }
14531
14532        String[] newArgs = new String[args.length - opti];
14533        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14534
14535        TaskRecord lastTask = null;
14536        boolean needSep = false;
14537        for (int i=activities.size()-1; i>=0; i--) {
14538            ActivityRecord r = activities.get(i);
14539            if (needSep) {
14540                pw.println();
14541            }
14542            needSep = true;
14543            synchronized (this) {
14544                if (lastTask != r.task) {
14545                    lastTask = r.task;
14546                    pw.print("TASK "); pw.print(lastTask.affinity);
14547                            pw.print(" id="); pw.println(lastTask.taskId);
14548                    if (dumpAll) {
14549                        lastTask.dump(pw, "  ");
14550                    }
14551                }
14552            }
14553            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14554        }
14555        return true;
14556    }
14557
14558    /**
14559     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14560     * there is a thread associated with the activity.
14561     */
14562    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14563            final ActivityRecord r, String[] args, boolean dumpAll) {
14564        String innerPrefix = prefix + "  ";
14565        synchronized (this) {
14566            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14567                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14568                    pw.print(" pid=");
14569                    if (r.app != null) pw.println(r.app.pid);
14570                    else pw.println("(not running)");
14571            if (dumpAll) {
14572                r.dump(pw, innerPrefix);
14573            }
14574        }
14575        if (r.app != null && r.app.thread != null) {
14576            // flush anything that is already in the PrintWriter since the thread is going
14577            // to write to the file descriptor directly
14578            pw.flush();
14579            try {
14580                TransferPipe tp = new TransferPipe();
14581                try {
14582                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14583                            r.appToken, innerPrefix, args);
14584                    tp.go(fd);
14585                } finally {
14586                    tp.kill();
14587                }
14588            } catch (IOException e) {
14589                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14590            } catch (RemoteException e) {
14591                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14592            }
14593        }
14594    }
14595
14596    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14597            int opti, boolean dumpAll, String dumpPackage) {
14598        boolean needSep = false;
14599        boolean onlyHistory = false;
14600        boolean printedAnything = false;
14601
14602        if ("history".equals(dumpPackage)) {
14603            if (opti < args.length && "-s".equals(args[opti])) {
14604                dumpAll = false;
14605            }
14606            onlyHistory = true;
14607            dumpPackage = null;
14608        }
14609
14610        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14611        if (!onlyHistory && dumpAll) {
14612            if (mRegisteredReceivers.size() > 0) {
14613                boolean printed = false;
14614                Iterator it = mRegisteredReceivers.values().iterator();
14615                while (it.hasNext()) {
14616                    ReceiverList r = (ReceiverList)it.next();
14617                    if (dumpPackage != null && (r.app == null ||
14618                            !dumpPackage.equals(r.app.info.packageName))) {
14619                        continue;
14620                    }
14621                    if (!printed) {
14622                        pw.println("  Registered Receivers:");
14623                        needSep = true;
14624                        printed = true;
14625                        printedAnything = true;
14626                    }
14627                    pw.print("  * "); pw.println(r);
14628                    r.dump(pw, "    ");
14629                }
14630            }
14631
14632            if (mReceiverResolver.dump(pw, needSep ?
14633                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14634                    "    ", dumpPackage, false, false)) {
14635                needSep = true;
14636                printedAnything = true;
14637            }
14638        }
14639
14640        for (BroadcastQueue q : mBroadcastQueues) {
14641            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14642            printedAnything |= needSep;
14643        }
14644
14645        needSep = true;
14646
14647        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14648            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14649                if (needSep) {
14650                    pw.println();
14651                }
14652                needSep = true;
14653                printedAnything = true;
14654                pw.print("  Sticky broadcasts for user ");
14655                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14656                StringBuilder sb = new StringBuilder(128);
14657                for (Map.Entry<String, ArrayList<Intent>> ent
14658                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14659                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14660                    if (dumpAll) {
14661                        pw.println(":");
14662                        ArrayList<Intent> intents = ent.getValue();
14663                        final int N = intents.size();
14664                        for (int i=0; i<N; i++) {
14665                            sb.setLength(0);
14666                            sb.append("    Intent: ");
14667                            intents.get(i).toShortString(sb, false, true, false, false);
14668                            pw.println(sb.toString());
14669                            Bundle bundle = intents.get(i).getExtras();
14670                            if (bundle != null) {
14671                                pw.print("      ");
14672                                pw.println(bundle.toString());
14673                            }
14674                        }
14675                    } else {
14676                        pw.println("");
14677                    }
14678                }
14679            }
14680        }
14681
14682        if (!onlyHistory && dumpAll) {
14683            pw.println();
14684            for (BroadcastQueue queue : mBroadcastQueues) {
14685                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14686                        + queue.mBroadcastsScheduled);
14687            }
14688            pw.println("  mHandler:");
14689            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14690            needSep = true;
14691            printedAnything = true;
14692        }
14693
14694        if (!printedAnything) {
14695            pw.println("  (nothing)");
14696        }
14697    }
14698
14699    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14700            int opti, boolean dumpAll, String dumpPackage) {
14701        boolean needSep;
14702        boolean printedAnything = false;
14703
14704        ItemMatcher matcher = new ItemMatcher();
14705        matcher.build(args, opti);
14706
14707        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14708
14709        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14710        printedAnything |= needSep;
14711
14712        if (mLaunchingProviders.size() > 0) {
14713            boolean printed = false;
14714            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14715                ContentProviderRecord r = mLaunchingProviders.get(i);
14716                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14717                    continue;
14718                }
14719                if (!printed) {
14720                    if (needSep) pw.println();
14721                    needSep = true;
14722                    pw.println("  Launching content providers:");
14723                    printed = true;
14724                    printedAnything = true;
14725                }
14726                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14727                        pw.println(r);
14728            }
14729        }
14730
14731        if (!printedAnything) {
14732            pw.println("  (nothing)");
14733        }
14734    }
14735
14736    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14737            int opti, boolean dumpAll, String dumpPackage) {
14738        boolean needSep = false;
14739        boolean printedAnything = false;
14740
14741        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14742
14743        if (mGrantedUriPermissions.size() > 0) {
14744            boolean printed = false;
14745            int dumpUid = -2;
14746            if (dumpPackage != null) {
14747                try {
14748                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14749                            MATCH_UNINSTALLED_PACKAGES, 0);
14750                } catch (NameNotFoundException e) {
14751                    dumpUid = -1;
14752                }
14753            }
14754            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14755                int uid = mGrantedUriPermissions.keyAt(i);
14756                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14757                    continue;
14758                }
14759                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14760                if (!printed) {
14761                    if (needSep) pw.println();
14762                    needSep = true;
14763                    pw.println("  Granted Uri Permissions:");
14764                    printed = true;
14765                    printedAnything = true;
14766                }
14767                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14768                for (UriPermission perm : perms.values()) {
14769                    pw.print("    "); pw.println(perm);
14770                    if (dumpAll) {
14771                        perm.dump(pw, "      ");
14772                    }
14773                }
14774            }
14775        }
14776
14777        if (!printedAnything) {
14778            pw.println("  (nothing)");
14779        }
14780    }
14781
14782    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14783            int opti, boolean dumpAll, String dumpPackage) {
14784        boolean printed = false;
14785
14786        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14787
14788        if (mIntentSenderRecords.size() > 0) {
14789            Iterator<WeakReference<PendingIntentRecord>> it
14790                    = mIntentSenderRecords.values().iterator();
14791            while (it.hasNext()) {
14792                WeakReference<PendingIntentRecord> ref = it.next();
14793                PendingIntentRecord rec = ref != null ? ref.get(): null;
14794                if (dumpPackage != null && (rec == null
14795                        || !dumpPackage.equals(rec.key.packageName))) {
14796                    continue;
14797                }
14798                printed = true;
14799                if (rec != null) {
14800                    pw.print("  * "); pw.println(rec);
14801                    if (dumpAll) {
14802                        rec.dump(pw, "    ");
14803                    }
14804                } else {
14805                    pw.print("  * "); pw.println(ref);
14806                }
14807            }
14808        }
14809
14810        if (!printed) {
14811            pw.println("  (nothing)");
14812        }
14813    }
14814
14815    private static final int dumpProcessList(PrintWriter pw,
14816            ActivityManagerService service, List list,
14817            String prefix, String normalLabel, String persistentLabel,
14818            String dumpPackage) {
14819        int numPers = 0;
14820        final int N = list.size()-1;
14821        for (int i=N; i>=0; i--) {
14822            ProcessRecord r = (ProcessRecord)list.get(i);
14823            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14824                continue;
14825            }
14826            pw.println(String.format("%s%s #%2d: %s",
14827                    prefix, (r.persistent ? persistentLabel : normalLabel),
14828                    i, r.toString()));
14829            if (r.persistent) {
14830                numPers++;
14831            }
14832        }
14833        return numPers;
14834    }
14835
14836    private static final boolean dumpProcessOomList(PrintWriter pw,
14837            ActivityManagerService service, List<ProcessRecord> origList,
14838            String prefix, String normalLabel, String persistentLabel,
14839            boolean inclDetails, String dumpPackage) {
14840
14841        ArrayList<Pair<ProcessRecord, Integer>> list
14842                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14843        for (int i=0; i<origList.size(); i++) {
14844            ProcessRecord r = origList.get(i);
14845            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14846                continue;
14847            }
14848            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14849        }
14850
14851        if (list.size() <= 0) {
14852            return false;
14853        }
14854
14855        Comparator<Pair<ProcessRecord, Integer>> comparator
14856                = new Comparator<Pair<ProcessRecord, Integer>>() {
14857            @Override
14858            public int compare(Pair<ProcessRecord, Integer> object1,
14859                    Pair<ProcessRecord, Integer> object2) {
14860                if (object1.first.setAdj != object2.first.setAdj) {
14861                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14862                }
14863                if (object1.first.setProcState != object2.first.setProcState) {
14864                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14865                }
14866                if (object1.second.intValue() != object2.second.intValue()) {
14867                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14868                }
14869                return 0;
14870            }
14871        };
14872
14873        Collections.sort(list, comparator);
14874
14875        final long curRealtime = SystemClock.elapsedRealtime();
14876        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14877        final long curUptime = SystemClock.uptimeMillis();
14878        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14879
14880        for (int i=list.size()-1; i>=0; i--) {
14881            ProcessRecord r = list.get(i).first;
14882            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14883            char schedGroup;
14884            switch (r.setSchedGroup) {
14885                case ProcessList.SCHED_GROUP_BACKGROUND:
14886                    schedGroup = 'B';
14887                    break;
14888                case ProcessList.SCHED_GROUP_DEFAULT:
14889                    schedGroup = 'F';
14890                    break;
14891                case ProcessList.SCHED_GROUP_TOP_APP:
14892                    schedGroup = 'T';
14893                    break;
14894                default:
14895                    schedGroup = '?';
14896                    break;
14897            }
14898            char foreground;
14899            if (r.foregroundActivities) {
14900                foreground = 'A';
14901            } else if (r.foregroundServices) {
14902                foreground = 'S';
14903            } else {
14904                foreground = ' ';
14905            }
14906            String procState = ProcessList.makeProcStateString(r.curProcState);
14907            pw.print(prefix);
14908            pw.print(r.persistent ? persistentLabel : normalLabel);
14909            pw.print(" #");
14910            int num = (origList.size()-1)-list.get(i).second;
14911            if (num < 10) pw.print(' ');
14912            pw.print(num);
14913            pw.print(": ");
14914            pw.print(oomAdj);
14915            pw.print(' ');
14916            pw.print(schedGroup);
14917            pw.print('/');
14918            pw.print(foreground);
14919            pw.print('/');
14920            pw.print(procState);
14921            pw.print(" trm:");
14922            if (r.trimMemoryLevel < 10) pw.print(' ');
14923            pw.print(r.trimMemoryLevel);
14924            pw.print(' ');
14925            pw.print(r.toShortString());
14926            pw.print(" (");
14927            pw.print(r.adjType);
14928            pw.println(')');
14929            if (r.adjSource != null || r.adjTarget != null) {
14930                pw.print(prefix);
14931                pw.print("    ");
14932                if (r.adjTarget instanceof ComponentName) {
14933                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14934                } else if (r.adjTarget != null) {
14935                    pw.print(r.adjTarget.toString());
14936                } else {
14937                    pw.print("{null}");
14938                }
14939                pw.print("<=");
14940                if (r.adjSource instanceof ProcessRecord) {
14941                    pw.print("Proc{");
14942                    pw.print(((ProcessRecord)r.adjSource).toShortString());
14943                    pw.println("}");
14944                } else if (r.adjSource != null) {
14945                    pw.println(r.adjSource.toString());
14946                } else {
14947                    pw.println("{null}");
14948                }
14949            }
14950            if (inclDetails) {
14951                pw.print(prefix);
14952                pw.print("    ");
14953                pw.print("oom: max="); pw.print(r.maxAdj);
14954                pw.print(" curRaw="); pw.print(r.curRawAdj);
14955                pw.print(" setRaw="); pw.print(r.setRawAdj);
14956                pw.print(" cur="); pw.print(r.curAdj);
14957                pw.print(" set="); pw.println(r.setAdj);
14958                pw.print(prefix);
14959                pw.print("    ");
14960                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14961                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14962                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14963                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
14964                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14965                pw.println();
14966                pw.print(prefix);
14967                pw.print("    ");
14968                pw.print("cached="); pw.print(r.cached);
14969                pw.print(" empty="); pw.print(r.empty);
14970                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14971
14972                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14973                    if (r.lastWakeTime != 0) {
14974                        long wtime;
14975                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14976                        synchronized (stats) {
14977                            wtime = stats.getProcessWakeTime(r.info.uid,
14978                                    r.pid, curRealtime);
14979                        }
14980                        long timeUsed = wtime - r.lastWakeTime;
14981                        pw.print(prefix);
14982                        pw.print("    ");
14983                        pw.print("keep awake over ");
14984                        TimeUtils.formatDuration(realtimeSince, pw);
14985                        pw.print(" used ");
14986                        TimeUtils.formatDuration(timeUsed, pw);
14987                        pw.print(" (");
14988                        pw.print((timeUsed*100)/realtimeSince);
14989                        pw.println("%)");
14990                    }
14991                    if (r.lastCpuTime != 0) {
14992                        long timeUsed = r.curCpuTime - r.lastCpuTime;
14993                        pw.print(prefix);
14994                        pw.print("    ");
14995                        pw.print("run cpu over ");
14996                        TimeUtils.formatDuration(uptimeSince, pw);
14997                        pw.print(" used ");
14998                        TimeUtils.formatDuration(timeUsed, pw);
14999                        pw.print(" (");
15000                        pw.print((timeUsed*100)/uptimeSince);
15001                        pw.println("%)");
15002                    }
15003                }
15004            }
15005        }
15006        return true;
15007    }
15008
15009    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15010            String[] args) {
15011        ArrayList<ProcessRecord> procs;
15012        synchronized (this) {
15013            if (args != null && args.length > start
15014                    && args[start].charAt(0) != '-') {
15015                procs = new ArrayList<ProcessRecord>();
15016                int pid = -1;
15017                try {
15018                    pid = Integer.parseInt(args[start]);
15019                } catch (NumberFormatException e) {
15020                }
15021                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15022                    ProcessRecord proc = mLruProcesses.get(i);
15023                    if (proc.pid == pid) {
15024                        procs.add(proc);
15025                    } else if (allPkgs && proc.pkgList != null
15026                            && proc.pkgList.containsKey(args[start])) {
15027                        procs.add(proc);
15028                    } else if (proc.processName.equals(args[start])) {
15029                        procs.add(proc);
15030                    }
15031                }
15032                if (procs.size() <= 0) {
15033                    return null;
15034                }
15035            } else {
15036                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15037            }
15038        }
15039        return procs;
15040    }
15041
15042    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15043            PrintWriter pw, String[] args) {
15044        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15045        if (procs == null) {
15046            pw.println("No process found for: " + args[0]);
15047            return;
15048        }
15049
15050        long uptime = SystemClock.uptimeMillis();
15051        long realtime = SystemClock.elapsedRealtime();
15052        pw.println("Applications Graphics Acceleration Info:");
15053        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15054
15055        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15056            ProcessRecord r = procs.get(i);
15057            if (r.thread != null) {
15058                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15059                pw.flush();
15060                try {
15061                    TransferPipe tp = new TransferPipe();
15062                    try {
15063                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15064                        tp.go(fd);
15065                    } finally {
15066                        tp.kill();
15067                    }
15068                } catch (IOException e) {
15069                    pw.println("Failure while dumping the app: " + r);
15070                    pw.flush();
15071                } catch (RemoteException e) {
15072                    pw.println("Got a RemoteException while dumping the app " + r);
15073                    pw.flush();
15074                }
15075            }
15076        }
15077    }
15078
15079    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15080        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15081        if (procs == null) {
15082            pw.println("No process found for: " + args[0]);
15083            return;
15084        }
15085
15086        pw.println("Applications Database Info:");
15087
15088        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15089            ProcessRecord r = procs.get(i);
15090            if (r.thread != null) {
15091                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15092                pw.flush();
15093                try {
15094                    TransferPipe tp = new TransferPipe();
15095                    try {
15096                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15097                        tp.go(fd);
15098                    } finally {
15099                        tp.kill();
15100                    }
15101                } catch (IOException e) {
15102                    pw.println("Failure while dumping the app: " + r);
15103                    pw.flush();
15104                } catch (RemoteException e) {
15105                    pw.println("Got a RemoteException while dumping the app " + r);
15106                    pw.flush();
15107                }
15108            }
15109        }
15110    }
15111
15112    final static class MemItem {
15113        final boolean isProc;
15114        final String label;
15115        final String shortLabel;
15116        final long pss;
15117        final long swapPss;
15118        final int id;
15119        final boolean hasActivities;
15120        ArrayList<MemItem> subitems;
15121
15122        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15123                boolean _hasActivities) {
15124            isProc = true;
15125            label = _label;
15126            shortLabel = _shortLabel;
15127            pss = _pss;
15128            swapPss = _swapPss;
15129            id = _id;
15130            hasActivities = _hasActivities;
15131        }
15132
15133        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15134            isProc = false;
15135            label = _label;
15136            shortLabel = _shortLabel;
15137            pss = _pss;
15138            swapPss = _swapPss;
15139            id = _id;
15140            hasActivities = false;
15141        }
15142    }
15143
15144    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15145            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15146        if (sort && !isCompact) {
15147            Collections.sort(items, new Comparator<MemItem>() {
15148                @Override
15149                public int compare(MemItem lhs, MemItem rhs) {
15150                    if (lhs.pss < rhs.pss) {
15151                        return 1;
15152                    } else if (lhs.pss > rhs.pss) {
15153                        return -1;
15154                    }
15155                    return 0;
15156                }
15157            });
15158        }
15159
15160        for (int i=0; i<items.size(); i++) {
15161            MemItem mi = items.get(i);
15162            if (!isCompact) {
15163                if (dumpSwapPss) {
15164                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15165                            mi.label, stringifyKBSize(mi.swapPss));
15166                } else {
15167                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15168                }
15169            } else if (mi.isProc) {
15170                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15171                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15172                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15173                pw.println(mi.hasActivities ? ",a" : ",e");
15174            } else {
15175                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15176                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15177            }
15178            if (mi.subitems != null) {
15179                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15180                        true, isCompact, dumpSwapPss);
15181            }
15182        }
15183    }
15184
15185    // These are in KB.
15186    static final long[] DUMP_MEM_BUCKETS = new long[] {
15187        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15188        120*1024, 160*1024, 200*1024,
15189        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15190        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15191    };
15192
15193    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15194            boolean stackLike) {
15195        int start = label.lastIndexOf('.');
15196        if (start >= 0) start++;
15197        else start = 0;
15198        int end = label.length();
15199        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15200            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15201                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15202                out.append(bucket);
15203                out.append(stackLike ? "MB." : "MB ");
15204                out.append(label, start, end);
15205                return;
15206            }
15207        }
15208        out.append(memKB/1024);
15209        out.append(stackLike ? "MB." : "MB ");
15210        out.append(label, start, end);
15211    }
15212
15213    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15214            ProcessList.NATIVE_ADJ,
15215            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15216            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15217            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15218            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15219            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15220            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15221    };
15222    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15223            "Native",
15224            "System", "Persistent", "Persistent Service", "Foreground",
15225            "Visible", "Perceptible",
15226            "Heavy Weight", "Backup",
15227            "A Services", "Home",
15228            "Previous", "B Services", "Cached"
15229    };
15230    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15231            "native",
15232            "sys", "pers", "persvc", "fore",
15233            "vis", "percept",
15234            "heavy", "backup",
15235            "servicea", "home",
15236            "prev", "serviceb", "cached"
15237    };
15238
15239    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15240            long realtime, boolean isCheckinRequest, boolean isCompact) {
15241        if (isCompact) {
15242            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15243        }
15244        if (isCheckinRequest || isCompact) {
15245            // short checkin version
15246            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15247        } else {
15248            pw.println("Applications Memory Usage (in Kilobytes):");
15249            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15250        }
15251    }
15252
15253    private static final int KSM_SHARED = 0;
15254    private static final int KSM_SHARING = 1;
15255    private static final int KSM_UNSHARED = 2;
15256    private static final int KSM_VOLATILE = 3;
15257
15258    private final long[] getKsmInfo() {
15259        long[] longOut = new long[4];
15260        final int[] SINGLE_LONG_FORMAT = new int[] {
15261            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15262        };
15263        long[] longTmp = new long[1];
15264        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15265                SINGLE_LONG_FORMAT, null, longTmp, null);
15266        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15267        longTmp[0] = 0;
15268        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15269                SINGLE_LONG_FORMAT, null, longTmp, null);
15270        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15271        longTmp[0] = 0;
15272        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15273                SINGLE_LONG_FORMAT, null, longTmp, null);
15274        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15275        longTmp[0] = 0;
15276        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15277                SINGLE_LONG_FORMAT, null, longTmp, null);
15278        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15279        return longOut;
15280    }
15281
15282    private static String stringifySize(long size, int order) {
15283        Locale locale = Locale.US;
15284        switch (order) {
15285            case 1:
15286                return String.format(locale, "%,13d", size);
15287            case 1024:
15288                return String.format(locale, "%,9dK", size / 1024);
15289            case 1024 * 1024:
15290                return String.format(locale, "%,5dM", size / 1024 / 1024);
15291            case 1024 * 1024 * 1024:
15292                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15293            default:
15294                throw new IllegalArgumentException("Invalid size order");
15295        }
15296    }
15297
15298    private static String stringifyKBSize(long size) {
15299        return stringifySize(size * 1024, 1024);
15300    }
15301
15302    // Update this version number in case you change the 'compact' format
15303    private static final int MEMINFO_COMPACT_VERSION = 1;
15304
15305    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15306            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15307        boolean dumpDetails = false;
15308        boolean dumpFullDetails = false;
15309        boolean dumpDalvik = false;
15310        boolean dumpSummaryOnly = false;
15311        boolean dumpUnreachable = false;
15312        boolean oomOnly = false;
15313        boolean isCompact = false;
15314        boolean localOnly = false;
15315        boolean packages = false;
15316        boolean isCheckinRequest = false;
15317        boolean dumpSwapPss = false;
15318
15319        int opti = 0;
15320        while (opti < args.length) {
15321            String opt = args[opti];
15322            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15323                break;
15324            }
15325            opti++;
15326            if ("-a".equals(opt)) {
15327                dumpDetails = true;
15328                dumpFullDetails = true;
15329                dumpDalvik = true;
15330                dumpSwapPss = true;
15331            } else if ("-d".equals(opt)) {
15332                dumpDalvik = true;
15333            } else if ("-c".equals(opt)) {
15334                isCompact = true;
15335            } else if ("-s".equals(opt)) {
15336                dumpDetails = true;
15337                dumpSummaryOnly = true;
15338            } else if ("-S".equals(opt)) {
15339                dumpSwapPss = true;
15340            } else if ("--unreachable".equals(opt)) {
15341                dumpUnreachable = true;
15342            } else if ("--oom".equals(opt)) {
15343                oomOnly = true;
15344            } else if ("--local".equals(opt)) {
15345                localOnly = true;
15346            } else if ("--package".equals(opt)) {
15347                packages = true;
15348            } else if ("--checkin".equals(opt)) {
15349                isCheckinRequest = true;
15350
15351            } else if ("-h".equals(opt)) {
15352                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15353                pw.println("  -a: include all available information for each process.");
15354                pw.println("  -d: include dalvik details.");
15355                pw.println("  -c: dump in a compact machine-parseable representation.");
15356                pw.println("  -s: dump only summary of application memory usage.");
15357                pw.println("  -S: dump also SwapPss.");
15358                pw.println("  --oom: only show processes organized by oom adj.");
15359                pw.println("  --local: only collect details locally, don't call process.");
15360                pw.println("  --package: interpret process arg as package, dumping all");
15361                pw.println("             processes that have loaded that package.");
15362                pw.println("  --checkin: dump data for a checkin");
15363                pw.println("If [process] is specified it can be the name or ");
15364                pw.println("pid of a specific process to dump.");
15365                return;
15366            } else {
15367                pw.println("Unknown argument: " + opt + "; use -h for help");
15368            }
15369        }
15370
15371        long uptime = SystemClock.uptimeMillis();
15372        long realtime = SystemClock.elapsedRealtime();
15373        final long[] tmpLong = new long[1];
15374
15375        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15376        if (procs == null) {
15377            // No Java processes.  Maybe they want to print a native process.
15378            if (args != null && args.length > opti
15379                    && args[opti].charAt(0) != '-') {
15380                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15381                        = new ArrayList<ProcessCpuTracker.Stats>();
15382                updateCpuStatsNow();
15383                int findPid = -1;
15384                try {
15385                    findPid = Integer.parseInt(args[opti]);
15386                } catch (NumberFormatException e) {
15387                }
15388                synchronized (mProcessCpuTracker) {
15389                    final int N = mProcessCpuTracker.countStats();
15390                    for (int i=0; i<N; i++) {
15391                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15392                        if (st.pid == findPid || (st.baseName != null
15393                                && st.baseName.equals(args[opti]))) {
15394                            nativeProcs.add(st);
15395                        }
15396                    }
15397                }
15398                if (nativeProcs.size() > 0) {
15399                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15400                            isCompact);
15401                    Debug.MemoryInfo mi = null;
15402                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15403                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15404                        final int pid = r.pid;
15405                        if (!isCheckinRequest && dumpDetails) {
15406                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15407                        }
15408                        if (mi == null) {
15409                            mi = new Debug.MemoryInfo();
15410                        }
15411                        if (dumpDetails || (!brief && !oomOnly)) {
15412                            Debug.getMemoryInfo(pid, mi);
15413                        } else {
15414                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15415                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15416                        }
15417                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15418                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15419                        if (isCheckinRequest) {
15420                            pw.println();
15421                        }
15422                    }
15423                    return;
15424                }
15425            }
15426            pw.println("No process found for: " + args[opti]);
15427            return;
15428        }
15429
15430        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15431            dumpDetails = true;
15432        }
15433
15434        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15435
15436        String[] innerArgs = new String[args.length-opti];
15437        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15438
15439        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15440        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15441        long nativePss = 0;
15442        long nativeSwapPss = 0;
15443        long dalvikPss = 0;
15444        long dalvikSwapPss = 0;
15445        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15446                EmptyArray.LONG;
15447        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15448                EmptyArray.LONG;
15449        long otherPss = 0;
15450        long otherSwapPss = 0;
15451        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15452        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15453
15454        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15455        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15456        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15457                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15458
15459        long totalPss = 0;
15460        long totalSwapPss = 0;
15461        long cachedPss = 0;
15462        long cachedSwapPss = 0;
15463        boolean hasSwapPss = false;
15464
15465        Debug.MemoryInfo mi = null;
15466        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15467            final ProcessRecord r = procs.get(i);
15468            final IApplicationThread thread;
15469            final int pid;
15470            final int oomAdj;
15471            final boolean hasActivities;
15472            synchronized (this) {
15473                thread = r.thread;
15474                pid = r.pid;
15475                oomAdj = r.getSetAdjWithServices();
15476                hasActivities = r.activities.size() > 0;
15477            }
15478            if (thread != null) {
15479                if (!isCheckinRequest && dumpDetails) {
15480                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15481                }
15482                if (mi == null) {
15483                    mi = new Debug.MemoryInfo();
15484                }
15485                if (dumpDetails || (!brief && !oomOnly)) {
15486                    Debug.getMemoryInfo(pid, mi);
15487                    hasSwapPss = mi.hasSwappedOutPss;
15488                } else {
15489                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15490                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15491                }
15492                if (dumpDetails) {
15493                    if (localOnly) {
15494                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15495                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15496                        if (isCheckinRequest) {
15497                            pw.println();
15498                        }
15499                    } else {
15500                        try {
15501                            pw.flush();
15502                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15503                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15504                        } catch (RemoteException e) {
15505                            if (!isCheckinRequest) {
15506                                pw.println("Got RemoteException!");
15507                                pw.flush();
15508                            }
15509                        }
15510                    }
15511                }
15512
15513                final long myTotalPss = mi.getTotalPss();
15514                final long myTotalUss = mi.getTotalUss();
15515                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15516
15517                synchronized (this) {
15518                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15519                        // Record this for posterity if the process has been stable.
15520                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15521                    }
15522                }
15523
15524                if (!isCheckinRequest && mi != null) {
15525                    totalPss += myTotalPss;
15526                    totalSwapPss += myTotalSwapPss;
15527                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15528                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15529                            myTotalSwapPss, pid, hasActivities);
15530                    procMems.add(pssItem);
15531                    procMemsMap.put(pid, pssItem);
15532
15533                    nativePss += mi.nativePss;
15534                    nativeSwapPss += mi.nativeSwappedOutPss;
15535                    dalvikPss += mi.dalvikPss;
15536                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15537                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15538                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15539                        dalvikSubitemSwapPss[j] +=
15540                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15541                    }
15542                    otherPss += mi.otherPss;
15543                    otherSwapPss += mi.otherSwappedOutPss;
15544                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15545                        long mem = mi.getOtherPss(j);
15546                        miscPss[j] += mem;
15547                        otherPss -= mem;
15548                        mem = mi.getOtherSwappedOutPss(j);
15549                        miscSwapPss[j] += mem;
15550                        otherSwapPss -= mem;
15551                    }
15552
15553                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15554                        cachedPss += myTotalPss;
15555                        cachedSwapPss += myTotalSwapPss;
15556                    }
15557
15558                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15559                        if (oomIndex == (oomPss.length - 1)
15560                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15561                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15562                            oomPss[oomIndex] += myTotalPss;
15563                            oomSwapPss[oomIndex] += myTotalSwapPss;
15564                            if (oomProcs[oomIndex] == null) {
15565                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15566                            }
15567                            oomProcs[oomIndex].add(pssItem);
15568                            break;
15569                        }
15570                    }
15571                }
15572            }
15573        }
15574
15575        long nativeProcTotalPss = 0;
15576
15577        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15578            // If we are showing aggregations, also look for native processes to
15579            // include so that our aggregations are more accurate.
15580            updateCpuStatsNow();
15581            mi = null;
15582            synchronized (mProcessCpuTracker) {
15583                final int N = mProcessCpuTracker.countStats();
15584                for (int i=0; i<N; i++) {
15585                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15586                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15587                        if (mi == null) {
15588                            mi = new Debug.MemoryInfo();
15589                        }
15590                        if (!brief && !oomOnly) {
15591                            Debug.getMemoryInfo(st.pid, mi);
15592                        } else {
15593                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15594                            mi.nativePrivateDirty = (int)tmpLong[0];
15595                        }
15596
15597                        final long myTotalPss = mi.getTotalPss();
15598                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15599                        totalPss += myTotalPss;
15600                        nativeProcTotalPss += myTotalPss;
15601
15602                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15603                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15604                        procMems.add(pssItem);
15605
15606                        nativePss += mi.nativePss;
15607                        nativeSwapPss += mi.nativeSwappedOutPss;
15608                        dalvikPss += mi.dalvikPss;
15609                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15610                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15611                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15612                            dalvikSubitemSwapPss[j] +=
15613                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15614                        }
15615                        otherPss += mi.otherPss;
15616                        otherSwapPss += mi.otherSwappedOutPss;
15617                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15618                            long mem = mi.getOtherPss(j);
15619                            miscPss[j] += mem;
15620                            otherPss -= mem;
15621                            mem = mi.getOtherSwappedOutPss(j);
15622                            miscSwapPss[j] += mem;
15623                            otherSwapPss -= mem;
15624                        }
15625                        oomPss[0] += myTotalPss;
15626                        oomSwapPss[0] += myTotalSwapPss;
15627                        if (oomProcs[0] == null) {
15628                            oomProcs[0] = new ArrayList<MemItem>();
15629                        }
15630                        oomProcs[0].add(pssItem);
15631                    }
15632                }
15633            }
15634
15635            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15636
15637            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15638            final MemItem dalvikItem =
15639                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15640            if (dalvikSubitemPss.length > 0) {
15641                dalvikItem.subitems = new ArrayList<MemItem>();
15642                for (int j=0; j<dalvikSubitemPss.length; j++) {
15643                    final String name = Debug.MemoryInfo.getOtherLabel(
15644                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15645                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15646                                    dalvikSubitemSwapPss[j], j));
15647                }
15648            }
15649            catMems.add(dalvikItem);
15650            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15651            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15652                String label = Debug.MemoryInfo.getOtherLabel(j);
15653                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15654            }
15655
15656            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15657            for (int j=0; j<oomPss.length; j++) {
15658                if (oomPss[j] != 0) {
15659                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15660                            : DUMP_MEM_OOM_LABEL[j];
15661                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15662                            DUMP_MEM_OOM_ADJ[j]);
15663                    item.subitems = oomProcs[j];
15664                    oomMems.add(item);
15665                }
15666            }
15667
15668            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15669            if (!brief && !oomOnly && !isCompact) {
15670                pw.println();
15671                pw.println("Total PSS by process:");
15672                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15673                pw.println();
15674            }
15675            if (!isCompact) {
15676                pw.println("Total PSS by OOM adjustment:");
15677            }
15678            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15679            if (!brief && !oomOnly) {
15680                PrintWriter out = categoryPw != null ? categoryPw : pw;
15681                if (!isCompact) {
15682                    out.println();
15683                    out.println("Total PSS by category:");
15684                }
15685                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15686            }
15687            if (!isCompact) {
15688                pw.println();
15689            }
15690            MemInfoReader memInfo = new MemInfoReader();
15691            memInfo.readMemInfo();
15692            if (nativeProcTotalPss > 0) {
15693                synchronized (this) {
15694                    final long cachedKb = memInfo.getCachedSizeKb();
15695                    final long freeKb = memInfo.getFreeSizeKb();
15696                    final long zramKb = memInfo.getZramTotalSizeKb();
15697                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15698                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15699                            kernelKb*1024, nativeProcTotalPss*1024);
15700                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15701                            nativeProcTotalPss);
15702                }
15703            }
15704            if (!brief) {
15705                if (!isCompact) {
15706                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15707                    pw.print(" (status ");
15708                    switch (mLastMemoryLevel) {
15709                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15710                            pw.println("normal)");
15711                            break;
15712                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15713                            pw.println("moderate)");
15714                            break;
15715                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15716                            pw.println("low)");
15717                            break;
15718                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15719                            pw.println("critical)");
15720                            break;
15721                        default:
15722                            pw.print(mLastMemoryLevel);
15723                            pw.println(")");
15724                            break;
15725                    }
15726                    pw.print(" Free RAM: ");
15727                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15728                            + memInfo.getFreeSizeKb()));
15729                    pw.print(" (");
15730                    pw.print(stringifyKBSize(cachedPss));
15731                    pw.print(" cached pss + ");
15732                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15733                    pw.print(" cached kernel + ");
15734                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15735                    pw.println(" free)");
15736                } else {
15737                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15738                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15739                            + memInfo.getFreeSizeKb()); pw.print(",");
15740                    pw.println(totalPss - cachedPss);
15741                }
15742            }
15743            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15744                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15745                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15746            if (!isCompact) {
15747                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15748                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15749                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15750                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15751                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15752            } else {
15753                pw.print("lostram,"); pw.println(lostRAM);
15754            }
15755            if (!brief) {
15756                if (memInfo.getZramTotalSizeKb() != 0) {
15757                    if (!isCompact) {
15758                        pw.print("     ZRAM: ");
15759                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15760                                pw.print(" physical used for ");
15761                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15762                                        - memInfo.getSwapFreeSizeKb()));
15763                                pw.print(" in swap (");
15764                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15765                                pw.println(" total swap)");
15766                    } else {
15767                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15768                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15769                                pw.println(memInfo.getSwapFreeSizeKb());
15770                    }
15771                }
15772                final long[] ksm = getKsmInfo();
15773                if (!isCompact) {
15774                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15775                            || ksm[KSM_VOLATILE] != 0) {
15776                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15777                                pw.print(" saved from shared ");
15778                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15779                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15780                                pw.print(" unshared; ");
15781                                pw.print(stringifyKBSize(
15782                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15783                    }
15784                    pw.print("   Tuning: ");
15785                    pw.print(ActivityManager.staticGetMemoryClass());
15786                    pw.print(" (large ");
15787                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15788                    pw.print("), oom ");
15789                    pw.print(stringifySize(
15790                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15791                    pw.print(", restore limit ");
15792                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15793                    if (ActivityManager.isLowRamDeviceStatic()) {
15794                        pw.print(" (low-ram)");
15795                    }
15796                    if (ActivityManager.isHighEndGfx()) {
15797                        pw.print(" (high-end-gfx)");
15798                    }
15799                    pw.println();
15800                } else {
15801                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15802                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15803                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15804                    pw.print("tuning,");
15805                    pw.print(ActivityManager.staticGetMemoryClass());
15806                    pw.print(',');
15807                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15808                    pw.print(',');
15809                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15810                    if (ActivityManager.isLowRamDeviceStatic()) {
15811                        pw.print(",low-ram");
15812                    }
15813                    if (ActivityManager.isHighEndGfx()) {
15814                        pw.print(",high-end-gfx");
15815                    }
15816                    pw.println();
15817                }
15818            }
15819        }
15820    }
15821
15822    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15823            long memtrack, String name) {
15824        sb.append("  ");
15825        sb.append(ProcessList.makeOomAdjString(oomAdj));
15826        sb.append(' ');
15827        sb.append(ProcessList.makeProcStateString(procState));
15828        sb.append(' ');
15829        ProcessList.appendRamKb(sb, pss);
15830        sb.append(": ");
15831        sb.append(name);
15832        if (memtrack > 0) {
15833            sb.append(" (");
15834            sb.append(stringifyKBSize(memtrack));
15835            sb.append(" memtrack)");
15836        }
15837    }
15838
15839    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15840        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15841        sb.append(" (pid ");
15842        sb.append(mi.pid);
15843        sb.append(") ");
15844        sb.append(mi.adjType);
15845        sb.append('\n');
15846        if (mi.adjReason != null) {
15847            sb.append("                      ");
15848            sb.append(mi.adjReason);
15849            sb.append('\n');
15850        }
15851    }
15852
15853    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15854        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15855        for (int i=0, N=memInfos.size(); i<N; i++) {
15856            ProcessMemInfo mi = memInfos.get(i);
15857            infoMap.put(mi.pid, mi);
15858        }
15859        updateCpuStatsNow();
15860        long[] memtrackTmp = new long[1];
15861        synchronized (mProcessCpuTracker) {
15862            final int N = mProcessCpuTracker.countStats();
15863            for (int i=0; i<N; i++) {
15864                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15865                if (st.vsize > 0) {
15866                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15867                    if (pss > 0) {
15868                        if (infoMap.indexOfKey(st.pid) < 0) {
15869                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15870                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15871                            mi.pss = pss;
15872                            mi.memtrack = memtrackTmp[0];
15873                            memInfos.add(mi);
15874                        }
15875                    }
15876                }
15877            }
15878        }
15879
15880        long totalPss = 0;
15881        long totalMemtrack = 0;
15882        for (int i=0, N=memInfos.size(); i<N; i++) {
15883            ProcessMemInfo mi = memInfos.get(i);
15884            if (mi.pss == 0) {
15885                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15886                mi.memtrack = memtrackTmp[0];
15887            }
15888            totalPss += mi.pss;
15889            totalMemtrack += mi.memtrack;
15890        }
15891        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15892            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15893                if (lhs.oomAdj != rhs.oomAdj) {
15894                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15895                }
15896                if (lhs.pss != rhs.pss) {
15897                    return lhs.pss < rhs.pss ? 1 : -1;
15898                }
15899                return 0;
15900            }
15901        });
15902
15903        StringBuilder tag = new StringBuilder(128);
15904        StringBuilder stack = new StringBuilder(128);
15905        tag.append("Low on memory -- ");
15906        appendMemBucket(tag, totalPss, "total", false);
15907        appendMemBucket(stack, totalPss, "total", true);
15908
15909        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15910        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15911        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15912
15913        boolean firstLine = true;
15914        int lastOomAdj = Integer.MIN_VALUE;
15915        long extraNativeRam = 0;
15916        long extraNativeMemtrack = 0;
15917        long cachedPss = 0;
15918        for (int i=0, N=memInfos.size(); i<N; i++) {
15919            ProcessMemInfo mi = memInfos.get(i);
15920
15921            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15922                cachedPss += mi.pss;
15923            }
15924
15925            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15926                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15927                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15928                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15929                if (lastOomAdj != mi.oomAdj) {
15930                    lastOomAdj = mi.oomAdj;
15931                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15932                        tag.append(" / ");
15933                    }
15934                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15935                        if (firstLine) {
15936                            stack.append(":");
15937                            firstLine = false;
15938                        }
15939                        stack.append("\n\t at ");
15940                    } else {
15941                        stack.append("$");
15942                    }
15943                } else {
15944                    tag.append(" ");
15945                    stack.append("$");
15946                }
15947                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15948                    appendMemBucket(tag, mi.pss, mi.name, false);
15949                }
15950                appendMemBucket(stack, mi.pss, mi.name, true);
15951                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15952                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15953                    stack.append("(");
15954                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15955                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15956                            stack.append(DUMP_MEM_OOM_LABEL[k]);
15957                            stack.append(":");
15958                            stack.append(DUMP_MEM_OOM_ADJ[k]);
15959                        }
15960                    }
15961                    stack.append(")");
15962                }
15963            }
15964
15965            appendMemInfo(fullNativeBuilder, mi);
15966            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15967                // The short form only has native processes that are >= 512K.
15968                if (mi.pss >= 512) {
15969                    appendMemInfo(shortNativeBuilder, mi);
15970                } else {
15971                    extraNativeRam += mi.pss;
15972                    extraNativeMemtrack += mi.memtrack;
15973                }
15974            } else {
15975                // Short form has all other details, but if we have collected RAM
15976                // from smaller native processes let's dump a summary of that.
15977                if (extraNativeRam > 0) {
15978                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15979                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15980                    shortNativeBuilder.append('\n');
15981                    extraNativeRam = 0;
15982                }
15983                appendMemInfo(fullJavaBuilder, mi);
15984            }
15985        }
15986
15987        fullJavaBuilder.append("           ");
15988        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15989        fullJavaBuilder.append(": TOTAL");
15990        if (totalMemtrack > 0) {
15991            fullJavaBuilder.append(" (");
15992            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15993            fullJavaBuilder.append(" memtrack)");
15994        } else {
15995        }
15996        fullJavaBuilder.append("\n");
15997
15998        MemInfoReader memInfo = new MemInfoReader();
15999        memInfo.readMemInfo();
16000        final long[] infos = memInfo.getRawInfo();
16001
16002        StringBuilder memInfoBuilder = new StringBuilder(1024);
16003        Debug.getMemInfo(infos);
16004        memInfoBuilder.append("  MemInfo: ");
16005        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16006        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16007        memInfoBuilder.append(stringifyKBSize(
16008                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16009        memInfoBuilder.append(stringifyKBSize(
16010                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16011        memInfoBuilder.append(stringifyKBSize(
16012                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16013        memInfoBuilder.append("           ");
16014        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16015        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16016        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16017        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16018        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16019            memInfoBuilder.append("  ZRAM: ");
16020            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16021            memInfoBuilder.append(" RAM, ");
16022            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16023            memInfoBuilder.append(" swap total, ");
16024            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16025            memInfoBuilder.append(" swap free\n");
16026        }
16027        final long[] ksm = getKsmInfo();
16028        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16029                || ksm[KSM_VOLATILE] != 0) {
16030            memInfoBuilder.append("  KSM: ");
16031            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16032            memInfoBuilder.append(" saved from shared ");
16033            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16034            memInfoBuilder.append("\n       ");
16035            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16036            memInfoBuilder.append(" unshared; ");
16037            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16038            memInfoBuilder.append(" volatile\n");
16039        }
16040        memInfoBuilder.append("  Free RAM: ");
16041        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16042                + memInfo.getFreeSizeKb()));
16043        memInfoBuilder.append("\n");
16044        memInfoBuilder.append("  Used RAM: ");
16045        memInfoBuilder.append(stringifyKBSize(
16046                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16047        memInfoBuilder.append("\n");
16048        memInfoBuilder.append("  Lost RAM: ");
16049        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16050                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16051                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16052        memInfoBuilder.append("\n");
16053        Slog.i(TAG, "Low on memory:");
16054        Slog.i(TAG, shortNativeBuilder.toString());
16055        Slog.i(TAG, fullJavaBuilder.toString());
16056        Slog.i(TAG, memInfoBuilder.toString());
16057
16058        StringBuilder dropBuilder = new StringBuilder(1024);
16059        /*
16060        StringWriter oomSw = new StringWriter();
16061        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16062        StringWriter catSw = new StringWriter();
16063        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16064        String[] emptyArgs = new String[] { };
16065        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16066        oomPw.flush();
16067        String oomString = oomSw.toString();
16068        */
16069        dropBuilder.append("Low on memory:");
16070        dropBuilder.append(stack);
16071        dropBuilder.append('\n');
16072        dropBuilder.append(fullNativeBuilder);
16073        dropBuilder.append(fullJavaBuilder);
16074        dropBuilder.append('\n');
16075        dropBuilder.append(memInfoBuilder);
16076        dropBuilder.append('\n');
16077        /*
16078        dropBuilder.append(oomString);
16079        dropBuilder.append('\n');
16080        */
16081        StringWriter catSw = new StringWriter();
16082        synchronized (ActivityManagerService.this) {
16083            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16084            String[] emptyArgs = new String[] { };
16085            catPw.println();
16086            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16087            catPw.println();
16088            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16089                    false, false, null);
16090            catPw.println();
16091            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16092            catPw.flush();
16093        }
16094        dropBuilder.append(catSw.toString());
16095        addErrorToDropBox("lowmem", null, "system_server", null,
16096                null, tag.toString(), dropBuilder.toString(), null, null);
16097        //Slog.i(TAG, "Sent to dropbox:");
16098        //Slog.i(TAG, dropBuilder.toString());
16099        synchronized (ActivityManagerService.this) {
16100            long now = SystemClock.uptimeMillis();
16101            if (mLastMemUsageReportTime < now) {
16102                mLastMemUsageReportTime = now;
16103            }
16104        }
16105    }
16106
16107    /**
16108     * Searches array of arguments for the specified string
16109     * @param args array of argument strings
16110     * @param value value to search for
16111     * @return true if the value is contained in the array
16112     */
16113    private static boolean scanArgs(String[] args, String value) {
16114        if (args != null) {
16115            for (String arg : args) {
16116                if (value.equals(arg)) {
16117                    return true;
16118                }
16119            }
16120        }
16121        return false;
16122    }
16123
16124    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16125            ContentProviderRecord cpr, boolean always) {
16126        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16127
16128        if (!inLaunching || always) {
16129            synchronized (cpr) {
16130                cpr.launchingApp = null;
16131                cpr.notifyAll();
16132            }
16133            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16134            String names[] = cpr.info.authority.split(";");
16135            for (int j = 0; j < names.length; j++) {
16136                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16137            }
16138        }
16139
16140        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16141            ContentProviderConnection conn = cpr.connections.get(i);
16142            if (conn.waiting) {
16143                // If this connection is waiting for the provider, then we don't
16144                // need to mess with its process unless we are always removing
16145                // or for some reason the provider is not currently launching.
16146                if (inLaunching && !always) {
16147                    continue;
16148                }
16149            }
16150            ProcessRecord capp = conn.client;
16151            conn.dead = true;
16152            if (conn.stableCount > 0) {
16153                if (!capp.persistent && capp.thread != null
16154                        && capp.pid != 0
16155                        && capp.pid != MY_PID) {
16156                    capp.kill("depends on provider "
16157                            + cpr.name.flattenToShortString()
16158                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16159                }
16160            } else if (capp.thread != null && conn.provider.provider != null) {
16161                try {
16162                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16163                } catch (RemoteException e) {
16164                }
16165                // In the protocol here, we don't expect the client to correctly
16166                // clean up this connection, we'll just remove it.
16167                cpr.connections.remove(i);
16168                if (conn.client.conProviders.remove(conn)) {
16169                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16170                }
16171            }
16172        }
16173
16174        if (inLaunching && always) {
16175            mLaunchingProviders.remove(cpr);
16176        }
16177        return inLaunching;
16178    }
16179
16180    /**
16181     * Main code for cleaning up a process when it has gone away.  This is
16182     * called both as a result of the process dying, or directly when stopping
16183     * a process when running in single process mode.
16184     *
16185     * @return Returns true if the given process has been restarted, so the
16186     * app that was passed in must remain on the process lists.
16187     */
16188    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16189            boolean restarting, boolean allowRestart, int index) {
16190        if (index >= 0) {
16191            removeLruProcessLocked(app);
16192            ProcessList.remove(app.pid);
16193        }
16194
16195        mProcessesToGc.remove(app);
16196        mPendingPssProcesses.remove(app);
16197
16198        // Dismiss any open dialogs.
16199        if (app.crashDialog != null && !app.forceCrashReport) {
16200            app.crashDialog.dismiss();
16201            app.crashDialog = null;
16202        }
16203        if (app.anrDialog != null) {
16204            app.anrDialog.dismiss();
16205            app.anrDialog = null;
16206        }
16207        if (app.waitDialog != null) {
16208            app.waitDialog.dismiss();
16209            app.waitDialog = null;
16210        }
16211
16212        app.crashing = false;
16213        app.notResponding = false;
16214
16215        app.resetPackageList(mProcessStats);
16216        app.unlinkDeathRecipient();
16217        app.makeInactive(mProcessStats);
16218        app.waitingToKill = null;
16219        app.forcingToForeground = null;
16220        updateProcessForegroundLocked(app, false, false);
16221        app.foregroundActivities = false;
16222        app.hasShownUi = false;
16223        app.treatLikeActivity = false;
16224        app.hasAboveClient = false;
16225        app.hasClientActivities = false;
16226
16227        mServices.killServicesLocked(app, allowRestart);
16228
16229        boolean restart = false;
16230
16231        // Remove published content providers.
16232        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16233            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16234            final boolean always = app.bad || !allowRestart;
16235            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16236            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16237                // We left the provider in the launching list, need to
16238                // restart it.
16239                restart = true;
16240            }
16241
16242            cpr.provider = null;
16243            cpr.proc = null;
16244        }
16245        app.pubProviders.clear();
16246
16247        // Take care of any launching providers waiting for this process.
16248        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16249            restart = true;
16250        }
16251
16252        // Unregister from connected content providers.
16253        if (!app.conProviders.isEmpty()) {
16254            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16255                ContentProviderConnection conn = app.conProviders.get(i);
16256                conn.provider.connections.remove(conn);
16257                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16258                        conn.provider.name);
16259            }
16260            app.conProviders.clear();
16261        }
16262
16263        // At this point there may be remaining entries in mLaunchingProviders
16264        // where we were the only one waiting, so they are no longer of use.
16265        // Look for these and clean up if found.
16266        // XXX Commented out for now.  Trying to figure out a way to reproduce
16267        // the actual situation to identify what is actually going on.
16268        if (false) {
16269            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16270                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16271                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16272                    synchronized (cpr) {
16273                        cpr.launchingApp = null;
16274                        cpr.notifyAll();
16275                    }
16276                }
16277            }
16278        }
16279
16280        skipCurrentReceiverLocked(app);
16281
16282        // Unregister any receivers.
16283        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16284            removeReceiverLocked(app.receivers.valueAt(i));
16285        }
16286        app.receivers.clear();
16287
16288        // If the app is undergoing backup, tell the backup manager about it
16289        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16290            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16291                    + mBackupTarget.appInfo + " died during backup");
16292            try {
16293                IBackupManager bm = IBackupManager.Stub.asInterface(
16294                        ServiceManager.getService(Context.BACKUP_SERVICE));
16295                bm.agentDisconnected(app.info.packageName);
16296            } catch (RemoteException e) {
16297                // can't happen; backup manager is local
16298            }
16299        }
16300
16301        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16302            ProcessChangeItem item = mPendingProcessChanges.get(i);
16303            if (item.pid == app.pid) {
16304                mPendingProcessChanges.remove(i);
16305                mAvailProcessChanges.add(item);
16306            }
16307        }
16308        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16309                null).sendToTarget();
16310
16311        // If the caller is restarting this app, then leave it in its
16312        // current lists and let the caller take care of it.
16313        if (restarting) {
16314            return false;
16315        }
16316
16317        if (!app.persistent || app.isolated) {
16318            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16319                    "Removing non-persistent process during cleanup: " + app);
16320            removeProcessNameLocked(app.processName, app.uid);
16321            if (mHeavyWeightProcess == app) {
16322                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16323                        mHeavyWeightProcess.userId, 0));
16324                mHeavyWeightProcess = null;
16325            }
16326        } else if (!app.removed) {
16327            // This app is persistent, so we need to keep its record around.
16328            // If it is not already on the pending app list, add it there
16329            // and start a new process for it.
16330            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16331                mPersistentStartingProcesses.add(app);
16332                restart = true;
16333            }
16334        }
16335        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16336                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16337        mProcessesOnHold.remove(app);
16338
16339        if (app == mHomeProcess) {
16340            mHomeProcess = null;
16341        }
16342        if (app == mPreviousProcess) {
16343            mPreviousProcess = null;
16344        }
16345
16346        if (restart && !app.isolated) {
16347            // We have components that still need to be running in the
16348            // process, so re-launch it.
16349            if (index < 0) {
16350                ProcessList.remove(app.pid);
16351            }
16352            addProcessNameLocked(app);
16353            startProcessLocked(app, "restart", app.processName);
16354            return true;
16355        } else if (app.pid > 0 && app.pid != MY_PID) {
16356            // Goodbye!
16357            boolean removed;
16358            synchronized (mPidsSelfLocked) {
16359                mPidsSelfLocked.remove(app.pid);
16360                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16361            }
16362            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16363            if (app.isolated) {
16364                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16365            }
16366            app.setPid(0);
16367        }
16368        return false;
16369    }
16370
16371    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16372        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16373            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16374            if (cpr.launchingApp == app) {
16375                return true;
16376            }
16377        }
16378        return false;
16379    }
16380
16381    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16382        // Look through the content providers we are waiting to have launched,
16383        // and if any run in this process then either schedule a restart of
16384        // the process or kill the client waiting for it if this process has
16385        // gone bad.
16386        boolean restart = false;
16387        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16388            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16389            if (cpr.launchingApp == app) {
16390                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16391                    restart = true;
16392                } else {
16393                    removeDyingProviderLocked(app, cpr, true);
16394                }
16395            }
16396        }
16397        return restart;
16398    }
16399
16400    // =========================================================
16401    // SERVICES
16402    // =========================================================
16403
16404    @Override
16405    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16406            int flags) {
16407        enforceNotIsolatedCaller("getServices");
16408        synchronized (this) {
16409            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16410        }
16411    }
16412
16413    @Override
16414    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16415        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16416        synchronized (this) {
16417            return mServices.getRunningServiceControlPanelLocked(name);
16418        }
16419    }
16420
16421    @Override
16422    public ComponentName startService(IApplicationThread caller, Intent service,
16423            String resolvedType, String callingPackage, int userId)
16424            throws TransactionTooLargeException {
16425        enforceNotIsolatedCaller("startService");
16426        // Refuse possible leaked file descriptors
16427        if (service != null && service.hasFileDescriptors() == true) {
16428            throw new IllegalArgumentException("File descriptors passed in Intent");
16429        }
16430
16431        if (callingPackage == null) {
16432            throw new IllegalArgumentException("callingPackage cannot be null");
16433        }
16434
16435        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16436                "startService: " + service + " type=" + resolvedType);
16437        synchronized(this) {
16438            final int callingPid = Binder.getCallingPid();
16439            final int callingUid = Binder.getCallingUid();
16440            final long origId = Binder.clearCallingIdentity();
16441            ComponentName res = mServices.startServiceLocked(caller, service,
16442                    resolvedType, callingPid, callingUid, callingPackage, userId);
16443            Binder.restoreCallingIdentity(origId);
16444            return res;
16445        }
16446    }
16447
16448    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16449            String callingPackage, int userId)
16450            throws TransactionTooLargeException {
16451        synchronized(this) {
16452            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16453                    "startServiceInPackage: " + service + " type=" + resolvedType);
16454            final long origId = Binder.clearCallingIdentity();
16455            ComponentName res = mServices.startServiceLocked(null, service,
16456                    resolvedType, -1, uid, callingPackage, userId);
16457            Binder.restoreCallingIdentity(origId);
16458            return res;
16459        }
16460    }
16461
16462    @Override
16463    public int stopService(IApplicationThread caller, Intent service,
16464            String resolvedType, int userId) {
16465        enforceNotIsolatedCaller("stopService");
16466        // Refuse possible leaked file descriptors
16467        if (service != null && service.hasFileDescriptors() == true) {
16468            throw new IllegalArgumentException("File descriptors passed in Intent");
16469        }
16470
16471        synchronized(this) {
16472            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16473        }
16474    }
16475
16476    @Override
16477    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16478        enforceNotIsolatedCaller("peekService");
16479        // Refuse possible leaked file descriptors
16480        if (service != null && service.hasFileDescriptors() == true) {
16481            throw new IllegalArgumentException("File descriptors passed in Intent");
16482        }
16483
16484        if (callingPackage == null) {
16485            throw new IllegalArgumentException("callingPackage cannot be null");
16486        }
16487
16488        synchronized(this) {
16489            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16490        }
16491    }
16492
16493    @Override
16494    public boolean stopServiceToken(ComponentName className, IBinder token,
16495            int startId) {
16496        synchronized(this) {
16497            return mServices.stopServiceTokenLocked(className, token, startId);
16498        }
16499    }
16500
16501    @Override
16502    public void setServiceForeground(ComponentName className, IBinder token,
16503            int id, Notification notification, int flags) {
16504        synchronized(this) {
16505            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16506        }
16507    }
16508
16509    @Override
16510    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16511            boolean requireFull, String name, String callerPackage) {
16512        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16513                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16514    }
16515
16516    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16517            String className, int flags) {
16518        boolean result = false;
16519        // For apps that don't have pre-defined UIDs, check for permission
16520        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16521            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16522                if (ActivityManager.checkUidPermission(
16523                        INTERACT_ACROSS_USERS,
16524                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16525                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16526                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16527                            + " requests FLAG_SINGLE_USER, but app does not hold "
16528                            + INTERACT_ACROSS_USERS;
16529                    Slog.w(TAG, msg);
16530                    throw new SecurityException(msg);
16531                }
16532                // Permission passed
16533                result = true;
16534            }
16535        } else if ("system".equals(componentProcessName)) {
16536            result = true;
16537        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16538            // Phone app and persistent apps are allowed to export singleuser providers.
16539            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16540                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16541        }
16542        if (DEBUG_MU) Slog.v(TAG_MU,
16543                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16544                + Integer.toHexString(flags) + ") = " + result);
16545        return result;
16546    }
16547
16548    /**
16549     * Checks to see if the caller is in the same app as the singleton
16550     * component, or the component is in a special app. It allows special apps
16551     * to export singleton components but prevents exporting singleton
16552     * components for regular apps.
16553     */
16554    boolean isValidSingletonCall(int callingUid, int componentUid) {
16555        int componentAppId = UserHandle.getAppId(componentUid);
16556        return UserHandle.isSameApp(callingUid, componentUid)
16557                || componentAppId == Process.SYSTEM_UID
16558                || componentAppId == Process.PHONE_UID
16559                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16560                        == PackageManager.PERMISSION_GRANTED;
16561    }
16562
16563    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16564            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16565            int userId) throws TransactionTooLargeException {
16566        enforceNotIsolatedCaller("bindService");
16567
16568        // Refuse possible leaked file descriptors
16569        if (service != null && service.hasFileDescriptors() == true) {
16570            throw new IllegalArgumentException("File descriptors passed in Intent");
16571        }
16572
16573        if (callingPackage == null) {
16574            throw new IllegalArgumentException("callingPackage cannot be null");
16575        }
16576
16577        synchronized(this) {
16578            return mServices.bindServiceLocked(caller, token, service,
16579                    resolvedType, connection, flags, callingPackage, userId);
16580        }
16581    }
16582
16583    public boolean unbindService(IServiceConnection connection) {
16584        synchronized (this) {
16585            return mServices.unbindServiceLocked(connection);
16586        }
16587    }
16588
16589    public void publishService(IBinder token, Intent intent, IBinder service) {
16590        // Refuse possible leaked file descriptors
16591        if (intent != null && intent.hasFileDescriptors() == true) {
16592            throw new IllegalArgumentException("File descriptors passed in Intent");
16593        }
16594
16595        synchronized(this) {
16596            if (!(token instanceof ServiceRecord)) {
16597                throw new IllegalArgumentException("Invalid service token");
16598            }
16599            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16600        }
16601    }
16602
16603    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16604        // Refuse possible leaked file descriptors
16605        if (intent != null && intent.hasFileDescriptors() == true) {
16606            throw new IllegalArgumentException("File descriptors passed in Intent");
16607        }
16608
16609        synchronized(this) {
16610            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16611        }
16612    }
16613
16614    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16615        synchronized(this) {
16616            if (!(token instanceof ServiceRecord)) {
16617                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16618                throw new IllegalArgumentException("Invalid service token");
16619            }
16620            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16621        }
16622    }
16623
16624    // =========================================================
16625    // BACKUP AND RESTORE
16626    // =========================================================
16627
16628    // Cause the target app to be launched if necessary and its backup agent
16629    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16630    // activity manager to announce its creation.
16631    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16632        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16633                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16634        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16635
16636        synchronized(this) {
16637            // !!! TODO: currently no check here that we're already bound
16638            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16639            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16640            synchronized (stats) {
16641                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16642            }
16643
16644            // Backup agent is now in use, its package can't be stopped.
16645            try {
16646                AppGlobals.getPackageManager().setPackageStoppedState(
16647                        app.packageName, false, UserHandle.getUserId(app.uid));
16648            } catch (RemoteException e) {
16649            } catch (IllegalArgumentException e) {
16650                Slog.w(TAG, "Failed trying to unstop package "
16651                        + app.packageName + ": " + e);
16652            }
16653
16654            BackupRecord r = new BackupRecord(ss, app, backupMode);
16655            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16656                    ? new ComponentName(app.packageName, app.backupAgentName)
16657                    : new ComponentName("android", "FullBackupAgent");
16658            // startProcessLocked() returns existing proc's record if it's already running
16659            ProcessRecord proc = startProcessLocked(app.processName, app,
16660                    false, 0, "backup", hostingName, false, false, false);
16661            if (proc == null) {
16662                Slog.e(TAG, "Unable to start backup agent process " + r);
16663                return false;
16664            }
16665
16666            r.app = proc;
16667            mBackupTarget = r;
16668            mBackupAppName = app.packageName;
16669
16670            // Try not to kill the process during backup
16671            updateOomAdjLocked(proc);
16672
16673            // If the process is already attached, schedule the creation of the backup agent now.
16674            // If it is not yet live, this will be done when it attaches to the framework.
16675            if (proc.thread != null) {
16676                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16677                try {
16678                    proc.thread.scheduleCreateBackupAgent(app,
16679                            compatibilityInfoForPackageLocked(app), backupMode);
16680                } catch (RemoteException e) {
16681                    // Will time out on the backup manager side
16682                }
16683            } else {
16684                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16685            }
16686            // Invariants: at this point, the target app process exists and the application
16687            // is either already running or in the process of coming up.  mBackupTarget and
16688            // mBackupAppName describe the app, so that when it binds back to the AM we
16689            // know that it's scheduled for a backup-agent operation.
16690        }
16691
16692        return true;
16693    }
16694
16695    @Override
16696    public void clearPendingBackup() {
16697        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16698        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16699
16700        synchronized (this) {
16701            mBackupTarget = null;
16702            mBackupAppName = null;
16703        }
16704    }
16705
16706    // A backup agent has just come up
16707    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16708        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16709                + " = " + agent);
16710
16711        synchronized(this) {
16712            if (!agentPackageName.equals(mBackupAppName)) {
16713                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16714                return;
16715            }
16716        }
16717
16718        long oldIdent = Binder.clearCallingIdentity();
16719        try {
16720            IBackupManager bm = IBackupManager.Stub.asInterface(
16721                    ServiceManager.getService(Context.BACKUP_SERVICE));
16722            bm.agentConnected(agentPackageName, agent);
16723        } catch (RemoteException e) {
16724            // can't happen; the backup manager service is local
16725        } catch (Exception e) {
16726            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16727            e.printStackTrace();
16728        } finally {
16729            Binder.restoreCallingIdentity(oldIdent);
16730        }
16731    }
16732
16733    // done with this agent
16734    public void unbindBackupAgent(ApplicationInfo appInfo) {
16735        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16736        if (appInfo == null) {
16737            Slog.w(TAG, "unbind backup agent for null app");
16738            return;
16739        }
16740
16741        synchronized(this) {
16742            try {
16743                if (mBackupAppName == null) {
16744                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16745                    return;
16746                }
16747
16748                if (!mBackupAppName.equals(appInfo.packageName)) {
16749                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16750                    return;
16751                }
16752
16753                // Not backing this app up any more; reset its OOM adjustment
16754                final ProcessRecord proc = mBackupTarget.app;
16755                updateOomAdjLocked(proc);
16756
16757                // If the app crashed during backup, 'thread' will be null here
16758                if (proc.thread != null) {
16759                    try {
16760                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16761                                compatibilityInfoForPackageLocked(appInfo));
16762                    } catch (Exception e) {
16763                        Slog.e(TAG, "Exception when unbinding backup agent:");
16764                        e.printStackTrace();
16765                    }
16766                }
16767            } finally {
16768                mBackupTarget = null;
16769                mBackupAppName = null;
16770            }
16771        }
16772    }
16773    // =========================================================
16774    // BROADCASTS
16775    // =========================================================
16776
16777    boolean isPendingBroadcastProcessLocked(int pid) {
16778        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16779                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16780    }
16781
16782    void skipPendingBroadcastLocked(int pid) {
16783            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16784            for (BroadcastQueue queue : mBroadcastQueues) {
16785                queue.skipPendingBroadcastLocked(pid);
16786            }
16787    }
16788
16789    // The app just attached; send any pending broadcasts that it should receive
16790    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16791        boolean didSomething = false;
16792        for (BroadcastQueue queue : mBroadcastQueues) {
16793            didSomething |= queue.sendPendingBroadcastsLocked(app);
16794        }
16795        return didSomething;
16796    }
16797
16798    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16799            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16800        enforceNotIsolatedCaller("registerReceiver");
16801        ArrayList<Intent> stickyIntents = null;
16802        ProcessRecord callerApp = null;
16803        int callingUid;
16804        int callingPid;
16805        synchronized(this) {
16806            if (caller != null) {
16807                callerApp = getRecordForAppLocked(caller);
16808                if (callerApp == null) {
16809                    throw new SecurityException(
16810                            "Unable to find app for caller " + caller
16811                            + " (pid=" + Binder.getCallingPid()
16812                            + ") when registering receiver " + receiver);
16813                }
16814                if (callerApp.info.uid != Process.SYSTEM_UID &&
16815                        !callerApp.pkgList.containsKey(callerPackage) &&
16816                        !"android".equals(callerPackage)) {
16817                    throw new SecurityException("Given caller package " + callerPackage
16818                            + " is not running in process " + callerApp);
16819                }
16820                callingUid = callerApp.info.uid;
16821                callingPid = callerApp.pid;
16822            } else {
16823                callerPackage = null;
16824                callingUid = Binder.getCallingUid();
16825                callingPid = Binder.getCallingPid();
16826            }
16827
16828            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16829                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16830
16831            Iterator<String> actions = filter.actionsIterator();
16832            if (actions == null) {
16833                ArrayList<String> noAction = new ArrayList<String>(1);
16834                noAction.add(null);
16835                actions = noAction.iterator();
16836            }
16837
16838            // Collect stickies of users
16839            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16840            while (actions.hasNext()) {
16841                String action = actions.next();
16842                for (int id : userIds) {
16843                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16844                    if (stickies != null) {
16845                        ArrayList<Intent> intents = stickies.get(action);
16846                        if (intents != null) {
16847                            if (stickyIntents == null) {
16848                                stickyIntents = new ArrayList<Intent>();
16849                            }
16850                            stickyIntents.addAll(intents);
16851                        }
16852                    }
16853                }
16854            }
16855        }
16856
16857        ArrayList<Intent> allSticky = null;
16858        if (stickyIntents != null) {
16859            final ContentResolver resolver = mContext.getContentResolver();
16860            // Look for any matching sticky broadcasts...
16861            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16862                Intent intent = stickyIntents.get(i);
16863                // If intent has scheme "content", it will need to acccess
16864                // provider that needs to lock mProviderMap in ActivityThread
16865                // and also it may need to wait application response, so we
16866                // cannot lock ActivityManagerService here.
16867                if (filter.match(resolver, intent, true, TAG) >= 0) {
16868                    if (allSticky == null) {
16869                        allSticky = new ArrayList<Intent>();
16870                    }
16871                    allSticky.add(intent);
16872                }
16873            }
16874        }
16875
16876        // The first sticky in the list is returned directly back to the client.
16877        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16878        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16879        if (receiver == null) {
16880            return sticky;
16881        }
16882
16883        synchronized (this) {
16884            if (callerApp != null && (callerApp.thread == null
16885                    || callerApp.thread.asBinder() != caller.asBinder())) {
16886                // Original caller already died
16887                return null;
16888            }
16889            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16890            if (rl == null) {
16891                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16892                        userId, receiver);
16893                if (rl.app != null) {
16894                    rl.app.receivers.add(rl);
16895                } else {
16896                    try {
16897                        receiver.asBinder().linkToDeath(rl, 0);
16898                    } catch (RemoteException e) {
16899                        return sticky;
16900                    }
16901                    rl.linkedToDeath = true;
16902                }
16903                mRegisteredReceivers.put(receiver.asBinder(), rl);
16904            } else if (rl.uid != callingUid) {
16905                throw new IllegalArgumentException(
16906                        "Receiver requested to register for uid " + callingUid
16907                        + " was previously registered for uid " + rl.uid);
16908            } else if (rl.pid != callingPid) {
16909                throw new IllegalArgumentException(
16910                        "Receiver requested to register for pid " + callingPid
16911                        + " was previously registered for pid " + rl.pid);
16912            } else if (rl.userId != userId) {
16913                throw new IllegalArgumentException(
16914                        "Receiver requested to register for user " + userId
16915                        + " was previously registered for user " + rl.userId);
16916            }
16917            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16918                    permission, callingUid, userId);
16919            rl.add(bf);
16920            if (!bf.debugCheck()) {
16921                Slog.w(TAG, "==> For Dynamic broadcast");
16922            }
16923            mReceiverResolver.addFilter(bf);
16924
16925            // Enqueue broadcasts for all existing stickies that match
16926            // this filter.
16927            if (allSticky != null) {
16928                ArrayList receivers = new ArrayList();
16929                receivers.add(bf);
16930
16931                final int stickyCount = allSticky.size();
16932                for (int i = 0; i < stickyCount; i++) {
16933                    Intent intent = allSticky.get(i);
16934                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16935                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16936                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16937                            null, 0, null, null, false, true, true, -1);
16938                    queue.enqueueParallelBroadcastLocked(r);
16939                    queue.scheduleBroadcastsLocked();
16940                }
16941            }
16942
16943            return sticky;
16944        }
16945    }
16946
16947    public void unregisterReceiver(IIntentReceiver receiver) {
16948        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16949
16950        final long origId = Binder.clearCallingIdentity();
16951        try {
16952            boolean doTrim = false;
16953
16954            synchronized(this) {
16955                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16956                if (rl != null) {
16957                    final BroadcastRecord r = rl.curBroadcast;
16958                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16959                        final boolean doNext = r.queue.finishReceiverLocked(
16960                                r, r.resultCode, r.resultData, r.resultExtras,
16961                                r.resultAbort, false);
16962                        if (doNext) {
16963                            doTrim = true;
16964                            r.queue.processNextBroadcast(false);
16965                        }
16966                    }
16967
16968                    if (rl.app != null) {
16969                        rl.app.receivers.remove(rl);
16970                    }
16971                    removeReceiverLocked(rl);
16972                    if (rl.linkedToDeath) {
16973                        rl.linkedToDeath = false;
16974                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
16975                    }
16976                }
16977            }
16978
16979            // If we actually concluded any broadcasts, we might now be able
16980            // to trim the recipients' apps from our working set
16981            if (doTrim) {
16982                trimApplications();
16983                return;
16984            }
16985
16986        } finally {
16987            Binder.restoreCallingIdentity(origId);
16988        }
16989    }
16990
16991    void removeReceiverLocked(ReceiverList rl) {
16992        mRegisteredReceivers.remove(rl.receiver.asBinder());
16993        for (int i = rl.size() - 1; i >= 0; i--) {
16994            mReceiverResolver.removeFilter(rl.get(i));
16995        }
16996    }
16997
16998    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16999        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17000            ProcessRecord r = mLruProcesses.get(i);
17001            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17002                try {
17003                    r.thread.dispatchPackageBroadcast(cmd, packages);
17004                } catch (RemoteException ex) {
17005                }
17006            }
17007        }
17008    }
17009
17010    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17011            int callingUid, int[] users) {
17012        // TODO: come back and remove this assumption to triage all broadcasts
17013        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17014
17015        List<ResolveInfo> receivers = null;
17016        try {
17017            HashSet<ComponentName> singleUserReceivers = null;
17018            boolean scannedFirstReceivers = false;
17019            for (int user : users) {
17020                // Skip users that have Shell restrictions, with exception of always permitted
17021                // Shell broadcasts
17022                if (callingUid == Process.SHELL_UID
17023                        && mUserController.hasUserRestriction(
17024                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17025                        && !isPermittedShellBroadcast(intent)) {
17026                    continue;
17027                }
17028                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17029                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17030                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17031                    // If this is not the system user, we need to check for
17032                    // any receivers that should be filtered out.
17033                    for (int i=0; i<newReceivers.size(); i++) {
17034                        ResolveInfo ri = newReceivers.get(i);
17035                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17036                            newReceivers.remove(i);
17037                            i--;
17038                        }
17039                    }
17040                }
17041                if (newReceivers != null && newReceivers.size() == 0) {
17042                    newReceivers = null;
17043                }
17044                if (receivers == null) {
17045                    receivers = newReceivers;
17046                } else if (newReceivers != null) {
17047                    // We need to concatenate the additional receivers
17048                    // found with what we have do far.  This would be easy,
17049                    // but we also need to de-dup any receivers that are
17050                    // singleUser.
17051                    if (!scannedFirstReceivers) {
17052                        // Collect any single user receivers we had already retrieved.
17053                        scannedFirstReceivers = true;
17054                        for (int i=0; i<receivers.size(); i++) {
17055                            ResolveInfo ri = receivers.get(i);
17056                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17057                                ComponentName cn = new ComponentName(
17058                                        ri.activityInfo.packageName, ri.activityInfo.name);
17059                                if (singleUserReceivers == null) {
17060                                    singleUserReceivers = new HashSet<ComponentName>();
17061                                }
17062                                singleUserReceivers.add(cn);
17063                            }
17064                        }
17065                    }
17066                    // Add the new results to the existing results, tracking
17067                    // and de-dupping single user receivers.
17068                    for (int i=0; i<newReceivers.size(); i++) {
17069                        ResolveInfo ri = newReceivers.get(i);
17070                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17071                            ComponentName cn = new ComponentName(
17072                                    ri.activityInfo.packageName, ri.activityInfo.name);
17073                            if (singleUserReceivers == null) {
17074                                singleUserReceivers = new HashSet<ComponentName>();
17075                            }
17076                            if (!singleUserReceivers.contains(cn)) {
17077                                singleUserReceivers.add(cn);
17078                                receivers.add(ri);
17079                            }
17080                        } else {
17081                            receivers.add(ri);
17082                        }
17083                    }
17084                }
17085            }
17086        } catch (RemoteException ex) {
17087            // pm is in same process, this will never happen.
17088        }
17089        return receivers;
17090    }
17091
17092    private boolean isPermittedShellBroadcast(Intent intent) {
17093        // remote bugreport should always be allowed to be taken
17094        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17095    }
17096
17097    final int broadcastIntentLocked(ProcessRecord callerApp,
17098            String callerPackage, Intent intent, String resolvedType,
17099            IIntentReceiver resultTo, int resultCode, String resultData,
17100            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17101            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17102        intent = new Intent(intent);
17103
17104        // By default broadcasts do not go to stopped apps.
17105        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17106
17107        // If we have not finished booting, don't allow this to launch new processes.
17108        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17109            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17110        }
17111
17112        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17113                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17114                + " ordered=" + ordered + " userid=" + userId);
17115        if ((resultTo != null) && !ordered) {
17116            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17117        }
17118
17119        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17120                ALLOW_NON_FULL, "broadcast", callerPackage);
17121
17122        // Make sure that the user who is receiving this broadcast is running.
17123        // If not, we will just skip it. Make an exception for shutdown broadcasts
17124        // and upgrade steps.
17125
17126        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17127            if ((callingUid != Process.SYSTEM_UID
17128                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17129                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17130                Slog.w(TAG, "Skipping broadcast of " + intent
17131                        + ": user " + userId + " is stopped");
17132                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17133            }
17134        }
17135
17136        BroadcastOptions brOptions = null;
17137        if (bOptions != null) {
17138            brOptions = new BroadcastOptions(bOptions);
17139            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17140                // See if the caller is allowed to do this.  Note we are checking against
17141                // the actual real caller (not whoever provided the operation as say a
17142                // PendingIntent), because that who is actually supplied the arguments.
17143                if (checkComponentPermission(
17144                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17145                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17146                        != PackageManager.PERMISSION_GRANTED) {
17147                    String msg = "Permission Denial: " + intent.getAction()
17148                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17149                            + ", uid=" + callingUid + ")"
17150                            + " requires "
17151                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17152                    Slog.w(TAG, msg);
17153                    throw new SecurityException(msg);
17154                }
17155            }
17156        }
17157
17158        // Verify that protected broadcasts are only being sent by system code,
17159        // and that system code is only sending protected broadcasts.
17160        final String action = intent.getAction();
17161        final boolean isProtectedBroadcast;
17162        try {
17163            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17164        } catch (RemoteException e) {
17165            Slog.w(TAG, "Remote exception", e);
17166            return ActivityManager.BROADCAST_SUCCESS;
17167        }
17168
17169        final boolean isCallerSystem;
17170        switch (UserHandle.getAppId(callingUid)) {
17171            case Process.ROOT_UID:
17172            case Process.SYSTEM_UID:
17173            case Process.PHONE_UID:
17174            case Process.BLUETOOTH_UID:
17175            case Process.NFC_UID:
17176                isCallerSystem = true;
17177                break;
17178            default:
17179                isCallerSystem = (callerApp != null) && callerApp.persistent;
17180                break;
17181        }
17182
17183        if (isCallerSystem) {
17184            if (isProtectedBroadcast
17185                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17186                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17187                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17188                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17189                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17190                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17191                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17192                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17193                // Broadcast is either protected, or it's a public action that
17194                // we've relaxed, so it's fine for system internals to send.
17195            } else {
17196                // The vast majority of broadcasts sent from system internals
17197                // should be protected to avoid security holes, so yell loudly
17198                // to ensure we examine these cases.
17199                Log.wtf(TAG, "Sending non-protected broadcast " + action
17200                        + " from system", new Throwable());
17201            }
17202
17203        } else {
17204            if (isProtectedBroadcast) {
17205                String msg = "Permission Denial: not allowed to send broadcast "
17206                        + action + " from pid="
17207                        + callingPid + ", uid=" + callingUid;
17208                Slog.w(TAG, msg);
17209                throw new SecurityException(msg);
17210
17211            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17212                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17213                // Special case for compatibility: we don't want apps to send this,
17214                // but historically it has not been protected and apps may be using it
17215                // to poke their own app widget.  So, instead of making it protected,
17216                // just limit it to the caller.
17217                if (callerPackage == null) {
17218                    String msg = "Permission Denial: not allowed to send broadcast "
17219                            + action + " from unknown caller.";
17220                    Slog.w(TAG, msg);
17221                    throw new SecurityException(msg);
17222                } else if (intent.getComponent() != null) {
17223                    // They are good enough to send to an explicit component...  verify
17224                    // it is being sent to the calling app.
17225                    if (!intent.getComponent().getPackageName().equals(
17226                            callerPackage)) {
17227                        String msg = "Permission Denial: not allowed to send broadcast "
17228                                + action + " to "
17229                                + intent.getComponent().getPackageName() + " from "
17230                                + callerPackage;
17231                        Slog.w(TAG, msg);
17232                        throw new SecurityException(msg);
17233                    }
17234                } else {
17235                    // Limit broadcast to their own package.
17236                    intent.setPackage(callerPackage);
17237                }
17238            }
17239        }
17240
17241        if (action != null) {
17242            switch (action) {
17243                case Intent.ACTION_UID_REMOVED:
17244                case Intent.ACTION_PACKAGE_REMOVED:
17245                case Intent.ACTION_PACKAGE_CHANGED:
17246                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17247                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17248                case Intent.ACTION_PACKAGES_SUSPENDED:
17249                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17250                    // Handle special intents: if this broadcast is from the package
17251                    // manager about a package being removed, we need to remove all of
17252                    // its activities from the history stack.
17253                    if (checkComponentPermission(
17254                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17255                            callingPid, callingUid, -1, true)
17256                            != PackageManager.PERMISSION_GRANTED) {
17257                        String msg = "Permission Denial: " + intent.getAction()
17258                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17259                                + ", uid=" + callingUid + ")"
17260                                + " requires "
17261                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17262                        Slog.w(TAG, msg);
17263                        throw new SecurityException(msg);
17264                    }
17265                    switch (action) {
17266                        case Intent.ACTION_UID_REMOVED:
17267                            final Bundle intentExtras = intent.getExtras();
17268                            final int uid = intentExtras != null
17269                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17270                            if (uid >= 0) {
17271                                mBatteryStatsService.removeUid(uid);
17272                                mAppOpsService.uidRemoved(uid);
17273                            }
17274                            break;
17275                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17276                            // If resources are unavailable just force stop all those packages
17277                            // and flush the attribute cache as well.
17278                            String list[] =
17279                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17280                            if (list != null && list.length > 0) {
17281                                for (int i = 0; i < list.length; i++) {
17282                                    forceStopPackageLocked(list[i], -1, false, true, true,
17283                                            false, false, userId, "storage unmount");
17284                                }
17285                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17286                                sendPackageBroadcastLocked(
17287                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17288                                        userId);
17289                            }
17290                            break;
17291                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17292                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17293                            break;
17294                        case Intent.ACTION_PACKAGE_REMOVED:
17295                        case Intent.ACTION_PACKAGE_CHANGED:
17296                            Uri data = intent.getData();
17297                            String ssp;
17298                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17299                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17300                                final boolean replacing =
17301                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17302                                final boolean killProcess =
17303                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17304                                final boolean fullUninstall = removed && !replacing;
17305                                if (killProcess) {
17306                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17307                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17308                                            false, true, true, false, fullUninstall, userId,
17309                                            removed ? "pkg removed" : "pkg changed");
17310                                }
17311                                if (removed) {
17312                                    final int cmd = killProcess
17313                                            ? IApplicationThread.PACKAGE_REMOVED
17314                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17315                                    sendPackageBroadcastLocked(cmd,
17316                                            new String[] {ssp}, userId);
17317                                    if (fullUninstall) {
17318                                        mAppOpsService.packageRemoved(
17319                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17320
17321                                        // Remove all permissions granted from/to this package
17322                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17323
17324                                        removeTasksByPackageNameLocked(ssp, userId);
17325                                        mBatteryStatsService.notePackageUninstalled(ssp);
17326                                    }
17327                                } else {
17328                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17329                                            intent.getStringArrayExtra(
17330                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17331                                }
17332                            }
17333                            break;
17334                        case Intent.ACTION_PACKAGES_SUSPENDED:
17335                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17336                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17337                                    intent.getAction());
17338                            final String[] packageNames = intent.getStringArrayExtra(
17339                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17340                            final int userHandle = intent.getIntExtra(
17341                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17342
17343                            synchronized(ActivityManagerService.this) {
17344                                mRecentTasks.onPackagesSuspendedChanged(
17345                                        packageNames, suspended, userHandle);
17346                            }
17347                            break;
17348                    }
17349                    break;
17350                case Intent.ACTION_PACKAGE_REPLACED:
17351                {
17352                    final Uri data = intent.getData();
17353                    final String ssp;
17354                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17355                        final ApplicationInfo aInfo =
17356                                getPackageManagerInternalLocked().getApplicationInfo(
17357                                        ssp,
17358                                        userId);
17359                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17360                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17361                                new String[] {ssp}, userId);
17362                    }
17363                    break;
17364                }
17365                case Intent.ACTION_PACKAGE_ADDED:
17366                {
17367                    // Special case for adding a package: by default turn on compatibility mode.
17368                    Uri data = intent.getData();
17369                    String ssp;
17370                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17371                        final boolean replacing =
17372                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17373                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17374
17375                        try {
17376                            ApplicationInfo ai = AppGlobals.getPackageManager().
17377                                    getApplicationInfo(ssp, 0, 0);
17378                            mBatteryStatsService.notePackageInstalled(ssp,
17379                                    ai != null ? ai.versionCode : 0);
17380                        } catch (RemoteException e) {
17381                        }
17382                    }
17383                    break;
17384                }
17385                case Intent.ACTION_TIMEZONE_CHANGED:
17386                    // If this is the time zone changed action, queue up a message that will reset
17387                    // the timezone of all currently running processes. This message will get
17388                    // queued up before the broadcast happens.
17389                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17390                    break;
17391                case Intent.ACTION_TIME_CHANGED:
17392                    // If the user set the time, let all running processes know.
17393                    final int is24Hour =
17394                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17395                                    : 0;
17396                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17397                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17398                    synchronized (stats) {
17399                        stats.noteCurrentTimeChangedLocked();
17400                    }
17401                    break;
17402                case Intent.ACTION_CLEAR_DNS_CACHE:
17403                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17404                    break;
17405                case Proxy.PROXY_CHANGE_ACTION:
17406                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17407                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17408                    break;
17409                case android.hardware.Camera.ACTION_NEW_PICTURE:
17410                case android.hardware.Camera.ACTION_NEW_VIDEO:
17411                    // These broadcasts are no longer allowed by the system, since they can
17412                    // cause significant thrashing at a crictical point (using the camera).
17413                    // Apps should use JobScehduler to monitor for media provider changes.
17414                    Slog.w(TAG, action + " no longer allowed; dropping from "
17415                            + UserHandle.formatUid(callingUid));
17416                    // Lie; we don't want to crash the app.
17417                    return ActivityManager.BROADCAST_SUCCESS;
17418            }
17419        }
17420
17421        // Add to the sticky list if requested.
17422        if (sticky) {
17423            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17424                    callingPid, callingUid)
17425                    != PackageManager.PERMISSION_GRANTED) {
17426                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17427                        + callingPid + ", uid=" + callingUid
17428                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17429                Slog.w(TAG, msg);
17430                throw new SecurityException(msg);
17431            }
17432            if (requiredPermissions != null && requiredPermissions.length > 0) {
17433                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17434                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17435                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17436            }
17437            if (intent.getComponent() != null) {
17438                throw new SecurityException(
17439                        "Sticky broadcasts can't target a specific component");
17440            }
17441            // We use userId directly here, since the "all" target is maintained
17442            // as a separate set of sticky broadcasts.
17443            if (userId != UserHandle.USER_ALL) {
17444                // But first, if this is not a broadcast to all users, then
17445                // make sure it doesn't conflict with an existing broadcast to
17446                // all users.
17447                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17448                        UserHandle.USER_ALL);
17449                if (stickies != null) {
17450                    ArrayList<Intent> list = stickies.get(intent.getAction());
17451                    if (list != null) {
17452                        int N = list.size();
17453                        int i;
17454                        for (i=0; i<N; i++) {
17455                            if (intent.filterEquals(list.get(i))) {
17456                                throw new IllegalArgumentException(
17457                                        "Sticky broadcast " + intent + " for user "
17458                                        + userId + " conflicts with existing global broadcast");
17459                            }
17460                        }
17461                    }
17462                }
17463            }
17464            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17465            if (stickies == null) {
17466                stickies = new ArrayMap<>();
17467                mStickyBroadcasts.put(userId, stickies);
17468            }
17469            ArrayList<Intent> list = stickies.get(intent.getAction());
17470            if (list == null) {
17471                list = new ArrayList<>();
17472                stickies.put(intent.getAction(), list);
17473            }
17474            final int stickiesCount = list.size();
17475            int i;
17476            for (i = 0; i < stickiesCount; i++) {
17477                if (intent.filterEquals(list.get(i))) {
17478                    // This sticky already exists, replace it.
17479                    list.set(i, new Intent(intent));
17480                    break;
17481                }
17482            }
17483            if (i >= stickiesCount) {
17484                list.add(new Intent(intent));
17485            }
17486        }
17487
17488        int[] users;
17489        if (userId == UserHandle.USER_ALL) {
17490            // Caller wants broadcast to go to all started users.
17491            users = mUserController.getStartedUserArrayLocked();
17492        } else {
17493            // Caller wants broadcast to go to one specific user.
17494            users = new int[] {userId};
17495        }
17496
17497        // Figure out who all will receive this broadcast.
17498        List receivers = null;
17499        List<BroadcastFilter> registeredReceivers = null;
17500        // Need to resolve the intent to interested receivers...
17501        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17502                 == 0) {
17503            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17504        }
17505        if (intent.getComponent() == null) {
17506            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17507                // Query one target user at a time, excluding shell-restricted users
17508                for (int i = 0; i < users.length; i++) {
17509                    if (mUserController.hasUserRestriction(
17510                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17511                        continue;
17512                    }
17513                    List<BroadcastFilter> registeredReceiversForUser =
17514                            mReceiverResolver.queryIntent(intent,
17515                                    resolvedType, false, users[i]);
17516                    if (registeredReceivers == null) {
17517                        registeredReceivers = registeredReceiversForUser;
17518                    } else if (registeredReceiversForUser != null) {
17519                        registeredReceivers.addAll(registeredReceiversForUser);
17520                    }
17521                }
17522            } else {
17523                registeredReceivers = mReceiverResolver.queryIntent(intent,
17524                        resolvedType, false, userId);
17525            }
17526        }
17527
17528        final boolean replacePending =
17529                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17530
17531        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17532                + " replacePending=" + replacePending);
17533
17534        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17535        if (!ordered && NR > 0) {
17536            // If we are not serializing this broadcast, then send the
17537            // registered receivers separately so they don't wait for the
17538            // components to be launched.
17539            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17540            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17541                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17542                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17543                    resultExtras, ordered, sticky, false, userId);
17544            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17545            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17546            if (!replaced) {
17547                queue.enqueueParallelBroadcastLocked(r);
17548                queue.scheduleBroadcastsLocked();
17549            }
17550            registeredReceivers = null;
17551            NR = 0;
17552        }
17553
17554        // Merge into one list.
17555        int ir = 0;
17556        if (receivers != null) {
17557            // A special case for PACKAGE_ADDED: do not allow the package
17558            // being added to see this broadcast.  This prevents them from
17559            // using this as a back door to get run as soon as they are
17560            // installed.  Maybe in the future we want to have a special install
17561            // broadcast or such for apps, but we'd like to deliberately make
17562            // this decision.
17563            String skipPackages[] = null;
17564            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17565                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17566                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17567                Uri data = intent.getData();
17568                if (data != null) {
17569                    String pkgName = data.getSchemeSpecificPart();
17570                    if (pkgName != null) {
17571                        skipPackages = new String[] { pkgName };
17572                    }
17573                }
17574            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17575                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17576            }
17577            if (skipPackages != null && (skipPackages.length > 0)) {
17578                for (String skipPackage : skipPackages) {
17579                    if (skipPackage != null) {
17580                        int NT = receivers.size();
17581                        for (int it=0; it<NT; it++) {
17582                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17583                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17584                                receivers.remove(it);
17585                                it--;
17586                                NT--;
17587                            }
17588                        }
17589                    }
17590                }
17591            }
17592
17593            int NT = receivers != null ? receivers.size() : 0;
17594            int it = 0;
17595            ResolveInfo curt = null;
17596            BroadcastFilter curr = null;
17597            while (it < NT && ir < NR) {
17598                if (curt == null) {
17599                    curt = (ResolveInfo)receivers.get(it);
17600                }
17601                if (curr == null) {
17602                    curr = registeredReceivers.get(ir);
17603                }
17604                if (curr.getPriority() >= curt.priority) {
17605                    // Insert this broadcast record into the final list.
17606                    receivers.add(it, curr);
17607                    ir++;
17608                    curr = null;
17609                    it++;
17610                    NT++;
17611                } else {
17612                    // Skip to the next ResolveInfo in the final list.
17613                    it++;
17614                    curt = null;
17615                }
17616            }
17617        }
17618        while (ir < NR) {
17619            if (receivers == null) {
17620                receivers = new ArrayList();
17621            }
17622            receivers.add(registeredReceivers.get(ir));
17623            ir++;
17624        }
17625
17626        if ((receivers != null && receivers.size() > 0)
17627                || resultTo != null) {
17628            BroadcastQueue queue = broadcastQueueForIntent(intent);
17629            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17630                    callerPackage, callingPid, callingUid, resolvedType,
17631                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17632                    resultData, resultExtras, ordered, sticky, false, userId);
17633
17634            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17635                    + ": prev had " + queue.mOrderedBroadcasts.size());
17636            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17637                    "Enqueueing broadcast " + r.intent.getAction());
17638
17639            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17640            if (!replaced) {
17641                queue.enqueueOrderedBroadcastLocked(r);
17642                queue.scheduleBroadcastsLocked();
17643            }
17644        }
17645
17646        return ActivityManager.BROADCAST_SUCCESS;
17647    }
17648
17649    final Intent verifyBroadcastLocked(Intent intent) {
17650        // Refuse possible leaked file descriptors
17651        if (intent != null && intent.hasFileDescriptors() == true) {
17652            throw new IllegalArgumentException("File descriptors passed in Intent");
17653        }
17654
17655        int flags = intent.getFlags();
17656
17657        if (!mProcessesReady) {
17658            // if the caller really truly claims to know what they're doing, go
17659            // ahead and allow the broadcast without launching any receivers
17660            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17661                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17662            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17663                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17664                        + " before boot completion");
17665                throw new IllegalStateException("Cannot broadcast before boot completed");
17666            }
17667        }
17668
17669        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17670            throw new IllegalArgumentException(
17671                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17672        }
17673
17674        return intent;
17675    }
17676
17677    public final int broadcastIntent(IApplicationThread caller,
17678            Intent intent, String resolvedType, IIntentReceiver resultTo,
17679            int resultCode, String resultData, Bundle resultExtras,
17680            String[] requiredPermissions, int appOp, Bundle bOptions,
17681            boolean serialized, boolean sticky, int userId) {
17682        enforceNotIsolatedCaller("broadcastIntent");
17683        synchronized(this) {
17684            intent = verifyBroadcastLocked(intent);
17685
17686            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17687            final int callingPid = Binder.getCallingPid();
17688            final int callingUid = Binder.getCallingUid();
17689            final long origId = Binder.clearCallingIdentity();
17690            int res = broadcastIntentLocked(callerApp,
17691                    callerApp != null ? callerApp.info.packageName : null,
17692                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17693                    requiredPermissions, appOp, bOptions, serialized, sticky,
17694                    callingPid, callingUid, userId);
17695            Binder.restoreCallingIdentity(origId);
17696            return res;
17697        }
17698    }
17699
17700
17701    int broadcastIntentInPackage(String packageName, int uid,
17702            Intent intent, String resolvedType, IIntentReceiver resultTo,
17703            int resultCode, String resultData, Bundle resultExtras,
17704            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17705            int userId) {
17706        synchronized(this) {
17707            intent = verifyBroadcastLocked(intent);
17708
17709            final long origId = Binder.clearCallingIdentity();
17710            String[] requiredPermissions = requiredPermission == null ? null
17711                    : new String[] {requiredPermission};
17712            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17713                    resultTo, resultCode, resultData, resultExtras,
17714                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17715                    sticky, -1, uid, userId);
17716            Binder.restoreCallingIdentity(origId);
17717            return res;
17718        }
17719    }
17720
17721    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17722        // Refuse possible leaked file descriptors
17723        if (intent != null && intent.hasFileDescriptors() == true) {
17724            throw new IllegalArgumentException("File descriptors passed in Intent");
17725        }
17726
17727        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17728                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17729
17730        synchronized(this) {
17731            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17732                    != PackageManager.PERMISSION_GRANTED) {
17733                String msg = "Permission Denial: unbroadcastIntent() from pid="
17734                        + Binder.getCallingPid()
17735                        + ", uid=" + Binder.getCallingUid()
17736                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17737                Slog.w(TAG, msg);
17738                throw new SecurityException(msg);
17739            }
17740            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17741            if (stickies != null) {
17742                ArrayList<Intent> list = stickies.get(intent.getAction());
17743                if (list != null) {
17744                    int N = list.size();
17745                    int i;
17746                    for (i=0; i<N; i++) {
17747                        if (intent.filterEquals(list.get(i))) {
17748                            list.remove(i);
17749                            break;
17750                        }
17751                    }
17752                    if (list.size() <= 0) {
17753                        stickies.remove(intent.getAction());
17754                    }
17755                }
17756                if (stickies.size() <= 0) {
17757                    mStickyBroadcasts.remove(userId);
17758                }
17759            }
17760        }
17761    }
17762
17763    void backgroundServicesFinishedLocked(int userId) {
17764        for (BroadcastQueue queue : mBroadcastQueues) {
17765            queue.backgroundServicesFinishedLocked(userId);
17766        }
17767    }
17768
17769    public void finishReceiver(IBinder who, int resultCode, String resultData,
17770            Bundle resultExtras, boolean resultAbort, int flags) {
17771        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17772
17773        // Refuse possible leaked file descriptors
17774        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17775            throw new IllegalArgumentException("File descriptors passed in Bundle");
17776        }
17777
17778        final long origId = Binder.clearCallingIdentity();
17779        try {
17780            boolean doNext = false;
17781            BroadcastRecord r;
17782
17783            synchronized(this) {
17784                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17785                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17786                r = queue.getMatchingOrderedReceiver(who);
17787                if (r != null) {
17788                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17789                        resultData, resultExtras, resultAbort, true);
17790                }
17791            }
17792
17793            if (doNext) {
17794                r.queue.processNextBroadcast(false);
17795            }
17796            trimApplications();
17797        } finally {
17798            Binder.restoreCallingIdentity(origId);
17799        }
17800    }
17801
17802    // =========================================================
17803    // INSTRUMENTATION
17804    // =========================================================
17805
17806    public boolean startInstrumentation(ComponentName className,
17807            String profileFile, int flags, Bundle arguments,
17808            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17809            int userId, String abiOverride) {
17810        enforceNotIsolatedCaller("startInstrumentation");
17811        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17812                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17813        // Refuse possible leaked file descriptors
17814        if (arguments != null && arguments.hasFileDescriptors()) {
17815            throw new IllegalArgumentException("File descriptors passed in Bundle");
17816        }
17817
17818        synchronized(this) {
17819            InstrumentationInfo ii = null;
17820            ApplicationInfo ai = null;
17821            try {
17822                ii = mContext.getPackageManager().getInstrumentationInfo(
17823                    className, STOCK_PM_FLAGS);
17824                ai = AppGlobals.getPackageManager().getApplicationInfo(
17825                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17826            } catch (PackageManager.NameNotFoundException e) {
17827            } catch (RemoteException e) {
17828            }
17829            if (ii == null) {
17830                reportStartInstrumentationFailureLocked(watcher, className,
17831                        "Unable to find instrumentation info for: " + className);
17832                return false;
17833            }
17834            if (ai == null) {
17835                reportStartInstrumentationFailureLocked(watcher, className,
17836                        "Unable to find instrumentation target package: " + ii.targetPackage);
17837                return false;
17838            }
17839            if (!ai.hasCode()) {
17840                reportStartInstrumentationFailureLocked(watcher, className,
17841                        "Instrumentation target has no code: " + ii.targetPackage);
17842                return false;
17843            }
17844
17845            int match = mContext.getPackageManager().checkSignatures(
17846                    ii.targetPackage, ii.packageName);
17847            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17848                String msg = "Permission Denial: starting instrumentation "
17849                        + className + " from pid="
17850                        + Binder.getCallingPid()
17851                        + ", uid=" + Binder.getCallingPid()
17852                        + " not allowed because package " + ii.packageName
17853                        + " does not have a signature matching the target "
17854                        + ii.targetPackage;
17855                reportStartInstrumentationFailureLocked(watcher, className, msg);
17856                throw new SecurityException(msg);
17857            }
17858
17859            final long origId = Binder.clearCallingIdentity();
17860            // Instrumentation can kill and relaunch even persistent processes
17861            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17862                    "start instr");
17863            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17864            app.instrumentationClass = className;
17865            app.instrumentationInfo = ai;
17866            app.instrumentationProfileFile = profileFile;
17867            app.instrumentationArguments = arguments;
17868            app.instrumentationWatcher = watcher;
17869            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17870            app.instrumentationResultClass = className;
17871            Binder.restoreCallingIdentity(origId);
17872        }
17873
17874        return true;
17875    }
17876
17877    /**
17878     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17879     * error to the logs, but if somebody is watching, send the report there too.  This enables
17880     * the "am" command to report errors with more information.
17881     *
17882     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17883     * @param cn The component name of the instrumentation.
17884     * @param report The error report.
17885     */
17886    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17887            ComponentName cn, String report) {
17888        Slog.w(TAG, report);
17889        if (watcher != null) {
17890            Bundle results = new Bundle();
17891            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17892            results.putString("Error", report);
17893            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17894        }
17895    }
17896
17897    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17898        if (app.instrumentationWatcher != null) {
17899            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17900                    app.instrumentationClass, resultCode, results);
17901        }
17902
17903        // Can't call out of the system process with a lock held, so post a message.
17904        if (app.instrumentationUiAutomationConnection != null) {
17905            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17906                    app.instrumentationUiAutomationConnection).sendToTarget();
17907        }
17908
17909        app.instrumentationWatcher = null;
17910        app.instrumentationUiAutomationConnection = null;
17911        app.instrumentationClass = null;
17912        app.instrumentationInfo = null;
17913        app.instrumentationProfileFile = null;
17914        app.instrumentationArguments = null;
17915
17916        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17917                "finished inst");
17918    }
17919
17920    public void finishInstrumentation(IApplicationThread target,
17921            int resultCode, Bundle results) {
17922        int userId = UserHandle.getCallingUserId();
17923        // Refuse possible leaked file descriptors
17924        if (results != null && results.hasFileDescriptors()) {
17925            throw new IllegalArgumentException("File descriptors passed in Intent");
17926        }
17927
17928        synchronized(this) {
17929            ProcessRecord app = getRecordForAppLocked(target);
17930            if (app == null) {
17931                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17932                return;
17933            }
17934            final long origId = Binder.clearCallingIdentity();
17935            finishInstrumentationLocked(app, resultCode, results);
17936            Binder.restoreCallingIdentity(origId);
17937        }
17938    }
17939
17940    // =========================================================
17941    // CONFIGURATION
17942    // =========================================================
17943
17944    public ConfigurationInfo getDeviceConfigurationInfo() {
17945        ConfigurationInfo config = new ConfigurationInfo();
17946        synchronized (this) {
17947            config.reqTouchScreen = mConfiguration.touchscreen;
17948            config.reqKeyboardType = mConfiguration.keyboard;
17949            config.reqNavigation = mConfiguration.navigation;
17950            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17951                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17952                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17953            }
17954            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17955                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17956                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17957            }
17958            config.reqGlEsVersion = GL_ES_VERSION;
17959        }
17960        return config;
17961    }
17962
17963    ActivityStack getFocusedStack() {
17964        return mStackSupervisor.getFocusedStack();
17965    }
17966
17967    @Override
17968    public int getFocusedStackId() throws RemoteException {
17969        ActivityStack focusedStack = getFocusedStack();
17970        if (focusedStack != null) {
17971            return focusedStack.getStackId();
17972        }
17973        return -1;
17974    }
17975
17976    public Configuration getConfiguration() {
17977        Configuration ci;
17978        synchronized(this) {
17979            ci = new Configuration(mConfiguration);
17980            ci.userSetLocale = false;
17981        }
17982        return ci;
17983    }
17984
17985    @Override
17986    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17987        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
17988        synchronized (this) {
17989            mSuppressResizeConfigChanges = suppress;
17990        }
17991    }
17992
17993    @Override
17994    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
17995        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
17996        if (fromStackId == HOME_STACK_ID) {
17997            throw new IllegalArgumentException("You can't move tasks from the home stack.");
17998        }
17999        synchronized (this) {
18000            final long origId = Binder.clearCallingIdentity();
18001            try {
18002                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18003            } finally {
18004                Binder.restoreCallingIdentity(origId);
18005            }
18006        }
18007    }
18008
18009    @Override
18010    public void updatePersistentConfiguration(Configuration values) {
18011        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18012                "updateConfiguration()");
18013        enforceWriteSettingsPermission("updateConfiguration()");
18014        if (values == null) {
18015            throw new NullPointerException("Configuration must not be null");
18016        }
18017
18018        int userId = UserHandle.getCallingUserId();
18019
18020        synchronized(this) {
18021            final long origId = Binder.clearCallingIdentity();
18022            updateConfigurationLocked(values, null, false, true, userId);
18023            Binder.restoreCallingIdentity(origId);
18024        }
18025    }
18026
18027    private void updateFontScaleIfNeeded() {
18028        final int currentUserId;
18029        synchronized(this) {
18030            currentUserId = mUserController.getCurrentUserIdLocked();
18031        }
18032        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18033                FONT_SCALE, 1.0f, currentUserId);
18034        if (mConfiguration.fontScale != scaleFactor) {
18035            final Configuration configuration = mWindowManager.computeNewConfiguration();
18036            configuration.fontScale = scaleFactor;
18037            updatePersistentConfiguration(configuration);
18038        }
18039    }
18040
18041    private void enforceWriteSettingsPermission(String func) {
18042        int uid = Binder.getCallingUid();
18043        if (uid == Process.ROOT_UID) {
18044            return;
18045        }
18046
18047        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18048                Settings.getPackageNameForUid(mContext, uid), false)) {
18049            return;
18050        }
18051
18052        String msg = "Permission Denial: " + func + " from pid="
18053                + Binder.getCallingPid()
18054                + ", uid=" + uid
18055                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18056        Slog.w(TAG, msg);
18057        throw new SecurityException(msg);
18058    }
18059
18060    public void updateConfiguration(Configuration values) {
18061        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18062                "updateConfiguration()");
18063
18064        synchronized(this) {
18065            if (values == null && mWindowManager != null) {
18066                // sentinel: fetch the current configuration from the window manager
18067                values = mWindowManager.computeNewConfiguration();
18068            }
18069
18070            if (mWindowManager != null) {
18071                mProcessList.applyDisplaySize(mWindowManager);
18072            }
18073
18074            final long origId = Binder.clearCallingIdentity();
18075            if (values != null) {
18076                Settings.System.clearConfiguration(values);
18077            }
18078            updateConfigurationLocked(values, null, false);
18079            Binder.restoreCallingIdentity(origId);
18080        }
18081    }
18082
18083    void updateUserConfigurationLocked() {
18084        Configuration configuration = new Configuration(mConfiguration);
18085        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18086                mUserController.getCurrentUserIdLocked());
18087        updateConfigurationLocked(configuration, null, false);
18088    }
18089
18090    boolean updateConfigurationLocked(Configuration values,
18091            ActivityRecord starting, boolean initLocale) {
18092        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18093        return updateConfigurationLocked(values, starting, initLocale, false,
18094                UserHandle.USER_NULL);
18095    }
18096
18097    // To cache the list of supported system locales
18098    private String[] mSupportedSystemLocales = null;
18099
18100    /**
18101     * Do either or both things: (1) change the current configuration, and (2)
18102     * make sure the given activity is running with the (now) current
18103     * configuration.  Returns true if the activity has been left running, or
18104     * false if <var>starting</var> is being destroyed to match the new
18105     * configuration.
18106     *
18107     * @param userId is only used when persistent parameter is set to true to persist configuration
18108     *               for that particular user
18109     */
18110    private boolean updateConfigurationLocked(Configuration values,
18111            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18112        int changes = 0;
18113
18114        if (mWindowManager != null) {
18115            mWindowManager.deferSurfaceLayout();
18116        }
18117        if (values != null) {
18118            Configuration newConfig = new Configuration(mConfiguration);
18119            changes = newConfig.updateFrom(values);
18120            if (changes != 0) {
18121                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18122                        "Updating configuration to: " + values);
18123
18124                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18125
18126                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18127                    final Locale locale;
18128                    if (values.getLocales().size() == 1) {
18129                        // This is an optimization to avoid the JNI call when the result of
18130                        // getFirstMatch() does not depend on the supported locales.
18131                        locale = values.getLocales().get(0);
18132                    } else {
18133                        if (mSupportedSystemLocales == null) {
18134                            mSupportedSystemLocales =
18135                                    Resources.getSystem().getAssets().getLocales();
18136                        }
18137                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18138                    }
18139                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18140                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18141                            locale));
18142                }
18143
18144                mConfigurationSeq++;
18145                if (mConfigurationSeq <= 0) {
18146                    mConfigurationSeq = 1;
18147                }
18148                newConfig.seq = mConfigurationSeq;
18149                mConfiguration = newConfig;
18150                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18151                mUsageStatsService.reportConfigurationChange(newConfig,
18152                        mUserController.getCurrentUserIdLocked());
18153                //mUsageStatsService.noteStartConfig(newConfig);
18154
18155                final Configuration configCopy = new Configuration(mConfiguration);
18156
18157                // TODO: If our config changes, should we auto dismiss any currently
18158                // showing dialogs?
18159                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18160
18161                AttributeCache ac = AttributeCache.instance();
18162                if (ac != null) {
18163                    ac.updateConfiguration(configCopy);
18164                }
18165
18166                // Make sure all resources in our process are updated
18167                // right now, so that anyone who is going to retrieve
18168                // resource values after we return will be sure to get
18169                // the new ones.  This is especially important during
18170                // boot, where the first config change needs to guarantee
18171                // all resources have that config before following boot
18172                // code is executed.
18173                mSystemThread.applyConfigurationToResources(configCopy);
18174
18175                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18176                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18177                    msg.obj = new Configuration(configCopy);
18178                    msg.arg1 = userId;
18179                    mHandler.sendMessage(msg);
18180                }
18181
18182                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18183                if (isDensityChange) {
18184                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18185                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18186                }
18187
18188                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18189                    ProcessRecord app = mLruProcesses.get(i);
18190                    try {
18191                        if (app.thread != null) {
18192                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18193                                    + app.processName + " new config " + mConfiguration);
18194                            app.thread.scheduleConfigurationChanged(configCopy);
18195                        }
18196                    } catch (Exception e) {
18197                    }
18198                }
18199                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18200                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18201                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18202                        | Intent.FLAG_RECEIVER_FOREGROUND);
18203                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18204                        null, AppOpsManager.OP_NONE, null, false, false,
18205                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18206                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18207                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18208                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18209                    if (!mProcessesReady) {
18210                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18211                    }
18212                    broadcastIntentLocked(null, null, intent,
18213                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18214                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18215                }
18216            }
18217            // Update the configuration with WM first and check if any of the stacks need to be
18218            // resized due to the configuration change. If so, resize the stacks now and do any
18219            // relaunches if necessary. This way we don't need to relaunch again below in
18220            // ensureActivityConfigurationLocked().
18221            if (mWindowManager != null) {
18222                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18223                if (resizedStacks != null) {
18224                    for (int stackId : resizedStacks) {
18225                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18226                        mStackSupervisor.resizeStackLocked(
18227                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18228                    }
18229                }
18230            }
18231        }
18232
18233        boolean kept = true;
18234        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18235        // mainStack is null during startup.
18236        if (mainStack != null) {
18237            if (changes != 0 && starting == null) {
18238                // If the configuration changed, and the caller is not already
18239                // in the process of starting an activity, then find the top
18240                // activity to check if its configuration needs to change.
18241                starting = mainStack.topRunningActivityLocked();
18242            }
18243
18244            if (starting != null) {
18245                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18246                // And we need to make sure at this point that all other activities
18247                // are made visible with the correct configuration.
18248                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18249                        !PRESERVE_WINDOWS);
18250            }
18251        }
18252        if (mWindowManager != null) {
18253            mWindowManager.continueSurfaceLayout();
18254        }
18255        return kept;
18256    }
18257
18258    /**
18259     * Decide based on the configuration whether we should shouw the ANR,
18260     * crash, etc dialogs.  The idea is that if there is no affordnace to
18261     * press the on-screen buttons, we shouldn't show the dialog.
18262     *
18263     * A thought: SystemUI might also want to get told about this, the Power
18264     * dialog / global actions also might want different behaviors.
18265     */
18266    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18267        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18268                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18269                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18270        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18271                                    == Configuration.UI_MODE_TYPE_CAR);
18272        return inputMethodExists && uiIsNotCarType && !inVrMode;
18273    }
18274
18275    @Override
18276    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18277        synchronized (this) {
18278            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18279            if (srec != null) {
18280                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18281            }
18282        }
18283        return false;
18284    }
18285
18286    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18287            Intent resultData) {
18288
18289        synchronized (this) {
18290            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18291            if (r != null) {
18292                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18293            }
18294            return false;
18295        }
18296    }
18297
18298    public int getLaunchedFromUid(IBinder activityToken) {
18299        ActivityRecord srec;
18300        synchronized (this) {
18301            srec = ActivityRecord.forTokenLocked(activityToken);
18302        }
18303        if (srec == null) {
18304            return -1;
18305        }
18306        return srec.launchedFromUid;
18307    }
18308
18309    public String getLaunchedFromPackage(IBinder activityToken) {
18310        ActivityRecord srec;
18311        synchronized (this) {
18312            srec = ActivityRecord.forTokenLocked(activityToken);
18313        }
18314        if (srec == null) {
18315            return null;
18316        }
18317        return srec.launchedFromPackage;
18318    }
18319
18320    // =========================================================
18321    // LIFETIME MANAGEMENT
18322    // =========================================================
18323
18324    // Returns which broadcast queue the app is the current [or imminent] receiver
18325    // on, or 'null' if the app is not an active broadcast recipient.
18326    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18327        BroadcastRecord r = app.curReceiver;
18328        if (r != null) {
18329            return r.queue;
18330        }
18331
18332        // It's not the current receiver, but it might be starting up to become one
18333        synchronized (this) {
18334            for (BroadcastQueue queue : mBroadcastQueues) {
18335                r = queue.mPendingBroadcast;
18336                if (r != null && r.curApp == app) {
18337                    // found it; report which queue it's in
18338                    return queue;
18339                }
18340            }
18341        }
18342
18343        return null;
18344    }
18345
18346    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18347            int targetUid, ComponentName targetComponent, String targetProcess) {
18348        if (!mTrackingAssociations) {
18349            return null;
18350        }
18351        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18352                = mAssociations.get(targetUid);
18353        if (components == null) {
18354            components = new ArrayMap<>();
18355            mAssociations.put(targetUid, components);
18356        }
18357        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18358        if (sourceUids == null) {
18359            sourceUids = new SparseArray<>();
18360            components.put(targetComponent, sourceUids);
18361        }
18362        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18363        if (sourceProcesses == null) {
18364            sourceProcesses = new ArrayMap<>();
18365            sourceUids.put(sourceUid, sourceProcesses);
18366        }
18367        Association ass = sourceProcesses.get(sourceProcess);
18368        if (ass == null) {
18369            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18370                    targetProcess);
18371            sourceProcesses.put(sourceProcess, ass);
18372        }
18373        ass.mCount++;
18374        ass.mNesting++;
18375        if (ass.mNesting == 1) {
18376            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18377            ass.mLastState = sourceState;
18378        }
18379        return ass;
18380    }
18381
18382    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18383            ComponentName targetComponent) {
18384        if (!mTrackingAssociations) {
18385            return;
18386        }
18387        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18388                = mAssociations.get(targetUid);
18389        if (components == null) {
18390            return;
18391        }
18392        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18393        if (sourceUids == null) {
18394            return;
18395        }
18396        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18397        if (sourceProcesses == null) {
18398            return;
18399        }
18400        Association ass = sourceProcesses.get(sourceProcess);
18401        if (ass == null || ass.mNesting <= 0) {
18402            return;
18403        }
18404        ass.mNesting--;
18405        if (ass.mNesting == 0) {
18406            long uptime = SystemClock.uptimeMillis();
18407            ass.mTime += uptime - ass.mStartTime;
18408            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18409                    += uptime - ass.mLastStateUptime;
18410            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18411        }
18412    }
18413
18414    private void noteUidProcessState(final int uid, final int state) {
18415        mBatteryStatsService.noteUidProcessState(uid, state);
18416        if (mTrackingAssociations) {
18417            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18418                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18419                        = mAssociations.valueAt(i1);
18420                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18421                    SparseArray<ArrayMap<String, Association>> sourceUids
18422                            = targetComponents.valueAt(i2);
18423                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18424                    if (sourceProcesses != null) {
18425                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18426                            Association ass = sourceProcesses.valueAt(i4);
18427                            if (ass.mNesting >= 1) {
18428                                // currently associated
18429                                long uptime = SystemClock.uptimeMillis();
18430                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18431                                        += uptime - ass.mLastStateUptime;
18432                                ass.mLastState = state;
18433                                ass.mLastStateUptime = uptime;
18434                            }
18435                        }
18436                    }
18437                }
18438            }
18439        }
18440    }
18441
18442    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18443            boolean doingAll, long now) {
18444        if (mAdjSeq == app.adjSeq) {
18445            // This adjustment has already been computed.
18446            return app.curRawAdj;
18447        }
18448
18449        if (app.thread == null) {
18450            app.adjSeq = mAdjSeq;
18451            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18452            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18453            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18454        }
18455
18456        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18457        app.adjSource = null;
18458        app.adjTarget = null;
18459        app.empty = false;
18460        app.cached = false;
18461
18462        final int activitiesSize = app.activities.size();
18463
18464        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18465            // The max adjustment doesn't allow this app to be anything
18466            // below foreground, so it is not worth doing work for it.
18467            app.adjType = "fixed";
18468            app.adjSeq = mAdjSeq;
18469            app.curRawAdj = app.maxAdj;
18470            app.foregroundActivities = false;
18471            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18472            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18473            // System processes can do UI, and when they do we want to have
18474            // them trim their memory after the user leaves the UI.  To
18475            // facilitate this, here we need to determine whether or not it
18476            // is currently showing UI.
18477            app.systemNoUi = true;
18478            if (app == TOP_APP) {
18479                app.systemNoUi = false;
18480            } else if (activitiesSize > 0) {
18481                for (int j = 0; j < activitiesSize; j++) {
18482                    final ActivityRecord r = app.activities.get(j);
18483                    if (r.visible) {
18484                        app.systemNoUi = false;
18485                    }
18486                }
18487            }
18488            if (!app.systemNoUi) {
18489                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18490            }
18491            return (app.curAdj=app.maxAdj);
18492        }
18493
18494        app.systemNoUi = false;
18495
18496        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18497
18498        // Determine the importance of the process, starting with most
18499        // important to least, and assign an appropriate OOM adjustment.
18500        int adj;
18501        int schedGroup;
18502        int procState;
18503        boolean foregroundActivities = false;
18504        BroadcastQueue queue;
18505        if (app == TOP_APP) {
18506            // The last app on the list is the foreground app.
18507            adj = ProcessList.FOREGROUND_APP_ADJ;
18508            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18509            app.adjType = "top-activity";
18510            foregroundActivities = true;
18511            procState = PROCESS_STATE_CUR_TOP;
18512        } else if (app.instrumentationClass != null) {
18513            // Don't want to kill running instrumentation.
18514            adj = ProcessList.FOREGROUND_APP_ADJ;
18515            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18516            app.adjType = "instrumentation";
18517            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18518        } else if ((queue = isReceivingBroadcast(app)) != null) {
18519            // An app that is currently receiving a broadcast also
18520            // counts as being in the foreground for OOM killer purposes.
18521            // It's placed in a sched group based on the nature of the
18522            // broadcast as reflected by which queue it's active in.
18523            adj = ProcessList.FOREGROUND_APP_ADJ;
18524            schedGroup = (queue == mFgBroadcastQueue)
18525                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18526            app.adjType = "broadcast";
18527            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18528        } else if (app.executingServices.size() > 0) {
18529            // An app that is currently executing a service callback also
18530            // counts as being in the foreground.
18531            adj = ProcessList.FOREGROUND_APP_ADJ;
18532            schedGroup = app.execServicesFg ?
18533                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18534            app.adjType = "exec-service";
18535            procState = ActivityManager.PROCESS_STATE_SERVICE;
18536            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18537        } else {
18538            // As far as we know the process is empty.  We may change our mind later.
18539            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18540            // At this point we don't actually know the adjustment.  Use the cached adj
18541            // value that the caller wants us to.
18542            adj = cachedAdj;
18543            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18544            app.cached = true;
18545            app.empty = true;
18546            app.adjType = "cch-empty";
18547        }
18548
18549        // Examine all activities if not already foreground.
18550        if (!foregroundActivities && activitiesSize > 0) {
18551            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18552            for (int j = 0; j < activitiesSize; j++) {
18553                final ActivityRecord r = app.activities.get(j);
18554                if (r.app != app) {
18555                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18556                            + " instead of expected " + app);
18557                    if (r.app == null || (r.app.uid == app.uid)) {
18558                        // Only fix things up when they look sane
18559                        r.app = app;
18560                    } else {
18561                        continue;
18562                    }
18563                }
18564                if (r.visible) {
18565                    // App has a visible activity; only upgrade adjustment.
18566                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18567                        adj = ProcessList.VISIBLE_APP_ADJ;
18568                        app.adjType = "visible";
18569                    }
18570                    if (procState > PROCESS_STATE_CUR_TOP) {
18571                        procState = PROCESS_STATE_CUR_TOP;
18572                    }
18573                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18574                    app.cached = false;
18575                    app.empty = false;
18576                    foregroundActivities = true;
18577                    if (r.task != null && minLayer > 0) {
18578                        final int layer = r.task.mLayerRank;
18579                        if (layer >= 0 && minLayer > layer) {
18580                            minLayer = layer;
18581                        }
18582                    }
18583                    break;
18584                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18585                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18586                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18587                        app.adjType = "pausing";
18588                    }
18589                    if (procState > PROCESS_STATE_CUR_TOP) {
18590                        procState = PROCESS_STATE_CUR_TOP;
18591                    }
18592                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18593                    app.cached = false;
18594                    app.empty = false;
18595                    foregroundActivities = true;
18596                } else if (r.state == ActivityState.STOPPING) {
18597                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18598                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18599                        app.adjType = "stopping";
18600                    }
18601                    // For the process state, we will at this point consider the
18602                    // process to be cached.  It will be cached either as an activity
18603                    // or empty depending on whether the activity is finishing.  We do
18604                    // this so that we can treat the process as cached for purposes of
18605                    // memory trimming (determing current memory level, trim command to
18606                    // send to process) since there can be an arbitrary number of stopping
18607                    // processes and they should soon all go into the cached state.
18608                    if (!r.finishing) {
18609                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18610                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18611                        }
18612                    }
18613                    app.cached = false;
18614                    app.empty = false;
18615                    foregroundActivities = true;
18616                } else {
18617                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18618                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18619                        app.adjType = "cch-act";
18620                    }
18621                }
18622            }
18623            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18624                adj += minLayer;
18625            }
18626        }
18627
18628        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18629                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18630            if (app.foregroundServices) {
18631                // The user is aware of this app, so make it visible.
18632                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18633                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18634                app.cached = false;
18635                app.adjType = "fg-service";
18636                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18637            } else if (app.forcingToForeground != null) {
18638                // The user is aware of this app, so make it visible.
18639                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18640                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18641                app.cached = false;
18642                app.adjType = "force-fg";
18643                app.adjSource = app.forcingToForeground;
18644                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18645            }
18646        }
18647
18648        if (app == mHeavyWeightProcess) {
18649            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18650                // We don't want to kill the current heavy-weight process.
18651                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18652                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18653                app.cached = false;
18654                app.adjType = "heavy";
18655            }
18656            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18657                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18658            }
18659        }
18660
18661        if (app == mHomeProcess) {
18662            if (adj > ProcessList.HOME_APP_ADJ) {
18663                // This process is hosting what we currently consider to be the
18664                // home app, so we don't want to let it go into the background.
18665                adj = ProcessList.HOME_APP_ADJ;
18666                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18667                app.cached = false;
18668                app.adjType = "home";
18669            }
18670            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18671                procState = ActivityManager.PROCESS_STATE_HOME;
18672            }
18673        }
18674
18675        if (app == mPreviousProcess && app.activities.size() > 0) {
18676            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18677                // This was the previous process that showed UI to the user.
18678                // We want to try to keep it around more aggressively, to give
18679                // a good experience around switching between two apps.
18680                adj = ProcessList.PREVIOUS_APP_ADJ;
18681                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18682                app.cached = false;
18683                app.adjType = "previous";
18684            }
18685            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18686                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18687            }
18688        }
18689
18690        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18691                + " reason=" + app.adjType);
18692
18693        // By default, we use the computed adjustment.  It may be changed if
18694        // there are applications dependent on our services or providers, but
18695        // this gives us a baseline and makes sure we don't get into an
18696        // infinite recursion.
18697        app.adjSeq = mAdjSeq;
18698        app.curRawAdj = adj;
18699        app.hasStartedServices = false;
18700
18701        if (mBackupTarget != null && app == mBackupTarget.app) {
18702            // If possible we want to avoid killing apps while they're being backed up
18703            if (adj > ProcessList.BACKUP_APP_ADJ) {
18704                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18705                adj = ProcessList.BACKUP_APP_ADJ;
18706                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18707                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18708                }
18709                app.adjType = "backup";
18710                app.cached = false;
18711            }
18712            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18713                procState = ActivityManager.PROCESS_STATE_BACKUP;
18714            }
18715        }
18716
18717        boolean mayBeTop = false;
18718
18719        for (int is = app.services.size()-1;
18720                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18721                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18722                        || procState > ActivityManager.PROCESS_STATE_TOP);
18723                is--) {
18724            ServiceRecord s = app.services.valueAt(is);
18725            if (s.startRequested) {
18726                app.hasStartedServices = true;
18727                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18728                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18729                }
18730                if (app.hasShownUi && app != mHomeProcess) {
18731                    // If this process has shown some UI, let it immediately
18732                    // go to the LRU list because it may be pretty heavy with
18733                    // UI stuff.  We'll tag it with a label just to help
18734                    // debug and understand what is going on.
18735                    if (adj > ProcessList.SERVICE_ADJ) {
18736                        app.adjType = "cch-started-ui-services";
18737                    }
18738                } else {
18739                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18740                        // This service has seen some activity within
18741                        // recent memory, so we will keep its process ahead
18742                        // of the background processes.
18743                        if (adj > ProcessList.SERVICE_ADJ) {
18744                            adj = ProcessList.SERVICE_ADJ;
18745                            app.adjType = "started-services";
18746                            app.cached = false;
18747                        }
18748                    }
18749                    // If we have let the service slide into the background
18750                    // state, still have some text describing what it is doing
18751                    // even though the service no longer has an impact.
18752                    if (adj > ProcessList.SERVICE_ADJ) {
18753                        app.adjType = "cch-started-services";
18754                    }
18755                }
18756            }
18757            for (int conni = s.connections.size()-1;
18758                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18759                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18760                            || procState > ActivityManager.PROCESS_STATE_TOP);
18761                    conni--) {
18762                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18763                for (int i = 0;
18764                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18765                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18766                                || procState > ActivityManager.PROCESS_STATE_TOP);
18767                        i++) {
18768                    // XXX should compute this based on the max of
18769                    // all connected clients.
18770                    ConnectionRecord cr = clist.get(i);
18771                    if (cr.binding.client == app) {
18772                        // Binding to ourself is not interesting.
18773                        continue;
18774                    }
18775                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18776                        ProcessRecord client = cr.binding.client;
18777                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18778                                TOP_APP, doingAll, now);
18779                        int clientProcState = client.curProcState;
18780                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18781                            // If the other app is cached for any reason, for purposes here
18782                            // we are going to consider it empty.  The specific cached state
18783                            // doesn't propagate except under certain conditions.
18784                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18785                        }
18786                        String adjType = null;
18787                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18788                            // Not doing bind OOM management, so treat
18789                            // this guy more like a started service.
18790                            if (app.hasShownUi && app != mHomeProcess) {
18791                                // If this process has shown some UI, let it immediately
18792                                // go to the LRU list because it may be pretty heavy with
18793                                // UI stuff.  We'll tag it with a label just to help
18794                                // debug and understand what is going on.
18795                                if (adj > clientAdj) {
18796                                    adjType = "cch-bound-ui-services";
18797                                }
18798                                app.cached = false;
18799                                clientAdj = adj;
18800                                clientProcState = procState;
18801                            } else {
18802                                if (now >= (s.lastActivity
18803                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18804                                    // This service has not seen activity within
18805                                    // recent memory, so allow it to drop to the
18806                                    // LRU list if there is no other reason to keep
18807                                    // it around.  We'll also tag it with a label just
18808                                    // to help debug and undertand what is going on.
18809                                    if (adj > clientAdj) {
18810                                        adjType = "cch-bound-services";
18811                                    }
18812                                    clientAdj = adj;
18813                                }
18814                            }
18815                        }
18816                        if (adj > clientAdj) {
18817                            // If this process has recently shown UI, and
18818                            // the process that is binding to it is less
18819                            // important than being visible, then we don't
18820                            // care about the binding as much as we care
18821                            // about letting this process get into the LRU
18822                            // list to be killed and restarted if needed for
18823                            // memory.
18824                            if (app.hasShownUi && app != mHomeProcess
18825                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18826                                adjType = "cch-bound-ui-services";
18827                            } else {
18828                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18829                                        |Context.BIND_IMPORTANT)) != 0) {
18830                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18831                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18832                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18833                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18834                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18835                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18836                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18837                                    adj = clientAdj;
18838                                } else {
18839                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18840                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18841                                    }
18842                                }
18843                                if (!client.cached) {
18844                                    app.cached = false;
18845                                }
18846                                adjType = "service";
18847                            }
18848                        }
18849                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18850                            // This will treat important bound services identically to
18851                            // the top app, which may behave differently than generic
18852                            // foreground work.
18853                            if (client.curSchedGroup > schedGroup) {
18854                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18855                                    schedGroup = client.curSchedGroup;
18856                                } else {
18857                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18858                                }
18859                            }
18860                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18861                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18862                                    // Special handling of clients who are in the top state.
18863                                    // We *may* want to consider this process to be in the
18864                                    // top state as well, but only if there is not another
18865                                    // reason for it to be running.  Being on the top is a
18866                                    // special state, meaning you are specifically running
18867                                    // for the current top app.  If the process is already
18868                                    // running in the background for some other reason, it
18869                                    // is more important to continue considering it to be
18870                                    // in the background state.
18871                                    mayBeTop = true;
18872                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18873                                } else {
18874                                    // Special handling for above-top states (persistent
18875                                    // processes).  These should not bring the current process
18876                                    // into the top state, since they are not on top.  Instead
18877                                    // give them the best state after that.
18878                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18879                                        clientProcState =
18880                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18881                                    } else if (mWakefulness
18882                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18883                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18884                                                    != 0) {
18885                                        clientProcState =
18886                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18887                                    } else {
18888                                        clientProcState =
18889                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18890                                    }
18891                                }
18892                            }
18893                        } else {
18894                            if (clientProcState <
18895                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18896                                clientProcState =
18897                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18898                            }
18899                        }
18900                        if (procState > clientProcState) {
18901                            procState = clientProcState;
18902                        }
18903                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18904                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18905                            app.pendingUiClean = true;
18906                        }
18907                        if (adjType != null) {
18908                            app.adjType = adjType;
18909                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18910                                    .REASON_SERVICE_IN_USE;
18911                            app.adjSource = cr.binding.client;
18912                            app.adjSourceProcState = clientProcState;
18913                            app.adjTarget = s.name;
18914                        }
18915                    }
18916                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18917                        app.treatLikeActivity = true;
18918                    }
18919                    final ActivityRecord a = cr.activity;
18920                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18921                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18922                            (a.visible || a.state == ActivityState.RESUMED ||
18923                             a.state == ActivityState.PAUSING)) {
18924                            adj = ProcessList.FOREGROUND_APP_ADJ;
18925                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18926                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18927                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18928                                } else {
18929                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18930                                }
18931                            }
18932                            app.cached = false;
18933                            app.adjType = "service";
18934                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18935                                    .REASON_SERVICE_IN_USE;
18936                            app.adjSource = a;
18937                            app.adjSourceProcState = procState;
18938                            app.adjTarget = s.name;
18939                        }
18940                    }
18941                }
18942            }
18943        }
18944
18945        for (int provi = app.pubProviders.size()-1;
18946                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18947                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18948                        || procState > ActivityManager.PROCESS_STATE_TOP);
18949                provi--) {
18950            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18951            for (int i = cpr.connections.size()-1;
18952                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18953                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18954                            || procState > ActivityManager.PROCESS_STATE_TOP);
18955                    i--) {
18956                ContentProviderConnection conn = cpr.connections.get(i);
18957                ProcessRecord client = conn.client;
18958                if (client == app) {
18959                    // Being our own client is not interesting.
18960                    continue;
18961                }
18962                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18963                int clientProcState = client.curProcState;
18964                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18965                    // If the other app is cached for any reason, for purposes here
18966                    // we are going to consider it empty.
18967                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18968                }
18969                if (adj > clientAdj) {
18970                    if (app.hasShownUi && app != mHomeProcess
18971                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18972                        app.adjType = "cch-ui-provider";
18973                    } else {
18974                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18975                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18976                        app.adjType = "provider";
18977                    }
18978                    app.cached &= client.cached;
18979                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18980                            .REASON_PROVIDER_IN_USE;
18981                    app.adjSource = client;
18982                    app.adjSourceProcState = clientProcState;
18983                    app.adjTarget = cpr.name;
18984                }
18985                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18986                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18987                        // Special handling of clients who are in the top state.
18988                        // We *may* want to consider this process to be in the
18989                        // top state as well, but only if there is not another
18990                        // reason for it to be running.  Being on the top is a
18991                        // special state, meaning you are specifically running
18992                        // for the current top app.  If the process is already
18993                        // running in the background for some other reason, it
18994                        // is more important to continue considering it to be
18995                        // in the background state.
18996                        mayBeTop = true;
18997                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18998                    } else {
18999                        // Special handling for above-top states (persistent
19000                        // processes).  These should not bring the current process
19001                        // into the top state, since they are not on top.  Instead
19002                        // give them the best state after that.
19003                        clientProcState =
19004                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19005                    }
19006                }
19007                if (procState > clientProcState) {
19008                    procState = clientProcState;
19009                }
19010                if (client.curSchedGroup > schedGroup) {
19011                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19012                }
19013            }
19014            // If the provider has external (non-framework) process
19015            // dependencies, ensure that its adjustment is at least
19016            // FOREGROUND_APP_ADJ.
19017            if (cpr.hasExternalProcessHandles()) {
19018                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19019                    adj = ProcessList.FOREGROUND_APP_ADJ;
19020                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19021                    app.cached = false;
19022                    app.adjType = "provider";
19023                    app.adjTarget = cpr.name;
19024                }
19025                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19026                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19027                }
19028            }
19029        }
19030
19031        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19032            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19033                adj = ProcessList.PREVIOUS_APP_ADJ;
19034                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19035                app.cached = false;
19036                app.adjType = "provider";
19037            }
19038            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19039                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19040            }
19041        }
19042
19043        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19044            // A client of one of our services or providers is in the top state.  We
19045            // *may* want to be in the top state, but not if we are already running in
19046            // the background for some other reason.  For the decision here, we are going
19047            // to pick out a few specific states that we want to remain in when a client
19048            // is top (states that tend to be longer-term) and otherwise allow it to go
19049            // to the top state.
19050            switch (procState) {
19051                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19052                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19053                case ActivityManager.PROCESS_STATE_SERVICE:
19054                    // These all are longer-term states, so pull them up to the top
19055                    // of the background states, but not all the way to the top state.
19056                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19057                    break;
19058                default:
19059                    // Otherwise, top is a better choice, so take it.
19060                    procState = ActivityManager.PROCESS_STATE_TOP;
19061                    break;
19062            }
19063        }
19064
19065        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19066            if (app.hasClientActivities) {
19067                // This is a cached process, but with client activities.  Mark it so.
19068                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19069                app.adjType = "cch-client-act";
19070            } else if (app.treatLikeActivity) {
19071                // This is a cached process, but somebody wants us to treat it like it has
19072                // an activity, okay!
19073                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19074                app.adjType = "cch-as-act";
19075            }
19076        }
19077
19078        if (adj == ProcessList.SERVICE_ADJ) {
19079            if (doingAll) {
19080                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19081                mNewNumServiceProcs++;
19082                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19083                if (!app.serviceb) {
19084                    // This service isn't far enough down on the LRU list to
19085                    // normally be a B service, but if we are low on RAM and it
19086                    // is large we want to force it down since we would prefer to
19087                    // keep launcher over it.
19088                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19089                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19090                        app.serviceHighRam = true;
19091                        app.serviceb = true;
19092                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19093                    } else {
19094                        mNewNumAServiceProcs++;
19095                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19096                    }
19097                } else {
19098                    app.serviceHighRam = false;
19099                }
19100            }
19101            if (app.serviceb) {
19102                adj = ProcessList.SERVICE_B_ADJ;
19103            }
19104        }
19105
19106        app.curRawAdj = adj;
19107
19108        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19109        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19110        if (adj > app.maxAdj) {
19111            adj = app.maxAdj;
19112            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19113                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19114            }
19115        }
19116
19117        // Do final modification to adj.  Everything we do between here and applying
19118        // the final setAdj must be done in this function, because we will also use
19119        // it when computing the final cached adj later.  Note that we don't need to
19120        // worry about this for max adj above, since max adj will always be used to
19121        // keep it out of the cached vaues.
19122        app.curAdj = app.modifyRawOomAdj(adj);
19123        app.curSchedGroup = schedGroup;
19124        app.curProcState = procState;
19125        app.foregroundActivities = foregroundActivities;
19126
19127        return app.curRawAdj;
19128    }
19129
19130    /**
19131     * Record new PSS sample for a process.
19132     */
19133    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19134            long now) {
19135        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19136                swapPss * 1024);
19137        proc.lastPssTime = now;
19138        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19139        if (DEBUG_PSS) Slog.d(TAG_PSS,
19140                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19141                + " state=" + ProcessList.makeProcStateString(procState));
19142        if (proc.initialIdlePss == 0) {
19143            proc.initialIdlePss = pss;
19144        }
19145        proc.lastPss = pss;
19146        proc.lastSwapPss = swapPss;
19147        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19148            proc.lastCachedPss = pss;
19149            proc.lastCachedSwapPss = swapPss;
19150        }
19151
19152        final SparseArray<Pair<Long, String>> watchUids
19153                = mMemWatchProcesses.getMap().get(proc.processName);
19154        Long check = null;
19155        if (watchUids != null) {
19156            Pair<Long, String> val = watchUids.get(proc.uid);
19157            if (val == null) {
19158                val = watchUids.get(0);
19159            }
19160            if (val != null) {
19161                check = val.first;
19162            }
19163        }
19164        if (check != null) {
19165            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19166                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19167                if (!isDebuggable) {
19168                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19169                        isDebuggable = true;
19170                    }
19171                }
19172                if (isDebuggable) {
19173                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19174                    final ProcessRecord myProc = proc;
19175                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19176                    mMemWatchDumpProcName = proc.processName;
19177                    mMemWatchDumpFile = heapdumpFile.toString();
19178                    mMemWatchDumpPid = proc.pid;
19179                    mMemWatchDumpUid = proc.uid;
19180                    BackgroundThread.getHandler().post(new Runnable() {
19181                        @Override
19182                        public void run() {
19183                            revokeUriPermission(ActivityThread.currentActivityThread()
19184                                            .getApplicationThread(),
19185                                    DumpHeapActivity.JAVA_URI,
19186                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19187                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19188                                    UserHandle.myUserId());
19189                            ParcelFileDescriptor fd = null;
19190                            try {
19191                                heapdumpFile.delete();
19192                                fd = ParcelFileDescriptor.open(heapdumpFile,
19193                                        ParcelFileDescriptor.MODE_CREATE |
19194                                                ParcelFileDescriptor.MODE_TRUNCATE |
19195                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19196                                                ParcelFileDescriptor.MODE_APPEND);
19197                                IApplicationThread thread = myProc.thread;
19198                                if (thread != null) {
19199                                    try {
19200                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19201                                                "Requesting dump heap from "
19202                                                + myProc + " to " + heapdumpFile);
19203                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19204                                    } catch (RemoteException e) {
19205                                    }
19206                                }
19207                            } catch (FileNotFoundException e) {
19208                                e.printStackTrace();
19209                            } finally {
19210                                if (fd != null) {
19211                                    try {
19212                                        fd.close();
19213                                    } catch (IOException e) {
19214                                    }
19215                                }
19216                            }
19217                        }
19218                    });
19219                } else {
19220                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19221                            + ", but debugging not enabled");
19222                }
19223            }
19224        }
19225    }
19226
19227    /**
19228     * Schedule PSS collection of a process.
19229     */
19230    void requestPssLocked(ProcessRecord proc, int procState) {
19231        if (mPendingPssProcesses.contains(proc)) {
19232            return;
19233        }
19234        if (mPendingPssProcesses.size() == 0) {
19235            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19236        }
19237        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19238        proc.pssProcState = procState;
19239        mPendingPssProcesses.add(proc);
19240    }
19241
19242    /**
19243     * Schedule PSS collection of all processes.
19244     */
19245    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19246        if (!always) {
19247            if (now < (mLastFullPssTime +
19248                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19249                return;
19250            }
19251        }
19252        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19253        mLastFullPssTime = now;
19254        mFullPssPending = true;
19255        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19256        mPendingPssProcesses.clear();
19257        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19258            ProcessRecord app = mLruProcesses.get(i);
19259            if (app.thread == null
19260                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19261                continue;
19262            }
19263            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19264                app.pssProcState = app.setProcState;
19265                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19266                        mTestPssMode, isSleeping(), now);
19267                mPendingPssProcesses.add(app);
19268            }
19269        }
19270        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19271    }
19272
19273    public void setTestPssMode(boolean enabled) {
19274        synchronized (this) {
19275            mTestPssMode = enabled;
19276            if (enabled) {
19277                // Whenever we enable the mode, we want to take a snapshot all of current
19278                // process mem use.
19279                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19280            }
19281        }
19282    }
19283
19284    /**
19285     * Ask a given process to GC right now.
19286     */
19287    final void performAppGcLocked(ProcessRecord app) {
19288        try {
19289            app.lastRequestedGc = SystemClock.uptimeMillis();
19290            if (app.thread != null) {
19291                if (app.reportLowMemory) {
19292                    app.reportLowMemory = false;
19293                    app.thread.scheduleLowMemory();
19294                } else {
19295                    app.thread.processInBackground();
19296                }
19297            }
19298        } catch (Exception e) {
19299            // whatever.
19300        }
19301    }
19302
19303    /**
19304     * Returns true if things are idle enough to perform GCs.
19305     */
19306    private final boolean canGcNowLocked() {
19307        boolean processingBroadcasts = false;
19308        for (BroadcastQueue q : mBroadcastQueues) {
19309            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19310                processingBroadcasts = true;
19311            }
19312        }
19313        return !processingBroadcasts
19314                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19315    }
19316
19317    /**
19318     * Perform GCs on all processes that are waiting for it, but only
19319     * if things are idle.
19320     */
19321    final void performAppGcsLocked() {
19322        final int N = mProcessesToGc.size();
19323        if (N <= 0) {
19324            return;
19325        }
19326        if (canGcNowLocked()) {
19327            while (mProcessesToGc.size() > 0) {
19328                ProcessRecord proc = mProcessesToGc.remove(0);
19329                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19330                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19331                            <= SystemClock.uptimeMillis()) {
19332                        // To avoid spamming the system, we will GC processes one
19333                        // at a time, waiting a few seconds between each.
19334                        performAppGcLocked(proc);
19335                        scheduleAppGcsLocked();
19336                        return;
19337                    } else {
19338                        // It hasn't been long enough since we last GCed this
19339                        // process...  put it in the list to wait for its time.
19340                        addProcessToGcListLocked(proc);
19341                        break;
19342                    }
19343                }
19344            }
19345
19346            scheduleAppGcsLocked();
19347        }
19348    }
19349
19350    /**
19351     * If all looks good, perform GCs on all processes waiting for them.
19352     */
19353    final void performAppGcsIfAppropriateLocked() {
19354        if (canGcNowLocked()) {
19355            performAppGcsLocked();
19356            return;
19357        }
19358        // Still not idle, wait some more.
19359        scheduleAppGcsLocked();
19360    }
19361
19362    /**
19363     * Schedule the execution of all pending app GCs.
19364     */
19365    final void scheduleAppGcsLocked() {
19366        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19367
19368        if (mProcessesToGc.size() > 0) {
19369            // Schedule a GC for the time to the next process.
19370            ProcessRecord proc = mProcessesToGc.get(0);
19371            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19372
19373            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19374            long now = SystemClock.uptimeMillis();
19375            if (when < (now+GC_TIMEOUT)) {
19376                when = now + GC_TIMEOUT;
19377            }
19378            mHandler.sendMessageAtTime(msg, when);
19379        }
19380    }
19381
19382    /**
19383     * Add a process to the array of processes waiting to be GCed.  Keeps the
19384     * list in sorted order by the last GC time.  The process can't already be
19385     * on the list.
19386     */
19387    final void addProcessToGcListLocked(ProcessRecord proc) {
19388        boolean added = false;
19389        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19390            if (mProcessesToGc.get(i).lastRequestedGc <
19391                    proc.lastRequestedGc) {
19392                added = true;
19393                mProcessesToGc.add(i+1, proc);
19394                break;
19395            }
19396        }
19397        if (!added) {
19398            mProcessesToGc.add(0, proc);
19399        }
19400    }
19401
19402    /**
19403     * Set up to ask a process to GC itself.  This will either do it
19404     * immediately, or put it on the list of processes to gc the next
19405     * time things are idle.
19406     */
19407    final void scheduleAppGcLocked(ProcessRecord app) {
19408        long now = SystemClock.uptimeMillis();
19409        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19410            return;
19411        }
19412        if (!mProcessesToGc.contains(app)) {
19413            addProcessToGcListLocked(app);
19414            scheduleAppGcsLocked();
19415        }
19416    }
19417
19418    final void checkExcessivePowerUsageLocked(boolean doKills) {
19419        updateCpuStatsNow();
19420
19421        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19422        boolean doWakeKills = doKills;
19423        boolean doCpuKills = doKills;
19424        if (mLastPowerCheckRealtime == 0) {
19425            doWakeKills = false;
19426        }
19427        if (mLastPowerCheckUptime == 0) {
19428            doCpuKills = false;
19429        }
19430        if (stats.isScreenOn()) {
19431            doWakeKills = false;
19432        }
19433        final long curRealtime = SystemClock.elapsedRealtime();
19434        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19435        final long curUptime = SystemClock.uptimeMillis();
19436        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19437        mLastPowerCheckRealtime = curRealtime;
19438        mLastPowerCheckUptime = curUptime;
19439        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19440            doWakeKills = false;
19441        }
19442        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19443            doCpuKills = false;
19444        }
19445        int i = mLruProcesses.size();
19446        while (i > 0) {
19447            i--;
19448            ProcessRecord app = mLruProcesses.get(i);
19449            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19450                long wtime;
19451                synchronized (stats) {
19452                    wtime = stats.getProcessWakeTime(app.info.uid,
19453                            app.pid, curRealtime);
19454                }
19455                long wtimeUsed = wtime - app.lastWakeTime;
19456                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19457                if (DEBUG_POWER) {
19458                    StringBuilder sb = new StringBuilder(128);
19459                    sb.append("Wake for ");
19460                    app.toShortString(sb);
19461                    sb.append(": over ");
19462                    TimeUtils.formatDuration(realtimeSince, sb);
19463                    sb.append(" used ");
19464                    TimeUtils.formatDuration(wtimeUsed, sb);
19465                    sb.append(" (");
19466                    sb.append((wtimeUsed*100)/realtimeSince);
19467                    sb.append("%)");
19468                    Slog.i(TAG_POWER, sb.toString());
19469                    sb.setLength(0);
19470                    sb.append("CPU for ");
19471                    app.toShortString(sb);
19472                    sb.append(": over ");
19473                    TimeUtils.formatDuration(uptimeSince, sb);
19474                    sb.append(" used ");
19475                    TimeUtils.formatDuration(cputimeUsed, sb);
19476                    sb.append(" (");
19477                    sb.append((cputimeUsed*100)/uptimeSince);
19478                    sb.append("%)");
19479                    Slog.i(TAG_POWER, sb.toString());
19480                }
19481                // If a process has held a wake lock for more
19482                // than 50% of the time during this period,
19483                // that sounds bad.  Kill!
19484                if (doWakeKills && realtimeSince > 0
19485                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19486                    synchronized (stats) {
19487                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19488                                realtimeSince, wtimeUsed);
19489                    }
19490                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19491                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19492                } else if (doCpuKills && uptimeSince > 0
19493                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19494                    synchronized (stats) {
19495                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19496                                uptimeSince, cputimeUsed);
19497                    }
19498                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19499                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19500                } else {
19501                    app.lastWakeTime = wtime;
19502                    app.lastCpuTime = app.curCpuTime;
19503                }
19504            }
19505        }
19506    }
19507
19508    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19509            long nowElapsed) {
19510        boolean success = true;
19511
19512        if (app.curRawAdj != app.setRawAdj) {
19513            app.setRawAdj = app.curRawAdj;
19514        }
19515
19516        int changes = 0;
19517
19518        if (app.curAdj != app.setAdj) {
19519            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19520            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19521                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19522                    + app.adjType);
19523            app.setAdj = app.curAdj;
19524        }
19525
19526        if (app.setSchedGroup != app.curSchedGroup) {
19527            app.setSchedGroup = app.curSchedGroup;
19528            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19529                    "Setting sched group of " + app.processName
19530                    + " to " + app.curSchedGroup);
19531            if (app.waitingToKill != null && app.curReceiver == null
19532                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19533                app.kill(app.waitingToKill, true);
19534                success = false;
19535            } else {
19536                int processGroup;
19537                switch (app.curSchedGroup) {
19538                    case ProcessList.SCHED_GROUP_BACKGROUND:
19539                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19540                        break;
19541                    case ProcessList.SCHED_GROUP_TOP_APP:
19542                        processGroup = Process.THREAD_GROUP_TOP_APP;
19543                        break;
19544                    default:
19545                        processGroup = Process.THREAD_GROUP_DEFAULT;
19546                        break;
19547                }
19548                if (true) {
19549                    long oldId = Binder.clearCallingIdentity();
19550                    try {
19551                        Process.setProcessGroup(app.pid, processGroup);
19552                    } catch (Exception e) {
19553                        Slog.w(TAG, "Failed setting process group of " + app.pid
19554                                + " to " + app.curSchedGroup);
19555                        e.printStackTrace();
19556                    } finally {
19557                        Binder.restoreCallingIdentity(oldId);
19558                    }
19559                } else {
19560                    if (app.thread != null) {
19561                        try {
19562                            app.thread.setSchedulingGroup(processGroup);
19563                        } catch (RemoteException e) {
19564                        }
19565                    }
19566                }
19567            }
19568        }
19569        if (app.repForegroundActivities != app.foregroundActivities) {
19570            app.repForegroundActivities = app.foregroundActivities;
19571            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19572        }
19573        if (app.repProcState != app.curProcState) {
19574            app.repProcState = app.curProcState;
19575            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19576            if (app.thread != null) {
19577                try {
19578                    if (false) {
19579                        //RuntimeException h = new RuntimeException("here");
19580                        Slog.i(TAG, "Sending new process state " + app.repProcState
19581                                + " to " + app /*, h*/);
19582                    }
19583                    app.thread.setProcessState(app.repProcState);
19584                } catch (RemoteException e) {
19585                }
19586            }
19587        }
19588        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19589                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19590            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19591                // Experimental code to more aggressively collect pss while
19592                // running test...  the problem is that this tends to collect
19593                // the data right when a process is transitioning between process
19594                // states, which well tend to give noisy data.
19595                long start = SystemClock.uptimeMillis();
19596                long pss = Debug.getPss(app.pid, mTmpLong, null);
19597                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19598                mPendingPssProcesses.remove(app);
19599                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19600                        + " to " + app.curProcState + ": "
19601                        + (SystemClock.uptimeMillis()-start) + "ms");
19602            }
19603            app.lastStateTime = now;
19604            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19605                    mTestPssMode, isSleeping(), now);
19606            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19607                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19608                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19609                    + (app.nextPssTime-now) + ": " + app);
19610        } else {
19611            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19612                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19613                    mTestPssMode)))) {
19614                requestPssLocked(app, app.setProcState);
19615                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19616                        mTestPssMode, isSleeping(), now);
19617            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19618                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19619        }
19620        if (app.setProcState != app.curProcState) {
19621            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19622                    "Proc state change of " + app.processName
19623                            + " to " + app.curProcState);
19624            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19625            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19626            if (setImportant && !curImportant) {
19627                // This app is no longer something we consider important enough to allow to
19628                // use arbitrary amounts of battery power.  Note
19629                // its current wake lock time to later know to kill it if
19630                // it is not behaving well.
19631                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19632                synchronized (stats) {
19633                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19634                            app.pid, nowElapsed);
19635                }
19636                app.lastCpuTime = app.curCpuTime;
19637
19638            }
19639            // Inform UsageStats of important process state change
19640            // Must be called before updating setProcState
19641            maybeUpdateUsageStatsLocked(app, nowElapsed);
19642
19643            app.setProcState = app.curProcState;
19644            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19645                app.notCachedSinceIdle = false;
19646            }
19647            if (!doingAll) {
19648                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19649            } else {
19650                app.procStateChanged = true;
19651            }
19652        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19653                > USAGE_STATS_INTERACTION_INTERVAL) {
19654            // For apps that sit around for a long time in the interactive state, we need
19655            // to report this at least once a day so they don't go idle.
19656            maybeUpdateUsageStatsLocked(app, nowElapsed);
19657        }
19658
19659        if (changes != 0) {
19660            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19661                    "Changes in " + app + ": " + changes);
19662            int i = mPendingProcessChanges.size()-1;
19663            ProcessChangeItem item = null;
19664            while (i >= 0) {
19665                item = mPendingProcessChanges.get(i);
19666                if (item.pid == app.pid) {
19667                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19668                            "Re-using existing item: " + item);
19669                    break;
19670                }
19671                i--;
19672            }
19673            if (i < 0) {
19674                // No existing item in pending changes; need a new one.
19675                final int NA = mAvailProcessChanges.size();
19676                if (NA > 0) {
19677                    item = mAvailProcessChanges.remove(NA-1);
19678                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19679                            "Retrieving available item: " + item);
19680                } else {
19681                    item = new ProcessChangeItem();
19682                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19683                            "Allocating new item: " + item);
19684                }
19685                item.changes = 0;
19686                item.pid = app.pid;
19687                item.uid = app.info.uid;
19688                if (mPendingProcessChanges.size() == 0) {
19689                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19690                            "*** Enqueueing dispatch processes changed!");
19691                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19692                }
19693                mPendingProcessChanges.add(item);
19694            }
19695            item.changes |= changes;
19696            item.processState = app.repProcState;
19697            item.foregroundActivities = app.repForegroundActivities;
19698            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19699                    "Item " + Integer.toHexString(System.identityHashCode(item))
19700                    + " " + app.toShortString() + ": changes=" + item.changes
19701                    + " procState=" + item.processState
19702                    + " foreground=" + item.foregroundActivities
19703                    + " type=" + app.adjType + " source=" + app.adjSource
19704                    + " target=" + app.adjTarget);
19705        }
19706
19707        return success;
19708    }
19709
19710    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19711        final UidRecord.ChangeItem pendingChange;
19712        if (uidRec == null || uidRec.pendingChange == null) {
19713            if (mPendingUidChanges.size() == 0) {
19714                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19715                        "*** Enqueueing dispatch uid changed!");
19716                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19717            }
19718            final int NA = mAvailUidChanges.size();
19719            if (NA > 0) {
19720                pendingChange = mAvailUidChanges.remove(NA-1);
19721                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19722                        "Retrieving available item: " + pendingChange);
19723            } else {
19724                pendingChange = new UidRecord.ChangeItem();
19725                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19726                        "Allocating new item: " + pendingChange);
19727            }
19728            if (uidRec != null) {
19729                uidRec.pendingChange = pendingChange;
19730                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19731                    // If this uid is going away, and we haven't yet reported it is gone,
19732                    // then do so now.
19733                    change = UidRecord.CHANGE_GONE_IDLE;
19734                }
19735            } else if (uid < 0) {
19736                throw new IllegalArgumentException("No UidRecord or uid");
19737            }
19738            pendingChange.uidRecord = uidRec;
19739            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19740            mPendingUidChanges.add(pendingChange);
19741        } else {
19742            pendingChange = uidRec.pendingChange;
19743            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19744                change = UidRecord.CHANGE_GONE_IDLE;
19745            }
19746        }
19747        pendingChange.change = change;
19748        pendingChange.processState = uidRec != null
19749                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19750    }
19751
19752    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19753            String authority) {
19754        if (app == null) return;
19755        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19756            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19757            if (userState == null) return;
19758            final long now = SystemClock.elapsedRealtime();
19759            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19760            if (lastReported == null || lastReported < now - 60 * 1000L) {
19761                mUsageStatsService.reportContentProviderUsage(
19762                        authority, providerPkgName, app.userId);
19763                userState.mProviderLastReportedFg.put(authority, now);
19764            }
19765        }
19766    }
19767
19768    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19769        if (DEBUG_USAGE_STATS) {
19770            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19771                    + "] state changes: old = " + app.setProcState + ", new = "
19772                    + app.curProcState);
19773        }
19774        if (mUsageStatsService == null) {
19775            return;
19776        }
19777        boolean isInteraction;
19778        // To avoid some abuse patterns, we are going to be careful about what we consider
19779        // to be an app interaction.  Being the top activity doesn't count while the display
19780        // is sleeping, nor do short foreground services.
19781        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19782            isInteraction = true;
19783            app.fgInteractionTime = 0;
19784        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19785            if (app.fgInteractionTime == 0) {
19786                app.fgInteractionTime = nowElapsed;
19787                isInteraction = false;
19788            } else {
19789                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19790            }
19791        } else {
19792            isInteraction = app.curProcState
19793                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19794            app.fgInteractionTime = 0;
19795        }
19796        if (isInteraction && (!app.reportedInteraction
19797                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19798            app.interactionEventTime = nowElapsed;
19799            String[] packages = app.getPackageList();
19800            if (packages != null) {
19801                for (int i = 0; i < packages.length; i++) {
19802                    mUsageStatsService.reportEvent(packages[i], app.userId,
19803                            UsageEvents.Event.SYSTEM_INTERACTION);
19804                }
19805            }
19806        }
19807        app.reportedInteraction = isInteraction;
19808        if (!isInteraction) {
19809            app.interactionEventTime = 0;
19810        }
19811    }
19812
19813    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19814        if (proc.thread != null) {
19815            if (proc.baseProcessTracker != null) {
19816                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19817            }
19818        }
19819    }
19820
19821    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19822            ProcessRecord TOP_APP, boolean doingAll, long now) {
19823        if (app.thread == null) {
19824            return false;
19825        }
19826
19827        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19828
19829        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19830    }
19831
19832    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19833            boolean oomAdj) {
19834        if (isForeground != proc.foregroundServices) {
19835            proc.foregroundServices = isForeground;
19836            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19837                    proc.info.uid);
19838            if (isForeground) {
19839                if (curProcs == null) {
19840                    curProcs = new ArrayList<ProcessRecord>();
19841                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19842                }
19843                if (!curProcs.contains(proc)) {
19844                    curProcs.add(proc);
19845                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19846                            proc.info.packageName, proc.info.uid);
19847                }
19848            } else {
19849                if (curProcs != null) {
19850                    if (curProcs.remove(proc)) {
19851                        mBatteryStatsService.noteEvent(
19852                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19853                                proc.info.packageName, proc.info.uid);
19854                        if (curProcs.size() <= 0) {
19855                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19856                        }
19857                    }
19858                }
19859            }
19860            if (oomAdj) {
19861                updateOomAdjLocked();
19862            }
19863        }
19864    }
19865
19866    private final ActivityRecord resumedAppLocked() {
19867        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19868        String pkg;
19869        int uid;
19870        if (act != null) {
19871            pkg = act.packageName;
19872            uid = act.info.applicationInfo.uid;
19873        } else {
19874            pkg = null;
19875            uid = -1;
19876        }
19877        // Has the UID or resumed package name changed?
19878        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19879                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19880            if (mCurResumedPackage != null) {
19881                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19882                        mCurResumedPackage, mCurResumedUid);
19883            }
19884            mCurResumedPackage = pkg;
19885            mCurResumedUid = uid;
19886            if (mCurResumedPackage != null) {
19887                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19888                        mCurResumedPackage, mCurResumedUid);
19889            }
19890        }
19891        return act;
19892    }
19893
19894    final boolean updateOomAdjLocked(ProcessRecord app) {
19895        final ActivityRecord TOP_ACT = resumedAppLocked();
19896        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19897        final boolean wasCached = app.cached;
19898
19899        mAdjSeq++;
19900
19901        // This is the desired cached adjusment we want to tell it to use.
19902        // If our app is currently cached, we know it, and that is it.  Otherwise,
19903        // we don't know it yet, and it needs to now be cached we will then
19904        // need to do a complete oom adj.
19905        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19906                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19907        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19908                SystemClock.uptimeMillis());
19909        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19910            // Changed to/from cached state, so apps after it in the LRU
19911            // list may also be changed.
19912            updateOomAdjLocked();
19913        }
19914        return success;
19915    }
19916
19917    final void updateOomAdjLocked() {
19918        final ActivityRecord TOP_ACT = resumedAppLocked();
19919        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19920        final long now = SystemClock.uptimeMillis();
19921        final long nowElapsed = SystemClock.elapsedRealtime();
19922        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19923        final int N = mLruProcesses.size();
19924
19925        if (false) {
19926            RuntimeException e = new RuntimeException();
19927            e.fillInStackTrace();
19928            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19929        }
19930
19931        // Reset state in all uid records.
19932        for (int i=mActiveUids.size()-1; i>=0; i--) {
19933            final UidRecord uidRec = mActiveUids.valueAt(i);
19934            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19935                    "Starting update of " + uidRec);
19936            uidRec.reset();
19937        }
19938
19939        mStackSupervisor.rankTaskLayersIfNeeded();
19940
19941        mAdjSeq++;
19942        mNewNumServiceProcs = 0;
19943        mNewNumAServiceProcs = 0;
19944
19945        final int emptyProcessLimit;
19946        final int cachedProcessLimit;
19947        if (mProcessLimit <= 0) {
19948            emptyProcessLimit = cachedProcessLimit = 0;
19949        } else if (mProcessLimit == 1) {
19950            emptyProcessLimit = 1;
19951            cachedProcessLimit = 0;
19952        } else {
19953            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19954            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19955        }
19956
19957        // Let's determine how many processes we have running vs.
19958        // how many slots we have for background processes; we may want
19959        // to put multiple processes in a slot of there are enough of
19960        // them.
19961        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19962                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19963        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19964        if (numEmptyProcs > cachedProcessLimit) {
19965            // If there are more empty processes than our limit on cached
19966            // processes, then use the cached process limit for the factor.
19967            // This ensures that the really old empty processes get pushed
19968            // down to the bottom, so if we are running low on memory we will
19969            // have a better chance at keeping around more cached processes
19970            // instead of a gazillion empty processes.
19971            numEmptyProcs = cachedProcessLimit;
19972        }
19973        int emptyFactor = numEmptyProcs/numSlots;
19974        if (emptyFactor < 1) emptyFactor = 1;
19975        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19976        if (cachedFactor < 1) cachedFactor = 1;
19977        int stepCached = 0;
19978        int stepEmpty = 0;
19979        int numCached = 0;
19980        int numEmpty = 0;
19981        int numTrimming = 0;
19982
19983        mNumNonCachedProcs = 0;
19984        mNumCachedHiddenProcs = 0;
19985
19986        // First update the OOM adjustment for each of the
19987        // application processes based on their current state.
19988        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19989        int nextCachedAdj = curCachedAdj+1;
19990        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19991        int nextEmptyAdj = curEmptyAdj+2;
19992        for (int i=N-1; i>=0; i--) {
19993            ProcessRecord app = mLruProcesses.get(i);
19994            if (!app.killedByAm && app.thread != null) {
19995                app.procStateChanged = false;
19996                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19997
19998                // If we haven't yet assigned the final cached adj
19999                // to the process, do that now.
20000                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20001                    switch (app.curProcState) {
20002                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20003                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20004                            // This process is a cached process holding activities...
20005                            // assign it the next cached value for that type, and then
20006                            // step that cached level.
20007                            app.curRawAdj = curCachedAdj;
20008                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20009                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20010                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20011                                    + ")");
20012                            if (curCachedAdj != nextCachedAdj) {
20013                                stepCached++;
20014                                if (stepCached >= cachedFactor) {
20015                                    stepCached = 0;
20016                                    curCachedAdj = nextCachedAdj;
20017                                    nextCachedAdj += 2;
20018                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20019                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20020                                    }
20021                                }
20022                            }
20023                            break;
20024                        default:
20025                            // For everything else, assign next empty cached process
20026                            // level and bump that up.  Note that this means that
20027                            // long-running services that have dropped down to the
20028                            // cached level will be treated as empty (since their process
20029                            // state is still as a service), which is what we want.
20030                            app.curRawAdj = curEmptyAdj;
20031                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20032                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20033                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20034                                    + ")");
20035                            if (curEmptyAdj != nextEmptyAdj) {
20036                                stepEmpty++;
20037                                if (stepEmpty >= emptyFactor) {
20038                                    stepEmpty = 0;
20039                                    curEmptyAdj = nextEmptyAdj;
20040                                    nextEmptyAdj += 2;
20041                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20042                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20043                                    }
20044                                }
20045                            }
20046                            break;
20047                    }
20048                }
20049
20050                applyOomAdjLocked(app, true, now, nowElapsed);
20051
20052                // Count the number of process types.
20053                switch (app.curProcState) {
20054                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20055                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20056                        mNumCachedHiddenProcs++;
20057                        numCached++;
20058                        if (numCached > cachedProcessLimit) {
20059                            app.kill("cached #" + numCached, true);
20060                        }
20061                        break;
20062                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20063                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20064                                && app.lastActivityTime < oldTime) {
20065                            app.kill("empty for "
20066                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20067                                    / 1000) + "s", true);
20068                        } else {
20069                            numEmpty++;
20070                            if (numEmpty > emptyProcessLimit) {
20071                                app.kill("empty #" + numEmpty, true);
20072                            }
20073                        }
20074                        break;
20075                    default:
20076                        mNumNonCachedProcs++;
20077                        break;
20078                }
20079
20080                if (app.isolated && app.services.size() <= 0) {
20081                    // If this is an isolated process, and there are no
20082                    // services running in it, then the process is no longer
20083                    // needed.  We agressively kill these because we can by
20084                    // definition not re-use the same process again, and it is
20085                    // good to avoid having whatever code was running in them
20086                    // left sitting around after no longer needed.
20087                    app.kill("isolated not needed", true);
20088                } else {
20089                    // Keeping this process, update its uid.
20090                    final UidRecord uidRec = app.uidRecord;
20091                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20092                        uidRec.curProcState = app.curProcState;
20093                    }
20094                }
20095
20096                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20097                        && !app.killedByAm) {
20098                    numTrimming++;
20099                }
20100            }
20101        }
20102
20103        mNumServiceProcs = mNewNumServiceProcs;
20104
20105        // Now determine the memory trimming level of background processes.
20106        // Unfortunately we need to start at the back of the list to do this
20107        // properly.  We only do this if the number of background apps we
20108        // are managing to keep around is less than half the maximum we desire;
20109        // if we are keeping a good number around, we'll let them use whatever
20110        // memory they want.
20111        final int numCachedAndEmpty = numCached + numEmpty;
20112        int memFactor;
20113        if (numCached <= ProcessList.TRIM_CACHED_APPS
20114                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20115            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20116                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20117            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20118                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20119            } else {
20120                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20121            }
20122        } else {
20123            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20124        }
20125        // We always allow the memory level to go up (better).  We only allow it to go
20126        // down if we are in a state where that is allowed, *and* the total number of processes
20127        // has gone down since last time.
20128        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20129                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20130                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20131        if (memFactor > mLastMemoryLevel) {
20132            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20133                memFactor = mLastMemoryLevel;
20134                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20135            }
20136        }
20137        if (memFactor != mLastMemoryLevel) {
20138            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20139        }
20140        mLastMemoryLevel = memFactor;
20141        mLastNumProcesses = mLruProcesses.size();
20142        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20143        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20144        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20145            if (mLowRamStartTime == 0) {
20146                mLowRamStartTime = now;
20147            }
20148            int step = 0;
20149            int fgTrimLevel;
20150            switch (memFactor) {
20151                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20152                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20153                    break;
20154                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20155                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20156                    break;
20157                default:
20158                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20159                    break;
20160            }
20161            int factor = numTrimming/3;
20162            int minFactor = 2;
20163            if (mHomeProcess != null) minFactor++;
20164            if (mPreviousProcess != null) minFactor++;
20165            if (factor < minFactor) factor = minFactor;
20166            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20167            for (int i=N-1; i>=0; i--) {
20168                ProcessRecord app = mLruProcesses.get(i);
20169                if (allChanged || app.procStateChanged) {
20170                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20171                    app.procStateChanged = false;
20172                }
20173                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20174                        && !app.killedByAm) {
20175                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20176                        try {
20177                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20178                                    "Trimming memory of " + app.processName + " to " + curLevel);
20179                            app.thread.scheduleTrimMemory(curLevel);
20180                        } catch (RemoteException e) {
20181                        }
20182                        if (false) {
20183                            // For now we won't do this; our memory trimming seems
20184                            // to be good enough at this point that destroying
20185                            // activities causes more harm than good.
20186                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20187                                    && app != mHomeProcess && app != mPreviousProcess) {
20188                                // Need to do this on its own message because the stack may not
20189                                // be in a consistent state at this point.
20190                                // For these apps we will also finish their activities
20191                                // to help them free memory.
20192                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20193                            }
20194                        }
20195                    }
20196                    app.trimMemoryLevel = curLevel;
20197                    step++;
20198                    if (step >= factor) {
20199                        step = 0;
20200                        switch (curLevel) {
20201                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20202                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20203                                break;
20204                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20205                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20206                                break;
20207                        }
20208                    }
20209                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20210                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20211                            && app.thread != null) {
20212                        try {
20213                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20214                                    "Trimming memory of heavy-weight " + app.processName
20215                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20216                            app.thread.scheduleTrimMemory(
20217                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20218                        } catch (RemoteException e) {
20219                        }
20220                    }
20221                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20222                } else {
20223                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20224                            || app.systemNoUi) && app.pendingUiClean) {
20225                        // If this application is now in the background and it
20226                        // had done UI, then give it the special trim level to
20227                        // have it free UI resources.
20228                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20229                        if (app.trimMemoryLevel < level && app.thread != null) {
20230                            try {
20231                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20232                                        "Trimming memory of bg-ui " + app.processName
20233                                        + " to " + level);
20234                                app.thread.scheduleTrimMemory(level);
20235                            } catch (RemoteException e) {
20236                            }
20237                        }
20238                        app.pendingUiClean = false;
20239                    }
20240                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20241                        try {
20242                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20243                                    "Trimming memory of fg " + app.processName
20244                                    + " to " + fgTrimLevel);
20245                            app.thread.scheduleTrimMemory(fgTrimLevel);
20246                        } catch (RemoteException e) {
20247                        }
20248                    }
20249                    app.trimMemoryLevel = fgTrimLevel;
20250                }
20251            }
20252        } else {
20253            if (mLowRamStartTime != 0) {
20254                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20255                mLowRamStartTime = 0;
20256            }
20257            for (int i=N-1; i>=0; i--) {
20258                ProcessRecord app = mLruProcesses.get(i);
20259                if (allChanged || app.procStateChanged) {
20260                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20261                    app.procStateChanged = false;
20262                }
20263                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20264                        || app.systemNoUi) && app.pendingUiClean) {
20265                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20266                            && app.thread != null) {
20267                        try {
20268                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20269                                    "Trimming memory of ui hidden " + app.processName
20270                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20271                            app.thread.scheduleTrimMemory(
20272                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20273                        } catch (RemoteException e) {
20274                        }
20275                    }
20276                    app.pendingUiClean = false;
20277                }
20278                app.trimMemoryLevel = 0;
20279            }
20280        }
20281
20282        if (mAlwaysFinishActivities) {
20283            // Need to do this on its own message because the stack may not
20284            // be in a consistent state at this point.
20285            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20286        }
20287
20288        if (allChanged) {
20289            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20290        }
20291
20292        // Update from any uid changes.
20293        for (int i=mActiveUids.size()-1; i>=0; i--) {
20294            final UidRecord uidRec = mActiveUids.valueAt(i);
20295            int uidChange = UidRecord.CHANGE_PROCSTATE;
20296            if (uidRec.setProcState != uidRec.curProcState) {
20297                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20298                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20299                        + " to " + uidRec.curProcState);
20300                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20301                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20302                        uidRec.lastBackgroundTime = nowElapsed;
20303                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20304                            // Note: the background settle time is in elapsed realtime, while
20305                            // the handler time base is uptime.  All this means is that we may
20306                            // stop background uids later than we had intended, but that only
20307                            // happens because the device was sleeping so we are okay anyway.
20308                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20309                        }
20310                    }
20311                } else {
20312                    if (uidRec.idle) {
20313                        uidChange = UidRecord.CHANGE_ACTIVE;
20314                        uidRec.idle = false;
20315                    }
20316                    uidRec.lastBackgroundTime = 0;
20317                }
20318                uidRec.setProcState = uidRec.curProcState;
20319                enqueueUidChangeLocked(uidRec, -1, uidChange);
20320                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20321            }
20322        }
20323
20324        if (mProcessStats.shouldWriteNowLocked(now)) {
20325            mHandler.post(new Runnable() {
20326                @Override public void run() {
20327                    synchronized (ActivityManagerService.this) {
20328                        mProcessStats.writeStateAsyncLocked();
20329                    }
20330                }
20331            });
20332        }
20333
20334        if (DEBUG_OOM_ADJ) {
20335            final long duration = SystemClock.uptimeMillis() - now;
20336            if (false) {
20337                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20338                        new RuntimeException("here").fillInStackTrace());
20339            } else {
20340                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20341            }
20342        }
20343    }
20344
20345    final void idleUids() {
20346        synchronized (this) {
20347            final long nowElapsed = SystemClock.elapsedRealtime();
20348            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20349            long nextTime = 0;
20350            for (int i=mActiveUids.size()-1; i>=0; i--) {
20351                final UidRecord uidRec = mActiveUids.valueAt(i);
20352                final long bgTime = uidRec.lastBackgroundTime;
20353                if (bgTime > 0 && !uidRec.idle) {
20354                    if (bgTime <= maxBgTime) {
20355                        uidRec.idle = true;
20356                        doStopUidLocked(uidRec.uid, uidRec);
20357                    } else {
20358                        if (nextTime == 0 || nextTime > bgTime) {
20359                            nextTime = bgTime;
20360                        }
20361                    }
20362                }
20363            }
20364            if (nextTime > 0) {
20365                mHandler.removeMessages(IDLE_UIDS_MSG);
20366                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20367                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20368            }
20369        }
20370    }
20371
20372    final void runInBackgroundDisabled(int uid) {
20373        synchronized (this) {
20374            UidRecord uidRec = mActiveUids.get(uid);
20375            if (uidRec != null) {
20376                // This uid is actually running...  should it be considered background now?
20377                if (uidRec.idle) {
20378                    doStopUidLocked(uidRec.uid, uidRec);
20379                }
20380            } else {
20381                // This uid isn't actually running...  still send a report about it being "stopped".
20382                doStopUidLocked(uid, null);
20383            }
20384        }
20385    }
20386
20387    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20388        mServices.stopInBackgroundLocked(uid);
20389        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20390    }
20391
20392    final void trimApplications() {
20393        synchronized (this) {
20394            int i;
20395
20396            // First remove any unused application processes whose package
20397            // has been removed.
20398            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20399                final ProcessRecord app = mRemovedProcesses.get(i);
20400                if (app.activities.size() == 0
20401                        && app.curReceiver == null && app.services.size() == 0) {
20402                    Slog.i(
20403                        TAG, "Exiting empty application process "
20404                        + app.processName + " ("
20405                        + (app.thread != null ? app.thread.asBinder() : null)
20406                        + ")\n");
20407                    if (app.pid > 0 && app.pid != MY_PID) {
20408                        app.kill("empty", false);
20409                    } else {
20410                        try {
20411                            app.thread.scheduleExit();
20412                        } catch (Exception e) {
20413                            // Ignore exceptions.
20414                        }
20415                    }
20416                    cleanUpApplicationRecordLocked(app, false, true, -1);
20417                    mRemovedProcesses.remove(i);
20418
20419                    if (app.persistent) {
20420                        addAppLocked(app.info, false, null /* ABI override */);
20421                    }
20422                }
20423            }
20424
20425            // Now update the oom adj for all processes.
20426            updateOomAdjLocked();
20427        }
20428    }
20429
20430    /** This method sends the specified signal to each of the persistent apps */
20431    public void signalPersistentProcesses(int sig) throws RemoteException {
20432        if (sig != Process.SIGNAL_USR1) {
20433            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20434        }
20435
20436        synchronized (this) {
20437            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20438                    != PackageManager.PERMISSION_GRANTED) {
20439                throw new SecurityException("Requires permission "
20440                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20441            }
20442
20443            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20444                ProcessRecord r = mLruProcesses.get(i);
20445                if (r.thread != null && r.persistent) {
20446                    Process.sendSignal(r.pid, sig);
20447                }
20448            }
20449        }
20450    }
20451
20452    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20453        if (proc == null || proc == mProfileProc) {
20454            proc = mProfileProc;
20455            profileType = mProfileType;
20456            clearProfilerLocked();
20457        }
20458        if (proc == null) {
20459            return;
20460        }
20461        try {
20462            proc.thread.profilerControl(false, null, profileType);
20463        } catch (RemoteException e) {
20464            throw new IllegalStateException("Process disappeared");
20465        }
20466    }
20467
20468    private void clearProfilerLocked() {
20469        if (mProfileFd != null) {
20470            try {
20471                mProfileFd.close();
20472            } catch (IOException e) {
20473            }
20474        }
20475        mProfileApp = null;
20476        mProfileProc = null;
20477        mProfileFile = null;
20478        mProfileType = 0;
20479        mAutoStopProfiler = false;
20480        mSamplingInterval = 0;
20481    }
20482
20483    public boolean profileControl(String process, int userId, boolean start,
20484            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20485
20486        try {
20487            synchronized (this) {
20488                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20489                // its own permission.
20490                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20491                        != PackageManager.PERMISSION_GRANTED) {
20492                    throw new SecurityException("Requires permission "
20493                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20494                }
20495
20496                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20497                    throw new IllegalArgumentException("null profile info or fd");
20498                }
20499
20500                ProcessRecord proc = null;
20501                if (process != null) {
20502                    proc = findProcessLocked(process, userId, "profileControl");
20503                }
20504
20505                if (start && (proc == null || proc.thread == null)) {
20506                    throw new IllegalArgumentException("Unknown process: " + process);
20507                }
20508
20509                if (start) {
20510                    stopProfilerLocked(null, 0);
20511                    setProfileApp(proc.info, proc.processName, profilerInfo);
20512                    mProfileProc = proc;
20513                    mProfileType = profileType;
20514                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20515                    try {
20516                        fd = fd.dup();
20517                    } catch (IOException e) {
20518                        fd = null;
20519                    }
20520                    profilerInfo.profileFd = fd;
20521                    proc.thread.profilerControl(start, profilerInfo, profileType);
20522                    fd = null;
20523                    mProfileFd = null;
20524                } else {
20525                    stopProfilerLocked(proc, profileType);
20526                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20527                        try {
20528                            profilerInfo.profileFd.close();
20529                        } catch (IOException e) {
20530                        }
20531                    }
20532                }
20533
20534                return true;
20535            }
20536        } catch (RemoteException e) {
20537            throw new IllegalStateException("Process disappeared");
20538        } finally {
20539            if (profilerInfo != null && profilerInfo.profileFd != null) {
20540                try {
20541                    profilerInfo.profileFd.close();
20542                } catch (IOException e) {
20543                }
20544            }
20545        }
20546    }
20547
20548    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20549        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20550                userId, true, ALLOW_FULL_ONLY, callName, null);
20551        ProcessRecord proc = null;
20552        try {
20553            int pid = Integer.parseInt(process);
20554            synchronized (mPidsSelfLocked) {
20555                proc = mPidsSelfLocked.get(pid);
20556            }
20557        } catch (NumberFormatException e) {
20558        }
20559
20560        if (proc == null) {
20561            ArrayMap<String, SparseArray<ProcessRecord>> all
20562                    = mProcessNames.getMap();
20563            SparseArray<ProcessRecord> procs = all.get(process);
20564            if (procs != null && procs.size() > 0) {
20565                proc = procs.valueAt(0);
20566                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20567                    for (int i=1; i<procs.size(); i++) {
20568                        ProcessRecord thisProc = procs.valueAt(i);
20569                        if (thisProc.userId == userId) {
20570                            proc = thisProc;
20571                            break;
20572                        }
20573                    }
20574                }
20575            }
20576        }
20577
20578        return proc;
20579    }
20580
20581    public boolean dumpHeap(String process, int userId, boolean managed,
20582            String path, ParcelFileDescriptor fd) throws RemoteException {
20583
20584        try {
20585            synchronized (this) {
20586                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20587                // its own permission (same as profileControl).
20588                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20589                        != PackageManager.PERMISSION_GRANTED) {
20590                    throw new SecurityException("Requires permission "
20591                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20592                }
20593
20594                if (fd == null) {
20595                    throw new IllegalArgumentException("null fd");
20596                }
20597
20598                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20599                if (proc == null || proc.thread == null) {
20600                    throw new IllegalArgumentException("Unknown process: " + process);
20601                }
20602
20603                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20604                if (!isDebuggable) {
20605                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20606                        throw new SecurityException("Process not debuggable: " + proc);
20607                    }
20608                }
20609
20610                proc.thread.dumpHeap(managed, path, fd);
20611                fd = null;
20612                return true;
20613            }
20614        } catch (RemoteException e) {
20615            throw new IllegalStateException("Process disappeared");
20616        } finally {
20617            if (fd != null) {
20618                try {
20619                    fd.close();
20620                } catch (IOException e) {
20621                }
20622            }
20623        }
20624    }
20625
20626    @Override
20627    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20628            String reportPackage) {
20629        if (processName != null) {
20630            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20631                    "setDumpHeapDebugLimit()");
20632        } else {
20633            synchronized (mPidsSelfLocked) {
20634                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20635                if (proc == null) {
20636                    throw new SecurityException("No process found for calling pid "
20637                            + Binder.getCallingPid());
20638                }
20639                if (!Build.IS_DEBUGGABLE
20640                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20641                    throw new SecurityException("Not running a debuggable build");
20642                }
20643                processName = proc.processName;
20644                uid = proc.uid;
20645                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20646                    throw new SecurityException("Package " + reportPackage + " is not running in "
20647                            + proc);
20648                }
20649            }
20650        }
20651        synchronized (this) {
20652            if (maxMemSize > 0) {
20653                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20654            } else {
20655                if (uid != 0) {
20656                    mMemWatchProcesses.remove(processName, uid);
20657                } else {
20658                    mMemWatchProcesses.getMap().remove(processName);
20659                }
20660            }
20661        }
20662    }
20663
20664    @Override
20665    public void dumpHeapFinished(String path) {
20666        synchronized (this) {
20667            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20668                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20669                        + " does not match last pid " + mMemWatchDumpPid);
20670                return;
20671            }
20672            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20673                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20674                        + " does not match last path " + mMemWatchDumpFile);
20675                return;
20676            }
20677            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20678            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20679        }
20680    }
20681
20682    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20683    public void monitor() {
20684        synchronized (this) { }
20685    }
20686
20687    void onCoreSettingsChange(Bundle settings) {
20688        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20689            ProcessRecord processRecord = mLruProcesses.get(i);
20690            try {
20691                if (processRecord.thread != null) {
20692                    processRecord.thread.setCoreSettings(settings);
20693                }
20694            } catch (RemoteException re) {
20695                /* ignore */
20696            }
20697        }
20698    }
20699
20700    // Multi-user methods
20701
20702    /**
20703     * Start user, if its not already running, but don't bring it to foreground.
20704     */
20705    @Override
20706    public boolean startUserInBackground(final int userId) {
20707        return mUserController.startUser(userId, /* foreground */ false);
20708    }
20709
20710    @Override
20711    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20712        return mUserController.unlockUser(userId, token, secret, listener);
20713    }
20714
20715    @Override
20716    public boolean switchUser(final int targetUserId) {
20717        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20718        UserInfo currentUserInfo;
20719        UserInfo targetUserInfo;
20720        synchronized (this) {
20721            int currentUserId = mUserController.getCurrentUserIdLocked();
20722            currentUserInfo = mUserController.getUserInfo(currentUserId);
20723            targetUserInfo = mUserController.getUserInfo(targetUserId);
20724            if (targetUserInfo == null) {
20725                Slog.w(TAG, "No user info for user #" + targetUserId);
20726                return false;
20727            }
20728            if (!targetUserInfo.supportsSwitchTo()) {
20729                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20730                return false;
20731            }
20732            if (targetUserInfo.isManagedProfile()) {
20733                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20734                return false;
20735            }
20736            mUserController.setTargetUserIdLocked(targetUserId);
20737        }
20738        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20739        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20740        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20741        return true;
20742    }
20743
20744    void scheduleStartProfilesLocked() {
20745        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20746            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20747                    DateUtils.SECOND_IN_MILLIS);
20748        }
20749    }
20750
20751    @Override
20752    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20753        return mUserController.stopUser(userId, force, callback);
20754    }
20755
20756    @Override
20757    public UserInfo getCurrentUser() {
20758        return mUserController.getCurrentUser();
20759    }
20760
20761    @Override
20762    public boolean isUserRunning(int userId, int flags) {
20763        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20764                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20765            String msg = "Permission Denial: isUserRunning() from pid="
20766                    + Binder.getCallingPid()
20767                    + ", uid=" + Binder.getCallingUid()
20768                    + " requires " + INTERACT_ACROSS_USERS;
20769            Slog.w(TAG, msg);
20770            throw new SecurityException(msg);
20771        }
20772        synchronized (this) {
20773            return mUserController.isUserRunningLocked(userId, flags);
20774        }
20775    }
20776
20777    @Override
20778    public int[] getRunningUserIds() {
20779        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20780                != PackageManager.PERMISSION_GRANTED) {
20781            String msg = "Permission Denial: isUserRunning() from pid="
20782                    + Binder.getCallingPid()
20783                    + ", uid=" + Binder.getCallingUid()
20784                    + " requires " + INTERACT_ACROSS_USERS;
20785            Slog.w(TAG, msg);
20786            throw new SecurityException(msg);
20787        }
20788        synchronized (this) {
20789            return mUserController.getStartedUserArrayLocked();
20790        }
20791    }
20792
20793    @Override
20794    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20795        mUserController.registerUserSwitchObserver(observer);
20796    }
20797
20798    @Override
20799    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20800        mUserController.unregisterUserSwitchObserver(observer);
20801    }
20802
20803    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20804        if (info == null) return null;
20805        ApplicationInfo newInfo = new ApplicationInfo(info);
20806        newInfo.initForUser(userId);
20807        return newInfo;
20808    }
20809
20810    public boolean isUserStopped(int userId) {
20811        synchronized (this) {
20812            return mUserController.getStartedUserStateLocked(userId) == null;
20813        }
20814    }
20815
20816    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20817        if (aInfo == null
20818                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20819            return aInfo;
20820        }
20821
20822        ActivityInfo info = new ActivityInfo(aInfo);
20823        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20824        return info;
20825    }
20826
20827    private boolean processSanityChecksLocked(ProcessRecord process) {
20828        if (process == null || process.thread == null) {
20829            return false;
20830        }
20831
20832        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20833        if (!isDebuggable) {
20834            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20835                return false;
20836            }
20837        }
20838
20839        return true;
20840    }
20841
20842    public boolean startBinderTracking() throws RemoteException {
20843        synchronized (this) {
20844            mBinderTransactionTrackingEnabled = true;
20845            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20846            // permission (same as profileControl).
20847            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20848                    != PackageManager.PERMISSION_GRANTED) {
20849                throw new SecurityException("Requires permission "
20850                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20851            }
20852
20853            for (int i = 0; i < mLruProcesses.size(); i++) {
20854                ProcessRecord process = mLruProcesses.get(i);
20855                if (!processSanityChecksLocked(process)) {
20856                    continue;
20857                }
20858                try {
20859                    process.thread.startBinderTracking();
20860                } catch (RemoteException e) {
20861                    Log.v(TAG, "Process disappared");
20862                }
20863            }
20864            return true;
20865        }
20866    }
20867
20868    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20869        try {
20870            synchronized (this) {
20871                mBinderTransactionTrackingEnabled = false;
20872                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20873                // permission (same as profileControl).
20874                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20875                        != PackageManager.PERMISSION_GRANTED) {
20876                    throw new SecurityException("Requires permission "
20877                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20878                }
20879
20880                if (fd == null) {
20881                    throw new IllegalArgumentException("null fd");
20882                }
20883
20884                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20885                pw.println("Binder transaction traces for all processes.\n");
20886                for (ProcessRecord process : mLruProcesses) {
20887                    if (!processSanityChecksLocked(process)) {
20888                        continue;
20889                    }
20890
20891                    pw.println("Traces for process: " + process.processName);
20892                    pw.flush();
20893                    try {
20894                        TransferPipe tp = new TransferPipe();
20895                        try {
20896                            process.thread.stopBinderTrackingAndDump(
20897                                    tp.getWriteFd().getFileDescriptor());
20898                            tp.go(fd.getFileDescriptor());
20899                        } finally {
20900                            tp.kill();
20901                        }
20902                    } catch (IOException e) {
20903                        pw.println("Failure while dumping IPC traces from " + process +
20904                                ".  Exception: " + e);
20905                        pw.flush();
20906                    } catch (RemoteException e) {
20907                        pw.println("Got a RemoteException while dumping IPC traces from " +
20908                                process + ".  Exception: " + e);
20909                        pw.flush();
20910                    }
20911                }
20912                fd = null;
20913                return true;
20914            }
20915        } finally {
20916            if (fd != null) {
20917                try {
20918                    fd.close();
20919                } catch (IOException e) {
20920                }
20921            }
20922        }
20923    }
20924
20925    private final class LocalService extends ActivityManagerInternal {
20926        @Override
20927        public void onWakefulnessChanged(int wakefulness) {
20928            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20929        }
20930
20931        @Override
20932        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20933                String processName, String abiOverride, int uid, Runnable crashHandler) {
20934            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20935                    processName, abiOverride, uid, crashHandler);
20936        }
20937
20938        @Override
20939        public SleepToken acquireSleepToken(String tag) {
20940            Preconditions.checkNotNull(tag);
20941
20942            synchronized (ActivityManagerService.this) {
20943                SleepTokenImpl token = new SleepTokenImpl(tag);
20944                mSleepTokens.add(token);
20945                updateSleepIfNeededLocked();
20946                applyVrModeIfNeededLocked(mFocusedActivity, false);
20947                return token;
20948            }
20949        }
20950
20951        @Override
20952        public ComponentName getHomeActivityForUser(int userId) {
20953            synchronized (ActivityManagerService.this) {
20954                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20955                return homeActivity == null ? null : homeActivity.realActivity;
20956            }
20957        }
20958
20959        @Override
20960        public void onUserRemoved(int userId) {
20961            synchronized (ActivityManagerService.this) {
20962                ActivityManagerService.this.onUserStoppedLocked(userId);
20963            }
20964        }
20965
20966        @Override
20967        public void onLocalVoiceInteractionStarted(IBinder activity,
20968                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20969            synchronized (ActivityManagerService.this) {
20970                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
20971                        voiceSession, voiceInteractor);
20972            }
20973        }
20974
20975        @Override
20976        public void notifyStartingWindowDrawn() {
20977            synchronized (ActivityManagerService.this) {
20978                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
20979            }
20980        }
20981
20982        @Override
20983        public void notifyAppTransitionStarting(int reason) {
20984            synchronized (ActivityManagerService.this) {
20985                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
20986            }
20987        }
20988
20989        @Override
20990        public void notifyAppTransitionFinished() {
20991            synchronized (ActivityManagerService.this) {
20992                mStackSupervisor.notifyAppTransitionDone();
20993            }
20994        }
20995
20996        @Override
20997        public void notifyAppTransitionCancelled() {
20998            synchronized (ActivityManagerService.this) {
20999                mStackSupervisor.notifyAppTransitionDone();
21000            }
21001        }
21002
21003        @Override
21004        public List<IBinder> getTopVisibleActivities() {
21005            synchronized (ActivityManagerService.this) {
21006                return mStackSupervisor.getTopVisibleActivities();
21007            }
21008        }
21009
21010        @Override
21011        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21012            synchronized (ActivityManagerService.this) {
21013                mStackSupervisor.setDockedStackMinimized(minimized);
21014            }
21015        }
21016
21017        @Override
21018        public void killForegroundAppsForUser(int userHandle) {
21019            synchronized (ActivityManagerService.this) {
21020                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21021                final int NP = mProcessNames.getMap().size();
21022                for (int ip = 0; ip < NP; ip++) {
21023                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21024                    final int NA = apps.size();
21025                    for (int ia = 0; ia < NA; ia++) {
21026                        final ProcessRecord app = apps.valueAt(ia);
21027                        if (app.persistent) {
21028                            // We don't kill persistent processes.
21029                            continue;
21030                        }
21031                        if (app.removed) {
21032                            procs.add(app);
21033                        } else if (app.userId == userHandle && app.foregroundActivities) {
21034                            app.removed = true;
21035                            procs.add(app);
21036                        }
21037                    }
21038                }
21039
21040                final int N = procs.size();
21041                for (int i = 0; i < N; i++) {
21042                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21043                }
21044            }
21045        }
21046    }
21047
21048    private final class SleepTokenImpl extends SleepToken {
21049        private final String mTag;
21050        private final long mAcquireTime;
21051
21052        public SleepTokenImpl(String tag) {
21053            mTag = tag;
21054            mAcquireTime = SystemClock.uptimeMillis();
21055        }
21056
21057        @Override
21058        public void release() {
21059            synchronized (ActivityManagerService.this) {
21060                if (mSleepTokens.remove(this)) {
21061                    updateSleepIfNeededLocked();
21062                }
21063            }
21064        }
21065
21066        @Override
21067        public String toString() {
21068            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21069        }
21070    }
21071
21072    /**
21073     * An implementation of IAppTask, that allows an app to manage its own tasks via
21074     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21075     * only the process that calls getAppTasks() can call the AppTask methods.
21076     */
21077    class AppTaskImpl extends IAppTask.Stub {
21078        private int mTaskId;
21079        private int mCallingUid;
21080
21081        public AppTaskImpl(int taskId, int callingUid) {
21082            mTaskId = taskId;
21083            mCallingUid = callingUid;
21084        }
21085
21086        private void checkCaller() {
21087            if (mCallingUid != Binder.getCallingUid()) {
21088                throw new SecurityException("Caller " + mCallingUid
21089                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21090            }
21091        }
21092
21093        @Override
21094        public void finishAndRemoveTask() {
21095            checkCaller();
21096
21097            synchronized (ActivityManagerService.this) {
21098                long origId = Binder.clearCallingIdentity();
21099                try {
21100                    // We remove the task from recents to preserve backwards
21101                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21102                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21103                    }
21104                } finally {
21105                    Binder.restoreCallingIdentity(origId);
21106                }
21107            }
21108        }
21109
21110        @Override
21111        public ActivityManager.RecentTaskInfo getTaskInfo() {
21112            checkCaller();
21113
21114            synchronized (ActivityManagerService.this) {
21115                long origId = Binder.clearCallingIdentity();
21116                try {
21117                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21118                    if (tr == null) {
21119                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21120                    }
21121                    return createRecentTaskInfoFromTaskRecord(tr);
21122                } finally {
21123                    Binder.restoreCallingIdentity(origId);
21124                }
21125            }
21126        }
21127
21128        @Override
21129        public void moveToFront() {
21130            checkCaller();
21131            // Will bring task to front if it already has a root activity.
21132            final long origId = Binder.clearCallingIdentity();
21133            try {
21134                synchronized (this) {
21135                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21136                }
21137            } finally {
21138                Binder.restoreCallingIdentity(origId);
21139            }
21140        }
21141
21142        @Override
21143        public int startActivity(IBinder whoThread, String callingPackage,
21144                Intent intent, String resolvedType, Bundle bOptions) {
21145            checkCaller();
21146
21147            int callingUser = UserHandle.getCallingUserId();
21148            TaskRecord tr;
21149            IApplicationThread appThread;
21150            synchronized (ActivityManagerService.this) {
21151                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21152                if (tr == null) {
21153                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21154                }
21155                appThread = ApplicationThreadNative.asInterface(whoThread);
21156                if (appThread == null) {
21157                    throw new IllegalArgumentException("Bad app thread " + appThread);
21158                }
21159            }
21160            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21161                    resolvedType, null, null, null, null, 0, 0, null, null,
21162                    null, bOptions, false, callingUser, null, tr);
21163        }
21164
21165        @Override
21166        public void setExcludeFromRecents(boolean exclude) {
21167            checkCaller();
21168
21169            synchronized (ActivityManagerService.this) {
21170                long origId = Binder.clearCallingIdentity();
21171                try {
21172                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21173                    if (tr == null) {
21174                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21175                    }
21176                    Intent intent = tr.getBaseIntent();
21177                    if (exclude) {
21178                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21179                    } else {
21180                        intent.setFlags(intent.getFlags()
21181                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21182                    }
21183                } finally {
21184                    Binder.restoreCallingIdentity(origId);
21185                }
21186            }
21187        }
21188    }
21189
21190    /**
21191     * Kill processes for the user with id userId and that depend on the package named packageName
21192     */
21193    @Override
21194    public void killPackageDependents(String packageName, int userId) {
21195        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21196        if (packageName == null) {
21197            throw new NullPointerException(
21198                    "Cannot kill the dependents of a package without its name.");
21199        }
21200
21201        long callingId = Binder.clearCallingIdentity();
21202        IPackageManager pm = AppGlobals.getPackageManager();
21203        int pkgUid = -1;
21204        try {
21205            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21206        } catch (RemoteException e) {
21207        }
21208        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21209            throw new IllegalArgumentException(
21210                    "Cannot kill dependents of non-existing package " + packageName);
21211        }
21212        try {
21213            synchronized(this) {
21214                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21215                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21216                        "dep: " + packageName);
21217            }
21218        } finally {
21219            Binder.restoreCallingIdentity(callingId);
21220        }
21221    }
21222}
21223