ActivityManagerService.java revision d375a04d2ec4edacb323ec86a2f310153fa4547c
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.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.internal.util.ProgressReporter;
45import com.android.server.AppOpsService;
46import com.android.server.AttributeCache;
47import com.android.server.DeviceIdleController;
48import com.android.server.IntentResolver;
49import com.android.server.LocalServices;
50import com.android.server.LockGuard;
51import com.android.server.ServiceThread;
52import com.android.server.SystemService;
53import com.android.server.SystemServiceManager;
54import com.android.server.Watchdog;
55import com.android.server.am.ActivityStack.ActivityState;
56import com.android.server.firewall.IntentFirewall;
57import com.android.server.pm.Installer;
58import com.android.server.statusbar.StatusBarManagerInternal;
59import com.android.server.vr.VrManagerInternal;
60import com.android.server.wm.WindowManagerService;
61
62import org.xmlpull.v1.XmlPullParser;
63import org.xmlpull.v1.XmlPullParserException;
64import org.xmlpull.v1.XmlSerializer;
65
66import android.Manifest;
67import android.annotation.UserIdInt;
68import android.app.Activity;
69import android.app.ActivityManager;
70import android.app.ActivityManager.RunningTaskInfo;
71import android.app.ActivityManager.StackId;
72import android.app.ActivityManager.StackInfo;
73import android.app.ActivityManager.TaskThumbnailInfo;
74import android.app.ActivityManagerInternal;
75import android.app.ActivityManagerInternal.SleepToken;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.AppOpsManager;
82import android.app.ApplicationErrorReport;
83import android.app.ApplicationThreadNative;
84import android.app.BroadcastOptions;
85import android.app.Dialog;
86import android.app.IActivityContainer;
87import android.app.IActivityContainerCallback;
88import android.app.IActivityController;
89import android.app.IAppTask;
90import android.app.IApplicationThread;
91import android.app.IInstrumentationWatcher;
92import android.app.INotificationManager;
93import android.app.IProcessObserver;
94import android.app.IServiceConnection;
95import android.app.IStopUserCallback;
96import android.app.ITaskStackListener;
97import android.app.IUiAutomationConnection;
98import android.app.IUidObserver;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.KeyguardManager;
102import android.app.Notification;
103import android.app.NotificationManager;
104import android.app.PendingIntent;
105import android.app.ProfilerInfo;
106import android.app.admin.DevicePolicyManager;
107import android.app.admin.DevicePolicyManagerInternal;
108import android.app.assist.AssistContent;
109import android.app.assist.AssistStructure;
110import android.app.backup.IBackupManager;
111import android.app.usage.UsageEvents;
112import android.app.usage.UsageStatsManagerInternal;
113import android.appwidget.AppWidgetManager;
114import android.content.ActivityNotFoundException;
115import android.content.BroadcastReceiver;
116import android.content.ClipData;
117import android.content.ComponentCallbacks2;
118import android.content.ComponentName;
119import android.content.ContentProvider;
120import android.content.ContentResolver;
121import android.content.Context;
122import android.content.DialogInterface;
123import android.content.IContentProvider;
124import android.content.IIntentReceiver;
125import android.content.IIntentSender;
126import android.content.Intent;
127import android.content.IntentFilter;
128import android.content.IntentSender;
129import android.content.pm.ActivityInfo;
130import android.content.pm.ApplicationInfo;
131import android.content.pm.ConfigurationInfo;
132import android.content.pm.IPackageDataObserver;
133import android.content.pm.IPackageManager;
134import android.content.pm.InstrumentationInfo;
135import android.content.pm.PackageInfo;
136import android.content.pm.PackageManager;
137import android.content.pm.PackageManager.NameNotFoundException;
138import android.content.pm.PackageManagerInternal;
139import android.content.pm.ParceledListSlice;
140import android.content.pm.PathPermission;
141import android.content.pm.PermissionInfo;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.pm.ShortcutServiceInternal;
146import android.content.pm.UserInfo;
147import android.content.res.CompatibilityInfo;
148import android.content.res.Configuration;
149import android.content.res.Resources;
150import android.database.ContentObserver;
151import android.graphics.Bitmap;
152import android.graphics.Point;
153import android.graphics.Rect;
154import android.location.LocationManager;
155import android.net.Proxy;
156import android.net.ProxyInfo;
157import android.net.Uri;
158import android.os.BatteryStats;
159import android.os.Binder;
160import android.os.Build;
161import android.os.Bundle;
162import android.os.Debug;
163import android.os.DropBoxManager;
164import android.os.Environment;
165import android.os.FactoryTest;
166import android.os.FileObserver;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.IPermissionController;
171import android.os.IProcessInfoService;
172import android.os.IProgressListener;
173import android.os.Looper;
174import android.os.Message;
175import android.os.Parcel;
176import android.os.ParcelFileDescriptor;
177import android.os.PersistableBundle;
178import android.os.PowerManager;
179import android.os.PowerManagerInternal;
180import android.os.Process;
181import android.os.RemoteCallbackList;
182import android.os.RemoteException;
183import android.os.ResultReceiver;
184import android.os.ServiceManager;
185import android.os.StrictMode;
186import android.os.SystemClock;
187import android.os.SystemProperties;
188import android.os.Trace;
189import android.os.TransactionTooLargeException;
190import android.os.UpdateLock;
191import android.os.UserHandle;
192import android.os.UserManager;
193import android.os.WorkSource;
194import android.os.storage.IMountService;
195import android.os.storage.MountServiceInternal;
196import android.os.storage.StorageManager;
197import android.provider.Settings;
198import android.service.voice.IVoiceInteractionSession;
199import android.service.voice.VoiceInteractionManagerInternal;
200import android.service.voice.VoiceInteractionSession;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.util.ArrayMap;
204import android.util.ArraySet;
205import android.util.AtomicFile;
206import android.util.DebugUtils;
207import android.util.EventLog;
208import android.util.LocaleList;
209import android.util.Log;
210import android.util.Pair;
211import android.util.PrintWriterPrinter;
212import android.util.Slog;
213import android.util.SparseArray;
214import android.util.TimeUtils;
215import android.util.Xml;
216import android.view.Display;
217import android.view.Gravity;
218import android.view.LayoutInflater;
219import android.view.View;
220import android.view.WindowManager;
221
222import java.io.File;
223import java.io.FileDescriptor;
224import java.io.FileInputStream;
225import java.io.FileNotFoundException;
226import java.io.FileOutputStream;
227import java.io.IOException;
228import java.io.InputStreamReader;
229import java.io.PrintWriter;
230import java.io.StringWriter;
231import java.lang.ref.WeakReference;
232import java.nio.charset.StandardCharsets;
233import java.util.ArrayList;
234import java.util.Arrays;
235import java.util.Collections;
236import java.util.Comparator;
237import java.util.HashMap;
238import java.util.HashSet;
239import java.util.Iterator;
240import java.util.List;
241import java.util.Locale;
242import java.util.Map;
243import java.util.Set;
244import java.util.concurrent.atomic.AtomicBoolean;
245import java.util.concurrent.atomic.AtomicLong;
246
247import dalvik.system.VMRuntime;
248
249import libcore.io.IoUtils;
250import libcore.util.EmptyArray;
251
252import static android.Manifest.permission.INTERACT_ACROSS_USERS;
253import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
254import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
255import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
256import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
257import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
258import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
259import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
260import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.HOME_STACK_ID;
263import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
264import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
265import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
266import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
267import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
268import static android.content.pm.PackageManager.GET_PROVIDERS;
269import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
270import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
271import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
272import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
273import static android.content.pm.PackageManager.PERMISSION_GRANTED;
274import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
275import static android.provider.Settings.Global.DEBUG_APP;
276import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
277import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
278import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
279import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
280import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
281import static android.provider.Settings.System.FONT_SCALE;
282import static com.android.internal.util.XmlUtils.readBooleanAttribute;
283import static com.android.internal.util.XmlUtils.readIntAttribute;
284import static com.android.internal.util.XmlUtils.readLongAttribute;
285import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
286import static com.android.internal.util.XmlUtils.writeIntAttribute;
287import static com.android.internal.util.XmlUtils.writeLongAttribute;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
344import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
345import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
346import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
347import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
348import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
349import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
350import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
351import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
352import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
353import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
354import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
355import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
356import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
357import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
358import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
359import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
360import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
361import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
362import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
363import static org.xmlpull.v1.XmlPullParser.START_TAG;
364
365public final class ActivityManagerService extends ActivityManagerNative
366        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
367
368    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
369    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
370    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
371    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
372    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
373    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
374    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
375    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
376    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
377    private static final String TAG_LRU = TAG + POSTFIX_LRU;
378    private static final String TAG_MU = TAG + POSTFIX_MU;
379    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
380    private static final String TAG_POWER = TAG + POSTFIX_POWER;
381    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
382    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
383    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
384    private static final String TAG_PSS = TAG + POSTFIX_PSS;
385    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
386    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
387    private static final String TAG_STACK = TAG + POSTFIX_STACK;
388    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
389    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
390    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
391    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
392    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
393
394    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
395    // here so that while the job scheduler can depend on AMS, the other way around
396    // need not be the case.
397    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
398
399    /** Control over CPU and battery monitoring */
400    // write battery stats every 30 minutes.
401    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
402    static final boolean MONITOR_CPU_USAGE = true;
403    // don't sample cpu less than every 5 seconds.
404    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
405    // wait possibly forever for next cpu sample.
406    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
407    static final boolean MONITOR_THREAD_CPU_USAGE = false;
408
409    // The flags that are set for all calls we make to the package manager.
410    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
411
412    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
413
414    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
415
416    // Amount of time after a call to stopAppSwitches() during which we will
417    // prevent further untrusted switches from happening.
418    static final long APP_SWITCH_DELAY_TIME = 5*1000;
419
420    // How long we wait for a launched process to attach to the activity manager
421    // before we decide it's never going to come up for real.
422    static final int PROC_START_TIMEOUT = 10*1000;
423    // How long we wait for an attached process to publish its content providers
424    // before we decide it must be hung.
425    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
426
427    // How long we will retain processes hosting content providers in the "last activity"
428    // state before allowing them to drop down to the regular cached LRU list.  This is
429    // to avoid thrashing of provider processes under low memory situations.
430    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
431
432    // How long we wait for a launched process to attach to the activity manager
433    // before we decide it's never going to come up for real, when the process was
434    // started with a wrapper for instrumentation (such as Valgrind) because it
435    // could take much longer than usual.
436    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
437
438    // How long to wait after going idle before forcing apps to GC.
439    static final int GC_TIMEOUT = 5*1000;
440
441    // The minimum amount of time between successive GC requests for a process.
442    static final int GC_MIN_INTERVAL = 60*1000;
443
444    // The minimum amount of time between successive PSS requests for a process.
445    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
446
447    // The minimum amount of time between successive PSS requests for a process
448    // when the request is due to the memory state being lowered.
449    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
450
451    // The rate at which we check for apps using excessive power -- 15 mins.
452    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
453
454    // The minimum sample duration we will allow before deciding we have
455    // enough data on wake locks to start killing things.
456    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
457
458    // The minimum sample duration we will allow before deciding we have
459    // enough data on CPU usage to start killing things.
460    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
461
462    // How long we allow a receiver to run before giving up on it.
463    static final int BROADCAST_FG_TIMEOUT = 10*1000;
464    static final int BROADCAST_BG_TIMEOUT = 60*1000;
465
466    // How long we wait until we timeout on key dispatching.
467    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
468
469    // How long we wait until we timeout on key dispatching during instrumentation.
470    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
471
472    // This is the amount of time an app needs to be running a foreground service before
473    // we will consider it to be doing interaction for usage stats.
474    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
475
476    // Maximum amount of time we will allow to elapse before re-reporting usage stats
477    // interaction with foreground processes.
478    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
479
480    // This is the amount of time we allow an app to settle after it goes into the background,
481    // before we start restricting what it can do.
482    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
483
484    // How long to wait in getAssistContextExtras for the activity and foreground services
485    // to respond with the result.
486    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
487
488    // How long top wait when going through the modern assist (which doesn't need to block
489    // on getting this result before starting to launch its UI).
490    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
491
492    // Maximum number of persisted Uri grants a package is allowed
493    static final int MAX_PERSISTED_URI_GRANTS = 128;
494
495    static final int MY_PID = Process.myPid();
496
497    static final String[] EMPTY_STRING_ARRAY = new String[0];
498
499    // How many bytes to write into the dropbox log before truncating
500    static final int DROPBOX_MAX_SIZE = 256 * 1024;
501
502    // Access modes for handleIncomingUser.
503    static final int ALLOW_NON_FULL = 0;
504    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
505    static final int ALLOW_FULL_ONLY = 2;
506
507    // Delay in notifying task stack change listeners (in millis)
508    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
509
510    // Necessary ApplicationInfo flags to mark an app as persistent
511    private static final int PERSISTENT_MASK =
512            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
513
514    // Intent sent when remote bugreport collection has been completed
515    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
516            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
517
518    // Delay to disable app launch boost
519    static final int APP_BOOST_MESSAGE_DELAY = 3000;
520    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
521    static final int APP_BOOST_TIMEOUT = 2500;
522
523    // Used to indicate that a task is removed it should also be removed from recents.
524    private static final boolean REMOVE_FROM_RECENTS = true;
525    // Used to indicate that an app transition should be animated.
526    static final boolean ANIMATE = true;
527
528    // Determines whether to take full screen screenshots
529    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
530    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
531
532    private static native int nativeMigrateToBoost();
533    private static native int nativeMigrateFromBoost();
534    private boolean mIsBoosted = false;
535    private long mBoostStartTime = 0;
536
537    /** All system services */
538    SystemServiceManager mSystemServiceManager;
539
540    private Installer mInstaller;
541
542    /** Run all ActivityStacks through this */
543    final ActivityStackSupervisor mStackSupervisor;
544
545    final ActivityStarter mActivityStarter;
546
547    /** Task stack change listeners. */
548    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
549            new RemoteCallbackList<ITaskStackListener>();
550
551    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
552
553    public IntentFirewall mIntentFirewall;
554
555    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
556    // default actuion automatically.  Important for devices without direct input
557    // devices.
558    private boolean mShowDialogs = true;
559    private boolean mInVrMode = false;
560
561    BroadcastQueue mFgBroadcastQueue;
562    BroadcastQueue mBgBroadcastQueue;
563    // Convenient for easy iteration over the queues. Foreground is first
564    // so that dispatch of foreground broadcasts gets precedence.
565    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
566
567    BroadcastQueue broadcastQueueForIntent(Intent intent) {
568        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
569        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
570                "Broadcast intent " + intent + " on "
571                + (isFg ? "foreground" : "background") + " queue");
572        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
573    }
574
575    /**
576     * Activity we have told the window manager to have key focus.
577     */
578    ActivityRecord mFocusedActivity = null;
579
580    /**
581     * User id of the last activity mFocusedActivity was set to.
582     */
583    private int mLastFocusedUserId;
584
585    /**
586     * If non-null, we are tracking the time the user spends in the currently focused app.
587     */
588    private AppTimeTracker mCurAppTimeTracker;
589
590    /**
591     * List of intents that were used to start the most recent tasks.
592     */
593    final RecentTasks mRecentTasks;
594
595    /**
596     * For addAppTask: cached of the last activity component that was added.
597     */
598    ComponentName mLastAddedTaskComponent;
599
600    /**
601     * For addAppTask: cached of the last activity uid that was added.
602     */
603    int mLastAddedTaskUid;
604
605    /**
606     * For addAppTask: cached of the last ActivityInfo that was added.
607     */
608    ActivityInfo mLastAddedTaskActivity;
609
610    /**
611     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
612     */
613    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
614
615    /**
616     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
617     */
618    String mDeviceOwnerName;
619
620    final UserController mUserController;
621
622    final AppErrors mAppErrors;
623
624    boolean mDoingSetFocusedActivity;
625
626    public boolean canShowErrorDialogs() {
627        return mShowDialogs && !mSleeping && !mShuttingDown;
628    }
629
630    public class PendingAssistExtras extends Binder implements Runnable {
631        public final ActivityRecord activity;
632        public final Bundle extras;
633        public final Intent intent;
634        public final String hint;
635        public final IResultReceiver receiver;
636        public final int userHandle;
637        public boolean haveResult = false;
638        public Bundle result = null;
639        public AssistStructure structure = null;
640        public AssistContent content = null;
641        public Bundle receiverExtras;
642
643        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
644                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
645            activity = _activity;
646            extras = _extras;
647            intent = _intent;
648            hint = _hint;
649            receiver = _receiver;
650            receiverExtras = _receiverExtras;
651            userHandle = _userHandle;
652        }
653        @Override
654        public void run() {
655            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
656            synchronized (this) {
657                haveResult = true;
658                notifyAll();
659            }
660            pendingAssistExtrasTimedOut(this);
661        }
662    }
663
664    final ArrayList<PendingAssistExtras> mPendingAssistExtras
665            = new ArrayList<PendingAssistExtras>();
666
667    /**
668     * Process management.
669     */
670    final ProcessList mProcessList = new ProcessList();
671
672    /**
673     * All of the applications we currently have running organized by name.
674     * The keys are strings of the application package name (as
675     * returned by the package manager), and the keys are ApplicationRecord
676     * objects.
677     */
678    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
679
680    /**
681     * Tracking long-term execution of processes to look for abuse and other
682     * bad app behavior.
683     */
684    final ProcessStatsService mProcessStats;
685
686    /**
687     * The currently running isolated processes.
688     */
689    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
690
691    /**
692     * Counter for assigning isolated process uids, to avoid frequently reusing the
693     * same ones.
694     */
695    int mNextIsolatedProcessUid = 0;
696
697    /**
698     * The currently running heavy-weight process, if any.
699     */
700    ProcessRecord mHeavyWeightProcess = null;
701
702    /**
703     * All of the processes we currently have running organized by pid.
704     * The keys are the pid running the application.
705     *
706     * <p>NOTE: This object is protected by its own lock, NOT the global
707     * activity manager lock!
708     */
709    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
710
711    /**
712     * All of the processes that have been forced to be foreground.  The key
713     * is the pid of the caller who requested it (we hold a death
714     * link on it).
715     */
716    abstract class ForegroundToken implements IBinder.DeathRecipient {
717        int pid;
718        IBinder token;
719    }
720    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
721
722    /**
723     * List of records for processes that someone had tried to start before the
724     * system was ready.  We don't start them at that point, but ensure they
725     * are started by the time booting is complete.
726     */
727    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
728
729    /**
730     * List of persistent applications that are in the process
731     * of being started.
732     */
733    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
734
735    /**
736     * Processes that are being forcibly torn down.
737     */
738    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
739
740    /**
741     * List of running applications, sorted by recent usage.
742     * The first entry in the list is the least recently used.
743     */
744    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
745
746    /**
747     * Where in mLruProcesses that the processes hosting activities start.
748     */
749    int mLruProcessActivityStart = 0;
750
751    /**
752     * Where in mLruProcesses that the processes hosting services start.
753     * This is after (lower index) than mLruProcessesActivityStart.
754     */
755    int mLruProcessServiceStart = 0;
756
757    /**
758     * List of processes that should gc as soon as things are idle.
759     */
760    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
761
762    /**
763     * Processes we want to collect PSS data from.
764     */
765    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
766
767    private boolean mBinderTransactionTrackingEnabled = false;
768
769    /**
770     * Last time we requested PSS data of all processes.
771     */
772    long mLastFullPssTime = SystemClock.uptimeMillis();
773
774    /**
775     * If set, the next time we collect PSS data we should do a full collection
776     * with data from native processes and the kernel.
777     */
778    boolean mFullPssPending = false;
779
780    /**
781     * This is the process holding what we currently consider to be
782     * the "home" activity.
783     */
784    ProcessRecord mHomeProcess;
785
786    /**
787     * This is the process holding the activity the user last visited that
788     * is in a different process from the one they are currently in.
789     */
790    ProcessRecord mPreviousProcess;
791
792    /**
793     * The time at which the previous process was last visible.
794     */
795    long mPreviousProcessVisibleTime;
796
797    /**
798     * Track all uids that have actively running processes.
799     */
800    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
801
802    /**
803     * This is for verifying the UID report flow.
804     */
805    static final boolean VALIDATE_UID_STATES = true;
806    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
807
808    /**
809     * Packages that the user has asked to have run in screen size
810     * compatibility mode instead of filling the screen.
811     */
812    final CompatModePackages mCompatModePackages;
813
814    /**
815     * Set of IntentSenderRecord objects that are currently active.
816     */
817    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
818            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
819
820    /**
821     * Fingerprints (hashCode()) of stack traces that we've
822     * already logged DropBox entries for.  Guarded by itself.  If
823     * something (rogue user app) forces this over
824     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
825     */
826    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
827    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
828
829    /**
830     * Strict Mode background batched logging state.
831     *
832     * The string buffer is guarded by itself, and its lock is also
833     * used to determine if another batched write is already
834     * in-flight.
835     */
836    private final StringBuilder mStrictModeBuffer = new StringBuilder();
837
838    /**
839     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
840     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
841     */
842    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
843
844    /**
845     * Resolver for broadcast intents to registered receivers.
846     * Holds BroadcastFilter (subclass of IntentFilter).
847     */
848    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
849            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
850        @Override
851        protected boolean allowFilterResult(
852                BroadcastFilter filter, List<BroadcastFilter> dest) {
853            IBinder target = filter.receiverList.receiver.asBinder();
854            for (int i = dest.size() - 1; i >= 0; i--) {
855                if (dest.get(i).receiverList.receiver.asBinder() == target) {
856                    return false;
857                }
858            }
859            return true;
860        }
861
862        @Override
863        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
864            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
865                    || userId == filter.owningUserId) {
866                return super.newResult(filter, match, userId);
867            }
868            return null;
869        }
870
871        @Override
872        protected BroadcastFilter[] newArray(int size) {
873            return new BroadcastFilter[size];
874        }
875
876        @Override
877        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
878            return packageName.equals(filter.packageName);
879        }
880    };
881
882    /**
883     * State of all active sticky broadcasts per user.  Keys are the action of the
884     * sticky Intent, values are an ArrayList of all broadcasted intents with
885     * that action (which should usually be one).  The SparseArray is keyed
886     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
887     * for stickies that are sent to all users.
888     */
889    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
890            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
891
892    final ActiveServices mServices;
893
894    final static class Association {
895        final int mSourceUid;
896        final String mSourceProcess;
897        final int mTargetUid;
898        final ComponentName mTargetComponent;
899        final String mTargetProcess;
900
901        int mCount;
902        long mTime;
903
904        int mNesting;
905        long mStartTime;
906
907        // states of the source process when the bind occurred.
908        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
909        long mLastStateUptime;
910        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
911                - ActivityManager.MIN_PROCESS_STATE+1];
912
913        Association(int sourceUid, String sourceProcess, int targetUid,
914                ComponentName targetComponent, String targetProcess) {
915            mSourceUid = sourceUid;
916            mSourceProcess = sourceProcess;
917            mTargetUid = targetUid;
918            mTargetComponent = targetComponent;
919            mTargetProcess = targetProcess;
920        }
921    }
922
923    /**
924     * When service association tracking is enabled, this is all of the associations we
925     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
926     * -> association data.
927     */
928    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
929            mAssociations = new SparseArray<>();
930    boolean mTrackingAssociations;
931
932    /**
933     * Backup/restore process management
934     */
935    String mBackupAppName = null;
936    BackupRecord mBackupTarget = null;
937
938    final ProviderMap mProviderMap;
939
940    /**
941     * List of content providers who have clients waiting for them.  The
942     * application is currently being launched and the provider will be
943     * removed from this list once it is published.
944     */
945    final ArrayList<ContentProviderRecord> mLaunchingProviders
946            = new ArrayList<ContentProviderRecord>();
947
948    /**
949     * File storing persisted {@link #mGrantedUriPermissions}.
950     */
951    private final AtomicFile mGrantFile;
952
953    /** XML constants used in {@link #mGrantFile} */
954    private static final String TAG_URI_GRANTS = "uri-grants";
955    private static final String TAG_URI_GRANT = "uri-grant";
956    private static final String ATTR_USER_HANDLE = "userHandle";
957    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
958    private static final String ATTR_TARGET_USER_ID = "targetUserId";
959    private static final String ATTR_SOURCE_PKG = "sourcePkg";
960    private static final String ATTR_TARGET_PKG = "targetPkg";
961    private static final String ATTR_URI = "uri";
962    private static final String ATTR_MODE_FLAGS = "modeFlags";
963    private static final String ATTR_CREATED_TIME = "createdTime";
964    private static final String ATTR_PREFIX = "prefix";
965
966    /**
967     * Global set of specific {@link Uri} permissions that have been granted.
968     * This optimized lookup structure maps from {@link UriPermission#targetUid}
969     * to {@link UriPermission#uri} to {@link UriPermission}.
970     */
971    @GuardedBy("this")
972    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
973            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
974
975    public static class GrantUri {
976        public final int sourceUserId;
977        public final Uri uri;
978        public boolean prefix;
979
980        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
981            this.sourceUserId = sourceUserId;
982            this.uri = uri;
983            this.prefix = prefix;
984        }
985
986        @Override
987        public int hashCode() {
988            int hashCode = 1;
989            hashCode = 31 * hashCode + sourceUserId;
990            hashCode = 31 * hashCode + uri.hashCode();
991            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
992            return hashCode;
993        }
994
995        @Override
996        public boolean equals(Object o) {
997            if (o instanceof GrantUri) {
998                GrantUri other = (GrantUri) o;
999                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1000                        && prefix == other.prefix;
1001            }
1002            return false;
1003        }
1004
1005        @Override
1006        public String toString() {
1007            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1008            if (prefix) result += " [prefix]";
1009            return result;
1010        }
1011
1012        public String toSafeString() {
1013            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1014            if (prefix) result += " [prefix]";
1015            return result;
1016        }
1017
1018        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1019            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1020                    ContentProvider.getUriWithoutUserId(uri), false);
1021        }
1022    }
1023
1024    CoreSettingsObserver mCoreSettingsObserver;
1025
1026    FontScaleSettingObserver mFontScaleSettingObserver;
1027
1028    private final class FontScaleSettingObserver extends ContentObserver {
1029        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1030
1031        public FontScaleSettingObserver() {
1032            super(mHandler);
1033            ContentResolver resolver = mContext.getContentResolver();
1034            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1035        }
1036
1037        @Override
1038        public void onChange(boolean selfChange, Uri uri) {
1039            if (mFontScaleUri.equals(uri)) {
1040                updateFontScaleIfNeeded();
1041            }
1042        }
1043    }
1044
1045    /**
1046     * Thread-local storage used to carry caller permissions over through
1047     * indirect content-provider access.
1048     */
1049    private class Identity {
1050        public final IBinder token;
1051        public final int pid;
1052        public final int uid;
1053
1054        Identity(IBinder _token, int _pid, int _uid) {
1055            token = _token;
1056            pid = _pid;
1057            uid = _uid;
1058        }
1059    }
1060
1061    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1062
1063    /**
1064     * All information we have collected about the runtime performance of
1065     * any user id that can impact battery performance.
1066     */
1067    final BatteryStatsService mBatteryStatsService;
1068
1069    /**
1070     * Information about component usage
1071     */
1072    UsageStatsManagerInternal mUsageStatsService;
1073
1074    /**
1075     * Access to DeviceIdleController service.
1076     */
1077    DeviceIdleController.LocalService mLocalDeviceIdleController;
1078
1079    /**
1080     * Information about and control over application operations
1081     */
1082    final AppOpsService mAppOpsService;
1083
1084    /**
1085     * Current configuration information.  HistoryRecord objects are given
1086     * a reference to this object to indicate which configuration they are
1087     * currently running in, so this object must be kept immutable.
1088     */
1089    Configuration mConfiguration = new Configuration();
1090
1091    /**
1092     * Current sequencing integer of the configuration, for skipping old
1093     * configurations.
1094     */
1095    int mConfigurationSeq = 0;
1096
1097    boolean mSuppressResizeConfigChanges = false;
1098
1099    /**
1100     * Hardware-reported OpenGLES version.
1101     */
1102    final int GL_ES_VERSION;
1103
1104    /**
1105     * List of initialization arguments to pass to all processes when binding applications to them.
1106     * For example, references to the commonly used services.
1107     */
1108    HashMap<String, IBinder> mAppBindArgs;
1109
1110    /**
1111     * Temporary to avoid allocations.  Protected by main lock.
1112     */
1113    final StringBuilder mStringBuilder = new StringBuilder(256);
1114
1115    /**
1116     * Used to control how we initialize the service.
1117     */
1118    ComponentName mTopComponent;
1119    String mTopAction = Intent.ACTION_MAIN;
1120    String mTopData;
1121
1122    volatile boolean mProcessesReady = false;
1123    volatile boolean mSystemReady = false;
1124    volatile boolean mOnBattery = false;
1125    volatile int mFactoryTest;
1126
1127    @GuardedBy("this") boolean mBooting = false;
1128    @GuardedBy("this") boolean mCallFinishBooting = false;
1129    @GuardedBy("this") boolean mBootAnimationComplete = false;
1130    @GuardedBy("this") boolean mLaunchWarningShown = false;
1131    @GuardedBy("this") boolean mCheckedForSetup = false;
1132
1133    Context mContext;
1134
1135    /**
1136     * The time at which we will allow normal application switches again,
1137     * after a call to {@link #stopAppSwitches()}.
1138     */
1139    long mAppSwitchesAllowedTime;
1140
1141    /**
1142     * This is set to true after the first switch after mAppSwitchesAllowedTime
1143     * is set; any switches after that will clear the time.
1144     */
1145    boolean mDidAppSwitch;
1146
1147    /**
1148     * Last time (in realtime) at which we checked for power usage.
1149     */
1150    long mLastPowerCheckRealtime;
1151
1152    /**
1153     * Last time (in uptime) at which we checked for power usage.
1154     */
1155    long mLastPowerCheckUptime;
1156
1157    /**
1158     * Set while we are wanting to sleep, to prevent any
1159     * activities from being started/resumed.
1160     */
1161    private boolean mSleeping = false;
1162
1163    /**
1164     * The process state used for processes that are running the top activities.
1165     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1166     */
1167    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1168
1169    /**
1170     * Set while we are running a voice interaction.  This overrides
1171     * sleeping while it is active.
1172     */
1173    private IVoiceInteractionSession mRunningVoice;
1174
1175    /**
1176     * For some direct access we need to power manager.
1177     */
1178    PowerManagerInternal mLocalPowerManager;
1179
1180    /**
1181     * We want to hold a wake lock while running a voice interaction session, since
1182     * this may happen with the screen off and we need to keep the CPU running to
1183     * be able to continue to interact with the user.
1184     */
1185    PowerManager.WakeLock mVoiceWakeLock;
1186
1187    /**
1188     * State of external calls telling us if the device is awake or asleep.
1189     */
1190    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1191
1192    /**
1193     * A list of tokens that cause the top activity to be put to sleep.
1194     * They are used by components that may hide and block interaction with underlying
1195     * activities.
1196     */
1197    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1198
1199    static final int LOCK_SCREEN_HIDDEN = 0;
1200    static final int LOCK_SCREEN_LEAVING = 1;
1201    static final int LOCK_SCREEN_SHOWN = 2;
1202    /**
1203     * State of external call telling us if the lock screen is shown.
1204     */
1205    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1206
1207    /**
1208     * Set if we are shutting down the system, similar to sleeping.
1209     */
1210    boolean mShuttingDown = false;
1211
1212    /**
1213     * Current sequence id for oom_adj computation traversal.
1214     */
1215    int mAdjSeq = 0;
1216
1217    /**
1218     * Current sequence id for process LRU updating.
1219     */
1220    int mLruSeq = 0;
1221
1222    /**
1223     * Keep track of the non-cached/empty process we last found, to help
1224     * determine how to distribute cached/empty processes next time.
1225     */
1226    int mNumNonCachedProcs = 0;
1227
1228    /**
1229     * Keep track of the number of cached hidden procs, to balance oom adj
1230     * distribution between those and empty procs.
1231     */
1232    int mNumCachedHiddenProcs = 0;
1233
1234    /**
1235     * Keep track of the number of service processes we last found, to
1236     * determine on the next iteration which should be B services.
1237     */
1238    int mNumServiceProcs = 0;
1239    int mNewNumAServiceProcs = 0;
1240    int mNewNumServiceProcs = 0;
1241
1242    /**
1243     * Allow the current computed overall memory level of the system to go down?
1244     * This is set to false when we are killing processes for reasons other than
1245     * memory management, so that the now smaller process list will not be taken as
1246     * an indication that memory is tighter.
1247     */
1248    boolean mAllowLowerMemLevel = false;
1249
1250    /**
1251     * The last computed memory level, for holding when we are in a state that
1252     * processes are going away for other reasons.
1253     */
1254    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1255
1256    /**
1257     * The last total number of process we have, to determine if changes actually look
1258     * like a shrinking number of process due to lower RAM.
1259     */
1260    int mLastNumProcesses;
1261
1262    /**
1263     * The uptime of the last time we performed idle maintenance.
1264     */
1265    long mLastIdleTime = SystemClock.uptimeMillis();
1266
1267    /**
1268     * Total time spent with RAM that has been added in the past since the last idle time.
1269     */
1270    long mLowRamTimeSinceLastIdle = 0;
1271
1272    /**
1273     * If RAM is currently low, when that horrible situation started.
1274     */
1275    long mLowRamStartTime = 0;
1276
1277    /**
1278     * For reporting to battery stats the current top application.
1279     */
1280    private String mCurResumedPackage = null;
1281    private int mCurResumedUid = -1;
1282
1283    /**
1284     * For reporting to battery stats the apps currently running foreground
1285     * service.  The ProcessMap is package/uid tuples; each of these contain
1286     * an array of the currently foreground processes.
1287     */
1288    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1289            = new ProcessMap<ArrayList<ProcessRecord>>();
1290
1291    /**
1292     * This is set if we had to do a delayed dexopt of an app before launching
1293     * it, to increase the ANR timeouts in that case.
1294     */
1295    boolean mDidDexOpt;
1296
1297    /**
1298     * Set if the systemServer made a call to enterSafeMode.
1299     */
1300    boolean mSafeMode;
1301
1302    /**
1303     * If true, we are running under a test environment so will sample PSS from processes
1304     * much more rapidly to try to collect better data when the tests are rapidly
1305     * running through apps.
1306     */
1307    boolean mTestPssMode = false;
1308
1309    String mDebugApp = null;
1310    boolean mWaitForDebugger = false;
1311    boolean mDebugTransient = false;
1312    String mOrigDebugApp = null;
1313    boolean mOrigWaitForDebugger = false;
1314    boolean mAlwaysFinishActivities = false;
1315    boolean mLenientBackgroundCheck = false;
1316    boolean mForceResizableActivities;
1317    boolean mSupportsMultiWindow;
1318    boolean mSupportsFreeformWindowManagement;
1319    boolean mSupportsPictureInPicture;
1320    Rect mDefaultPinnedStackBounds;
1321    IActivityController mController = null;
1322    boolean mControllerIsAMonkey = false;
1323    String mProfileApp = null;
1324    ProcessRecord mProfileProc = null;
1325    String mProfileFile;
1326    ParcelFileDescriptor mProfileFd;
1327    int mSamplingInterval = 0;
1328    boolean mAutoStopProfiler = false;
1329    int mProfileType = 0;
1330    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1331    String mMemWatchDumpProcName;
1332    String mMemWatchDumpFile;
1333    int mMemWatchDumpPid;
1334    int mMemWatchDumpUid;
1335    String mTrackAllocationApp = null;
1336    String mNativeDebuggingApp = null;
1337
1338    final long[] mTmpLong = new long[2];
1339
1340    static final class ProcessChangeItem {
1341        static final int CHANGE_ACTIVITIES = 1<<0;
1342        static final int CHANGE_PROCESS_STATE = 1<<1;
1343        int changes;
1344        int uid;
1345        int pid;
1346        int processState;
1347        boolean foregroundActivities;
1348    }
1349
1350    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1351    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1352
1353    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1354    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1355
1356    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1357    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1358
1359    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1360    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1361
1362    /**
1363     * Runtime CPU use collection thread.  This object's lock is used to
1364     * perform synchronization with the thread (notifying it to run).
1365     */
1366    final Thread mProcessCpuThread;
1367
1368    /**
1369     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1370     * Must acquire this object's lock when accessing it.
1371     * NOTE: this lock will be held while doing long operations (trawling
1372     * through all processes in /proc), so it should never be acquired by
1373     * any critical paths such as when holding the main activity manager lock.
1374     */
1375    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1376            MONITOR_THREAD_CPU_USAGE);
1377    final AtomicLong mLastCpuTime = new AtomicLong(0);
1378    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1379
1380    long mLastWriteTime = 0;
1381
1382    /**
1383     * Used to retain an update lock when the foreground activity is in
1384     * immersive mode.
1385     */
1386    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1387
1388    /**
1389     * Set to true after the system has finished booting.
1390     */
1391    boolean mBooted = false;
1392
1393    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1394    int mProcessLimitOverride = -1;
1395
1396    WindowManagerService mWindowManager;
1397    final ActivityThread mSystemThread;
1398
1399    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1400        final ProcessRecord mApp;
1401        final int mPid;
1402        final IApplicationThread mAppThread;
1403
1404        AppDeathRecipient(ProcessRecord app, int pid,
1405                IApplicationThread thread) {
1406            if (DEBUG_ALL) Slog.v(
1407                TAG, "New death recipient " + this
1408                + " for thread " + thread.asBinder());
1409            mApp = app;
1410            mPid = pid;
1411            mAppThread = thread;
1412        }
1413
1414        @Override
1415        public void binderDied() {
1416            if (DEBUG_ALL) Slog.v(
1417                TAG, "Death received in " + this
1418                + " for thread " + mAppThread.asBinder());
1419            synchronized(ActivityManagerService.this) {
1420                appDiedLocked(mApp, mPid, mAppThread, true);
1421            }
1422        }
1423    }
1424
1425    static final int SHOW_ERROR_UI_MSG = 1;
1426    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1427    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1428    static final int UPDATE_CONFIGURATION_MSG = 4;
1429    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1430    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1431    static final int SERVICE_TIMEOUT_MSG = 12;
1432    static final int UPDATE_TIME_ZONE = 13;
1433    static final int SHOW_UID_ERROR_UI_MSG = 14;
1434    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1435    static final int PROC_START_TIMEOUT_MSG = 20;
1436    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1437    static final int KILL_APPLICATION_MSG = 22;
1438    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1439    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1440    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1441    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1442    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1443    static final int CLEAR_DNS_CACHE_MSG = 28;
1444    static final int UPDATE_HTTP_PROXY_MSG = 29;
1445    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1446    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1447    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1448    static final int REPORT_MEM_USAGE_MSG = 33;
1449    static final int REPORT_USER_SWITCH_MSG = 34;
1450    static final int CONTINUE_USER_SWITCH_MSG = 35;
1451    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1452    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1453    static final int PERSIST_URI_GRANTS_MSG = 38;
1454    static final int REQUEST_ALL_PSS_MSG = 39;
1455    static final int START_PROFILES_MSG = 40;
1456    static final int UPDATE_TIME = 41;
1457    static final int SYSTEM_USER_START_MSG = 42;
1458    static final int SYSTEM_USER_CURRENT_MSG = 43;
1459    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1460    static final int FINISH_BOOTING_MSG = 45;
1461    static final int START_USER_SWITCH_UI_MSG = 46;
1462    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1463    static final int DISMISS_DIALOG_UI_MSG = 48;
1464    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1465    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1466    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1467    static final int DELETE_DUMPHEAP_MSG = 52;
1468    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1469    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1470    static final int REPORT_TIME_TRACKER_MSG = 55;
1471    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1472    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1473    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1474    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1475    static final int IDLE_UIDS_MSG = 60;
1476    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1477    static final int LOG_STACK_STATE = 62;
1478    static final int VR_MODE_CHANGE_MSG = 63;
1479    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1480    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1481    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1482    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1483    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1484    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1485
1486    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1487    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1488    static final int FIRST_COMPAT_MODE_MSG = 300;
1489    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1490
1491    static ServiceThread sKillThread = null;
1492    static KillHandler sKillHandler = null;
1493
1494    CompatModeDialog mCompatModeDialog;
1495    long mLastMemUsageReportTime = 0;
1496
1497    /**
1498     * Flag whether the current user is a "monkey", i.e. whether
1499     * the UI is driven by a UI automation tool.
1500     */
1501    private boolean mUserIsMonkey;
1502
1503    /** Flag whether the device has a Recents UI */
1504    boolean mHasRecents;
1505
1506    /** The dimensions of the thumbnails in the Recents UI. */
1507    int mThumbnailWidth;
1508    int mThumbnailHeight;
1509    float mFullscreenThumbnailScale;
1510
1511    final ServiceThread mHandlerThread;
1512    final MainHandler mHandler;
1513    final UiHandler mUiHandler;
1514
1515    PackageManagerInternal mPackageManagerInt;
1516
1517    // VoiceInteraction session ID that changes for each new request except when
1518    // being called for multiwindow assist in a single session.
1519    private int mViSessionId = 1000;
1520
1521    final class KillHandler extends Handler {
1522        static final int KILL_PROCESS_GROUP_MSG = 4000;
1523
1524        public KillHandler(Looper looper) {
1525            super(looper, null, true);
1526        }
1527
1528        @Override
1529        public void handleMessage(Message msg) {
1530            switch (msg.what) {
1531                case KILL_PROCESS_GROUP_MSG:
1532                {
1533                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1534                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1535                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1536                }
1537                break;
1538
1539                default:
1540                    super.handleMessage(msg);
1541            }
1542        }
1543    }
1544
1545    final class UiHandler extends Handler {
1546        public UiHandler() {
1547            super(com.android.server.UiThread.get().getLooper(), null, true);
1548        }
1549
1550        @Override
1551        public void handleMessage(Message msg) {
1552            switch (msg.what) {
1553            case SHOW_ERROR_UI_MSG: {
1554                mAppErrors.handleShowAppErrorUi(msg);
1555                ensureBootCompleted();
1556            } break;
1557            case SHOW_NOT_RESPONDING_UI_MSG: {
1558                mAppErrors.handleShowAnrUi(msg);
1559                ensureBootCompleted();
1560            } break;
1561            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1562                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1563                synchronized (ActivityManagerService.this) {
1564                    ProcessRecord proc = (ProcessRecord) data.get("app");
1565                    if (proc == null) {
1566                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1567                        break;
1568                    }
1569                    if (proc.crashDialog != null) {
1570                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1571                        return;
1572                    }
1573                    AppErrorResult res = (AppErrorResult) data.get("result");
1574                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1575                        Dialog d = new StrictModeViolationDialog(mContext,
1576                                ActivityManagerService.this, res, proc);
1577                        d.show();
1578                        proc.crashDialog = d;
1579                    } else {
1580                        // The device is asleep, so just pretend that the user
1581                        // saw a crash dialog and hit "force quit".
1582                        res.set(0);
1583                    }
1584                }
1585                ensureBootCompleted();
1586            } break;
1587            case SHOW_FACTORY_ERROR_UI_MSG: {
1588                Dialog d = new FactoryErrorDialog(
1589                    mContext, msg.getData().getCharSequence("msg"));
1590                d.show();
1591                ensureBootCompleted();
1592            } break;
1593            case WAIT_FOR_DEBUGGER_UI_MSG: {
1594                synchronized (ActivityManagerService.this) {
1595                    ProcessRecord app = (ProcessRecord)msg.obj;
1596                    if (msg.arg1 != 0) {
1597                        if (!app.waitedForDebugger) {
1598                            Dialog d = new AppWaitingForDebuggerDialog(
1599                                    ActivityManagerService.this,
1600                                    mContext, app);
1601                            app.waitDialog = d;
1602                            app.waitedForDebugger = true;
1603                            d.show();
1604                        }
1605                    } else {
1606                        if (app.waitDialog != null) {
1607                            app.waitDialog.dismiss();
1608                            app.waitDialog = null;
1609                        }
1610                    }
1611                }
1612            } break;
1613            case SHOW_UID_ERROR_UI_MSG: {
1614                if (mShowDialogs) {
1615                    AlertDialog d = new BaseErrorDialog(mContext);
1616                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1617                    d.setCancelable(false);
1618                    d.setTitle(mContext.getText(R.string.android_system_label));
1619                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1620                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1621                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1622                    d.show();
1623                }
1624            } break;
1625            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1626                if (mShowDialogs) {
1627                    AlertDialog d = new BaseErrorDialog(mContext);
1628                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1629                    d.setCancelable(false);
1630                    d.setTitle(mContext.getText(R.string.android_system_label));
1631                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1632                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1633                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1634                    d.show();
1635                }
1636            } break;
1637            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1638                synchronized (ActivityManagerService.this) {
1639                    ActivityRecord ar = (ActivityRecord) msg.obj;
1640                    if (mCompatModeDialog != null) {
1641                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1642                                ar.info.applicationInfo.packageName)) {
1643                            return;
1644                        }
1645                        mCompatModeDialog.dismiss();
1646                        mCompatModeDialog = null;
1647                    }
1648                    if (ar != null && false) {
1649                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1650                                ar.packageName)) {
1651                            int mode = mCompatModePackages.computeCompatModeLocked(
1652                                    ar.info.applicationInfo);
1653                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1654                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1655                                mCompatModeDialog = new CompatModeDialog(
1656                                        ActivityManagerService.this, mContext,
1657                                        ar.info.applicationInfo);
1658                                mCompatModeDialog.show();
1659                            }
1660                        }
1661                    }
1662                }
1663                break;
1664            }
1665            case START_USER_SWITCH_UI_MSG: {
1666                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1667                break;
1668            }
1669            case DISMISS_DIALOG_UI_MSG: {
1670                final Dialog d = (Dialog) msg.obj;
1671                d.dismiss();
1672                break;
1673            }
1674            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1675                dispatchProcessesChanged();
1676                break;
1677            }
1678            case DISPATCH_PROCESS_DIED_UI_MSG: {
1679                final int pid = msg.arg1;
1680                final int uid = msg.arg2;
1681                dispatchProcessDied(pid, uid);
1682                break;
1683            }
1684            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1685                dispatchUidsChanged();
1686            } break;
1687            }
1688        }
1689    }
1690
1691    final class MainHandler extends Handler {
1692        public MainHandler(Looper looper) {
1693            super(looper, null, true);
1694        }
1695
1696        @Override
1697        public void handleMessage(Message msg) {
1698            switch (msg.what) {
1699            case UPDATE_CONFIGURATION_MSG: {
1700                final ContentResolver resolver = mContext.getContentResolver();
1701                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1702                        msg.arg1);
1703            } break;
1704            case GC_BACKGROUND_PROCESSES_MSG: {
1705                synchronized (ActivityManagerService.this) {
1706                    performAppGcsIfAppropriateLocked();
1707                }
1708            } break;
1709            case SERVICE_TIMEOUT_MSG: {
1710                if (mDidDexOpt) {
1711                    mDidDexOpt = false;
1712                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1713                    nmsg.obj = msg.obj;
1714                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1715                    return;
1716                }
1717                mServices.serviceTimeout((ProcessRecord)msg.obj);
1718            } break;
1719            case UPDATE_TIME_ZONE: {
1720                synchronized (ActivityManagerService.this) {
1721                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1722                        ProcessRecord r = mLruProcesses.get(i);
1723                        if (r.thread != null) {
1724                            try {
1725                                r.thread.updateTimeZone();
1726                            } catch (RemoteException ex) {
1727                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1728                            }
1729                        }
1730                    }
1731                }
1732            } break;
1733            case CLEAR_DNS_CACHE_MSG: {
1734                synchronized (ActivityManagerService.this) {
1735                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1736                        ProcessRecord r = mLruProcesses.get(i);
1737                        if (r.thread != null) {
1738                            try {
1739                                r.thread.clearDnsCache();
1740                            } catch (RemoteException ex) {
1741                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1742                            }
1743                        }
1744                    }
1745                }
1746            } break;
1747            case UPDATE_HTTP_PROXY_MSG: {
1748                ProxyInfo proxy = (ProxyInfo)msg.obj;
1749                String host = "";
1750                String port = "";
1751                String exclList = "";
1752                Uri pacFileUrl = Uri.EMPTY;
1753                if (proxy != null) {
1754                    host = proxy.getHost();
1755                    port = Integer.toString(proxy.getPort());
1756                    exclList = proxy.getExclusionListAsString();
1757                    pacFileUrl = proxy.getPacFileUrl();
1758                }
1759                synchronized (ActivityManagerService.this) {
1760                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1761                        ProcessRecord r = mLruProcesses.get(i);
1762                        if (r.thread != null) {
1763                            try {
1764                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1765                            } catch (RemoteException ex) {
1766                                Slog.w(TAG, "Failed to update http proxy for: " +
1767                                        r.info.processName);
1768                            }
1769                        }
1770                    }
1771                }
1772            } break;
1773            case PROC_START_TIMEOUT_MSG: {
1774                if (mDidDexOpt) {
1775                    mDidDexOpt = false;
1776                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1777                    nmsg.obj = msg.obj;
1778                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1779                    return;
1780                }
1781                ProcessRecord app = (ProcessRecord)msg.obj;
1782                synchronized (ActivityManagerService.this) {
1783                    processStartTimedOutLocked(app);
1784                }
1785            } break;
1786            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1787                ProcessRecord app = (ProcessRecord)msg.obj;
1788                synchronized (ActivityManagerService.this) {
1789                    processContentProviderPublishTimedOutLocked(app);
1790                }
1791            } break;
1792            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1793                synchronized (ActivityManagerService.this) {
1794                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1795                }
1796            } break;
1797            case KILL_APPLICATION_MSG: {
1798                synchronized (ActivityManagerService.this) {
1799                    int appid = msg.arg1;
1800                    boolean restart = (msg.arg2 == 1);
1801                    Bundle bundle = (Bundle)msg.obj;
1802                    String pkg = bundle.getString("pkg");
1803                    String reason = bundle.getString("reason");
1804                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1805                            false, UserHandle.USER_ALL, reason);
1806                }
1807            } break;
1808            case FINALIZE_PENDING_INTENT_MSG: {
1809                ((PendingIntentRecord)msg.obj).completeFinalize();
1810            } break;
1811            case POST_HEAVY_NOTIFICATION_MSG: {
1812                INotificationManager inm = NotificationManager.getService();
1813                if (inm == null) {
1814                    return;
1815                }
1816
1817                ActivityRecord root = (ActivityRecord)msg.obj;
1818                ProcessRecord process = root.app;
1819                if (process == null) {
1820                    return;
1821                }
1822
1823                try {
1824                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1825                    String text = mContext.getString(R.string.heavy_weight_notification,
1826                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1827                    Notification notification = new Notification.Builder(context)
1828                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1829                            .setWhen(0)
1830                            .setOngoing(true)
1831                            .setTicker(text)
1832                            .setColor(mContext.getColor(
1833                                    com.android.internal.R.color.system_notification_accent_color))
1834                            .setContentTitle(text)
1835                            .setContentText(
1836                                    mContext.getText(R.string.heavy_weight_notification_detail))
1837                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1838                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1839                                    new UserHandle(root.userId)))
1840                            .build();
1841                    try {
1842                        int[] outId = new int[1];
1843                        inm.enqueueNotificationWithTag("android", "android", null,
1844                                R.string.heavy_weight_notification,
1845                                notification, outId, root.userId);
1846                    } catch (RuntimeException e) {
1847                        Slog.w(ActivityManagerService.TAG,
1848                                "Error showing notification for heavy-weight app", e);
1849                    } catch (RemoteException e) {
1850                    }
1851                } catch (NameNotFoundException e) {
1852                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1853                }
1854            } break;
1855            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1856                INotificationManager inm = NotificationManager.getService();
1857                if (inm == null) {
1858                    return;
1859                }
1860                try {
1861                    inm.cancelNotificationWithTag("android", null,
1862                            R.string.heavy_weight_notification,  msg.arg1);
1863                } catch (RuntimeException e) {
1864                    Slog.w(ActivityManagerService.TAG,
1865                            "Error canceling notification for service", e);
1866                } catch (RemoteException e) {
1867                }
1868            } break;
1869            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1870                synchronized (ActivityManagerService.this) {
1871                    checkExcessivePowerUsageLocked(true);
1872                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1873                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1874                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1875                }
1876            } break;
1877            case REPORT_MEM_USAGE_MSG: {
1878                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1879                Thread thread = new Thread() {
1880                    @Override public void run() {
1881                        reportMemUsage(memInfos);
1882                    }
1883                };
1884                thread.start();
1885                break;
1886            }
1887            case REPORT_USER_SWITCH_MSG: {
1888                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1889                break;
1890            }
1891            case CONTINUE_USER_SWITCH_MSG: {
1892                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1893                break;
1894            }
1895            case USER_SWITCH_TIMEOUT_MSG: {
1896                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1897                break;
1898            }
1899            case IMMERSIVE_MODE_LOCK_MSG: {
1900                final boolean nextState = (msg.arg1 != 0);
1901                if (mUpdateLock.isHeld() != nextState) {
1902                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1903                            "Applying new update lock state '" + nextState
1904                            + "' for " + (ActivityRecord)msg.obj);
1905                    if (nextState) {
1906                        mUpdateLock.acquire();
1907                    } else {
1908                        mUpdateLock.release();
1909                    }
1910                }
1911                break;
1912            }
1913            case PERSIST_URI_GRANTS_MSG: {
1914                writeGrantedUriPermissions();
1915                break;
1916            }
1917            case REQUEST_ALL_PSS_MSG: {
1918                synchronized (ActivityManagerService.this) {
1919                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1920                }
1921                break;
1922            }
1923            case START_PROFILES_MSG: {
1924                synchronized (ActivityManagerService.this) {
1925                    mUserController.startProfilesLocked();
1926                }
1927                break;
1928            }
1929            case UPDATE_TIME: {
1930                synchronized (ActivityManagerService.this) {
1931                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1932                        ProcessRecord r = mLruProcesses.get(i);
1933                        if (r.thread != null) {
1934                            try {
1935                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1936                            } catch (RemoteException ex) {
1937                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1938                            }
1939                        }
1940                    }
1941                }
1942                break;
1943            }
1944            case SYSTEM_USER_START_MSG: {
1945                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1946                        Integer.toString(msg.arg1), msg.arg1);
1947                mSystemServiceManager.startUser(msg.arg1);
1948                break;
1949            }
1950            case SYSTEM_USER_UNLOCK_MSG: {
1951                final int userId = msg.arg1;
1952                mSystemServiceManager.unlockUser(userId);
1953                synchronized (ActivityManagerService.this) {
1954                    mRecentTasks.loadUserRecentsLocked(userId);
1955                }
1956                if (userId == UserHandle.USER_SYSTEM) {
1957                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1958                }
1959                installEncryptionUnawareProviders(userId);
1960                mUserController.finishUserUnlocked((UserState) msg.obj);
1961                break;
1962            }
1963            case SYSTEM_USER_CURRENT_MSG: {
1964                mBatteryStatsService.noteEvent(
1965                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1966                        Integer.toString(msg.arg2), msg.arg2);
1967                mBatteryStatsService.noteEvent(
1968                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1969                        Integer.toString(msg.arg1), msg.arg1);
1970                mSystemServiceManager.switchUser(msg.arg1);
1971                break;
1972            }
1973            case ENTER_ANIMATION_COMPLETE_MSG: {
1974                synchronized (ActivityManagerService.this) {
1975                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1976                    if (r != null && r.app != null && r.app.thread != null) {
1977                        try {
1978                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1979                        } catch (RemoteException e) {
1980                        }
1981                    }
1982                }
1983                break;
1984            }
1985            case FINISH_BOOTING_MSG: {
1986                if (msg.arg1 != 0) {
1987                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1988                    finishBooting();
1989                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1990                }
1991                if (msg.arg2 != 0) {
1992                    enableScreenAfterBoot();
1993                }
1994                break;
1995            }
1996            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1997                try {
1998                    Locale l = (Locale) msg.obj;
1999                    IBinder service = ServiceManager.getService("mount");
2000                    IMountService mountService = IMountService.Stub.asInterface(service);
2001                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2002                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2003                } catch (RemoteException e) {
2004                    Log.e(TAG, "Error storing locale for decryption UI", e);
2005                }
2006                break;
2007            }
2008            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2009                synchronized (ActivityManagerService.this) {
2010                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2011                        try {
2012                            // Make a one-way callback to the listener
2013                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2014                        } catch (RemoteException e){
2015                            // Handled by the RemoteCallbackList
2016                        }
2017                    }
2018                    mTaskStackListeners.finishBroadcast();
2019                }
2020                break;
2021            }
2022            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2023                synchronized (ActivityManagerService.this) {
2024                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2025                        try {
2026                            // Make a one-way callback to the listener
2027                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2028                        } catch (RemoteException e){
2029                            // Handled by the RemoteCallbackList
2030                        }
2031                    }
2032                    mTaskStackListeners.finishBroadcast();
2033                }
2034                break;
2035            }
2036            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2037                synchronized (ActivityManagerService.this) {
2038                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2039                        try {
2040                            // Make a one-way callback to the listener
2041                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2042                        } catch (RemoteException e){
2043                            // Handled by the RemoteCallbackList
2044                        }
2045                    }
2046                    mTaskStackListeners.finishBroadcast();
2047                }
2048                break;
2049            }
2050            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2051                synchronized (ActivityManagerService.this) {
2052                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2053                        try {
2054                            // Make a one-way callback to the listener
2055                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2056                        } catch (RemoteException e){
2057                            // Handled by the RemoteCallbackList
2058                        }
2059                    }
2060                    mTaskStackListeners.finishBroadcast();
2061                }
2062                break;
2063            }
2064            case NOTIFY_FORCED_RESIZABLE_MSG: {
2065                synchronized (ActivityManagerService.this) {
2066                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2067                        try {
2068                            // Make a one-way callback to the listener
2069                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2070                                    (String) msg.obj, msg.arg1);
2071                        } catch (RemoteException e){
2072                            // Handled by the RemoteCallbackList
2073                        }
2074                    }
2075                    mTaskStackListeners.finishBroadcast();
2076                }
2077                break;
2078            }
2079                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2080                    synchronized (ActivityManagerService.this) {
2081                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2082                            try {
2083                                // Make a one-way callback to the listener
2084                                mTaskStackListeners.getBroadcastItem(i)
2085                                        .onActivityDismissingDockedStack();
2086                            } catch (RemoteException e){
2087                                // Handled by the RemoteCallbackList
2088                            }
2089                        }
2090                        mTaskStackListeners.finishBroadcast();
2091                    }
2092                    break;
2093                }
2094            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2095                final int uid = msg.arg1;
2096                final byte[] firstPacket = (byte[]) msg.obj;
2097
2098                synchronized (mPidsSelfLocked) {
2099                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2100                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2101                        if (p.uid == uid) {
2102                            try {
2103                                p.thread.notifyCleartextNetwork(firstPacket);
2104                            } catch (RemoteException ignored) {
2105                            }
2106                        }
2107                    }
2108                }
2109                break;
2110            }
2111            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2112                final String procName;
2113                final int uid;
2114                final long memLimit;
2115                final String reportPackage;
2116                synchronized (ActivityManagerService.this) {
2117                    procName = mMemWatchDumpProcName;
2118                    uid = mMemWatchDumpUid;
2119                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2120                    if (val == null) {
2121                        val = mMemWatchProcesses.get(procName, 0);
2122                    }
2123                    if (val != null) {
2124                        memLimit = val.first;
2125                        reportPackage = val.second;
2126                    } else {
2127                        memLimit = 0;
2128                        reportPackage = null;
2129                    }
2130                }
2131                if (procName == null) {
2132                    return;
2133                }
2134
2135                if (DEBUG_PSS) Slog.d(TAG_PSS,
2136                        "Showing dump heap notification from " + procName + "/" + uid);
2137
2138                INotificationManager inm = NotificationManager.getService();
2139                if (inm == null) {
2140                    return;
2141                }
2142
2143                String text = mContext.getString(R.string.dump_heap_notification, procName);
2144
2145
2146                Intent deleteIntent = new Intent();
2147                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2148                Intent intent = new Intent();
2149                intent.setClassName("android", DumpHeapActivity.class.getName());
2150                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2151                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2152                if (reportPackage != null) {
2153                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2154                }
2155                int userId = UserHandle.getUserId(uid);
2156                Notification notification = new Notification.Builder(mContext)
2157                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2158                        .setWhen(0)
2159                        .setOngoing(true)
2160                        .setAutoCancel(true)
2161                        .setTicker(text)
2162                        .setColor(mContext.getColor(
2163                                com.android.internal.R.color.system_notification_accent_color))
2164                        .setContentTitle(text)
2165                        .setContentText(
2166                                mContext.getText(R.string.dump_heap_notification_detail))
2167                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2168                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2169                                new UserHandle(userId)))
2170                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2171                                deleteIntent, 0, UserHandle.SYSTEM))
2172                        .build();
2173
2174                try {
2175                    int[] outId = new int[1];
2176                    inm.enqueueNotificationWithTag("android", "android", null,
2177                            R.string.dump_heap_notification,
2178                            notification, outId, userId);
2179                } catch (RuntimeException e) {
2180                    Slog.w(ActivityManagerService.TAG,
2181                            "Error showing notification for dump heap", e);
2182                } catch (RemoteException e) {
2183                }
2184            } break;
2185            case DELETE_DUMPHEAP_MSG: {
2186                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2187                        DumpHeapActivity.JAVA_URI,
2188                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2189                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2190                        UserHandle.myUserId());
2191                synchronized (ActivityManagerService.this) {
2192                    mMemWatchDumpFile = null;
2193                    mMemWatchDumpProcName = null;
2194                    mMemWatchDumpPid = -1;
2195                    mMemWatchDumpUid = -1;
2196                }
2197            } break;
2198            case FOREGROUND_PROFILE_CHANGED_MSG: {
2199                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2200            } break;
2201            case REPORT_TIME_TRACKER_MSG: {
2202                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2203                tracker.deliverResult(mContext);
2204            } break;
2205            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2206                mUserController.dispatchUserSwitchComplete(msg.arg1);
2207            } break;
2208            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2209                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2210                try {
2211                    connection.shutdown();
2212                } catch (RemoteException e) {
2213                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2214                }
2215                // Only a UiAutomation can set this flag and now that
2216                // it is finished we make sure it is reset to its default.
2217                mUserIsMonkey = false;
2218            } break;
2219            case APP_BOOST_DEACTIVATE_MSG: {
2220                synchronized(ActivityManagerService.this) {
2221                    if (mIsBoosted) {
2222                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2223                            nativeMigrateFromBoost();
2224                            mIsBoosted = false;
2225                            mBoostStartTime = 0;
2226                        } else {
2227                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2228                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2229                        }
2230                    }
2231                }
2232            } break;
2233            case IDLE_UIDS_MSG: {
2234                idleUids();
2235            } break;
2236            case LOG_STACK_STATE: {
2237                synchronized (ActivityManagerService.this) {
2238                    mStackSupervisor.logStackState();
2239                }
2240            } break;
2241            case VR_MODE_CHANGE_MSG: {
2242                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2243                final ActivityRecord r = (ActivityRecord) msg.obj;
2244                boolean vrMode;
2245                ComponentName requestedPackage;
2246                ComponentName callingPackage;
2247                int userId;
2248                synchronized (ActivityManagerService.this) {
2249                    vrMode = r.requestedVrComponent != null;
2250                    requestedPackage = r.requestedVrComponent;
2251                    userId = r.userId;
2252                    callingPackage = r.info.getComponentName();
2253                    if (mInVrMode != vrMode) {
2254                        mInVrMode = vrMode;
2255                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2256                    }
2257                }
2258                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2259            } break;
2260            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2261                final ActivityRecord r = (ActivityRecord) msg.obj;
2262                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2263                if (needsVrMode) {
2264                    VrManagerInternal vrService =
2265                            LocalServices.getService(VrManagerInternal.class);
2266                    boolean enable = msg.arg1 == 1;
2267                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2268                            r.info.getComponentName());
2269                }
2270            } break;
2271            }
2272        }
2273    };
2274
2275    static final int COLLECT_PSS_BG_MSG = 1;
2276
2277    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2278        @Override
2279        public void handleMessage(Message msg) {
2280            switch (msg.what) {
2281            case COLLECT_PSS_BG_MSG: {
2282                long start = SystemClock.uptimeMillis();
2283                MemInfoReader memInfo = null;
2284                synchronized (ActivityManagerService.this) {
2285                    if (mFullPssPending) {
2286                        mFullPssPending = false;
2287                        memInfo = new MemInfoReader();
2288                    }
2289                }
2290                if (memInfo != null) {
2291                    updateCpuStatsNow();
2292                    long nativeTotalPss = 0;
2293                    synchronized (mProcessCpuTracker) {
2294                        final int N = mProcessCpuTracker.countStats();
2295                        for (int j=0; j<N; j++) {
2296                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2297                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2298                                // This is definitely an application process; skip it.
2299                                continue;
2300                            }
2301                            synchronized (mPidsSelfLocked) {
2302                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2303                                    // This is one of our own processes; skip it.
2304                                    continue;
2305                                }
2306                            }
2307                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2308                        }
2309                    }
2310                    memInfo.readMemInfo();
2311                    synchronized (ActivityManagerService.this) {
2312                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2313                                + (SystemClock.uptimeMillis()-start) + "ms");
2314                        final long cachedKb = memInfo.getCachedSizeKb();
2315                        final long freeKb = memInfo.getFreeSizeKb();
2316                        final long zramKb = memInfo.getZramTotalSizeKb();
2317                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2318                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2319                                kernelKb*1024, nativeTotalPss*1024);
2320                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2321                                nativeTotalPss);
2322                    }
2323                }
2324
2325                int num = 0;
2326                long[] tmp = new long[2];
2327                do {
2328                    ProcessRecord proc;
2329                    int procState;
2330                    int pid;
2331                    long lastPssTime;
2332                    synchronized (ActivityManagerService.this) {
2333                        if (mPendingPssProcesses.size() <= 0) {
2334                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2335                                    "Collected PSS of " + num + " processes in "
2336                                    + (SystemClock.uptimeMillis() - start) + "ms");
2337                            mPendingPssProcesses.clear();
2338                            return;
2339                        }
2340                        proc = mPendingPssProcesses.remove(0);
2341                        procState = proc.pssProcState;
2342                        lastPssTime = proc.lastPssTime;
2343                        if (proc.thread != null && procState == proc.setProcState
2344                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2345                                        < SystemClock.uptimeMillis()) {
2346                            pid = proc.pid;
2347                        } else {
2348                            proc = null;
2349                            pid = 0;
2350                        }
2351                    }
2352                    if (proc != null) {
2353                        long pss = Debug.getPss(pid, tmp, null);
2354                        synchronized (ActivityManagerService.this) {
2355                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2356                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2357                                num++;
2358                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2359                                        SystemClock.uptimeMillis());
2360                            }
2361                        }
2362                    }
2363                } while (true);
2364            }
2365            }
2366        }
2367    };
2368
2369    public void setSystemProcess() {
2370        try {
2371            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2372            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2373            ServiceManager.addService("meminfo", new MemBinder(this));
2374            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2375            ServiceManager.addService("dbinfo", new DbBinder(this));
2376            if (MONITOR_CPU_USAGE) {
2377                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2378            }
2379            ServiceManager.addService("permission", new PermissionController(this));
2380            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2381
2382            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2383                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2384            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2385
2386            synchronized (this) {
2387                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2388                app.persistent = true;
2389                app.pid = MY_PID;
2390                app.maxAdj = ProcessList.SYSTEM_ADJ;
2391                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2392                synchronized (mPidsSelfLocked) {
2393                    mPidsSelfLocked.put(app.pid, app);
2394                }
2395                updateLruProcessLocked(app, false, null);
2396                updateOomAdjLocked();
2397            }
2398        } catch (PackageManager.NameNotFoundException e) {
2399            throw new RuntimeException(
2400                    "Unable to find android system package", e);
2401        }
2402    }
2403
2404    public void setWindowManager(WindowManagerService wm) {
2405        mWindowManager = wm;
2406        mStackSupervisor.setWindowManager(wm);
2407        mActivityStarter.setWindowManager(wm);
2408    }
2409
2410    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2411        mUsageStatsService = usageStatsManager;
2412    }
2413
2414    public void startObservingNativeCrashes() {
2415        final NativeCrashListener ncl = new NativeCrashListener(this);
2416        ncl.start();
2417    }
2418
2419    public IAppOpsService getAppOpsService() {
2420        return mAppOpsService;
2421    }
2422
2423    static class MemBinder extends Binder {
2424        ActivityManagerService mActivityManagerService;
2425        MemBinder(ActivityManagerService activityManagerService) {
2426            mActivityManagerService = activityManagerService;
2427        }
2428
2429        @Override
2430        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2431            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2432                    != PackageManager.PERMISSION_GRANTED) {
2433                pw.println("Permission Denial: can't dump meminfo from from pid="
2434                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2435                        + " without permission " + android.Manifest.permission.DUMP);
2436                return;
2437            }
2438
2439            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2440        }
2441    }
2442
2443    static class GraphicsBinder extends Binder {
2444        ActivityManagerService mActivityManagerService;
2445        GraphicsBinder(ActivityManagerService activityManagerService) {
2446            mActivityManagerService = activityManagerService;
2447        }
2448
2449        @Override
2450        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2451            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2452                    != PackageManager.PERMISSION_GRANTED) {
2453                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2454                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2455                        + " without permission " + android.Manifest.permission.DUMP);
2456                return;
2457            }
2458
2459            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2460        }
2461    }
2462
2463    static class DbBinder extends Binder {
2464        ActivityManagerService mActivityManagerService;
2465        DbBinder(ActivityManagerService activityManagerService) {
2466            mActivityManagerService = activityManagerService;
2467        }
2468
2469        @Override
2470        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2471            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2472                    != PackageManager.PERMISSION_GRANTED) {
2473                pw.println("Permission Denial: can't dump dbinfo from from pid="
2474                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2475                        + " without permission " + android.Manifest.permission.DUMP);
2476                return;
2477            }
2478
2479            mActivityManagerService.dumpDbInfo(fd, pw, args);
2480        }
2481    }
2482
2483    static class CpuBinder extends Binder {
2484        ActivityManagerService mActivityManagerService;
2485        CpuBinder(ActivityManagerService activityManagerService) {
2486            mActivityManagerService = activityManagerService;
2487        }
2488
2489        @Override
2490        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2491            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2492                    != PackageManager.PERMISSION_GRANTED) {
2493                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2494                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2495                        + " without permission " + android.Manifest.permission.DUMP);
2496                return;
2497            }
2498
2499            synchronized (mActivityManagerService.mProcessCpuTracker) {
2500                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2501                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2502                        SystemClock.uptimeMillis()));
2503            }
2504        }
2505    }
2506
2507    public static final class Lifecycle extends SystemService {
2508        private final ActivityManagerService mService;
2509
2510        public Lifecycle(Context context) {
2511            super(context);
2512            mService = new ActivityManagerService(context);
2513        }
2514
2515        @Override
2516        public void onStart() {
2517            mService.start();
2518        }
2519
2520        public ActivityManagerService getService() {
2521            return mService;
2522        }
2523    }
2524
2525    // Note: This method is invoked on the main thread but may need to attach various
2526    // handlers to other threads.  So take care to be explicit about the looper.
2527    public ActivityManagerService(Context systemContext) {
2528        mContext = systemContext;
2529        mFactoryTest = FactoryTest.getMode();
2530        mSystemThread = ActivityThread.currentActivityThread();
2531
2532        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2533
2534        mHandlerThread = new ServiceThread(TAG,
2535                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2536        mHandlerThread.start();
2537        mHandler = new MainHandler(mHandlerThread.getLooper());
2538        mUiHandler = new UiHandler();
2539
2540        /* static; one-time init here */
2541        if (sKillHandler == null) {
2542            sKillThread = new ServiceThread(TAG + ":kill",
2543                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2544            sKillThread.start();
2545            sKillHandler = new KillHandler(sKillThread.getLooper());
2546        }
2547
2548        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2549                "foreground", BROADCAST_FG_TIMEOUT, false);
2550        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2551                "background", BROADCAST_BG_TIMEOUT, true);
2552        mBroadcastQueues[0] = mFgBroadcastQueue;
2553        mBroadcastQueues[1] = mBgBroadcastQueue;
2554
2555        mServices = new ActiveServices(this);
2556        mProviderMap = new ProviderMap(this);
2557        mAppErrors = new AppErrors(mContext, this);
2558
2559        // TODO: Move creation of battery stats service outside of activity manager service.
2560        File dataDir = Environment.getDataDirectory();
2561        File systemDir = new File(dataDir, "system");
2562        systemDir.mkdirs();
2563        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2564        mBatteryStatsService.getActiveStatistics().readLocked();
2565        mBatteryStatsService.scheduleWriteToDisk();
2566        mOnBattery = DEBUG_POWER ? true
2567                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2568        mBatteryStatsService.getActiveStatistics().setCallback(this);
2569
2570        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2571
2572        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2573        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2574                new IAppOpsCallback.Stub() {
2575                    @Override public void opChanged(int op, int uid, String packageName) {
2576                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2577                            if (mAppOpsService.checkOperation(op, uid, packageName)
2578                                    != AppOpsManager.MODE_ALLOWED) {
2579                                runInBackgroundDisabled(uid);
2580                            }
2581                        }
2582                    }
2583                });
2584
2585        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2586
2587        mUserController = new UserController(this);
2588
2589        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2590            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2591
2592        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2593
2594        mConfiguration.setToDefaults();
2595        mConfiguration.setLocales(LocaleList.getDefault());
2596
2597        mConfigurationSeq = mConfiguration.seq = 1;
2598        mProcessCpuTracker.init();
2599
2600        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2601        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2602        mStackSupervisor = new ActivityStackSupervisor(this);
2603        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2604        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2605
2606        mProcessCpuThread = new Thread("CpuTracker") {
2607            @Override
2608            public void run() {
2609                while (true) {
2610                    try {
2611                        try {
2612                            synchronized(this) {
2613                                final long now = SystemClock.uptimeMillis();
2614                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2615                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2616                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2617                                //        + ", write delay=" + nextWriteDelay);
2618                                if (nextWriteDelay < nextCpuDelay) {
2619                                    nextCpuDelay = nextWriteDelay;
2620                                }
2621                                if (nextCpuDelay > 0) {
2622                                    mProcessCpuMutexFree.set(true);
2623                                    this.wait(nextCpuDelay);
2624                                }
2625                            }
2626                        } catch (InterruptedException e) {
2627                        }
2628                        updateCpuStatsNow();
2629                    } catch (Exception e) {
2630                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2631                    }
2632                }
2633            }
2634        };
2635
2636        Watchdog.getInstance().addMonitor(this);
2637        Watchdog.getInstance().addThread(mHandler);
2638    }
2639
2640    public void setSystemServiceManager(SystemServiceManager mgr) {
2641        mSystemServiceManager = mgr;
2642    }
2643
2644    public void setInstaller(Installer installer) {
2645        mInstaller = installer;
2646    }
2647
2648    private void start() {
2649        Process.removeAllProcessGroups();
2650        mProcessCpuThread.start();
2651
2652        mBatteryStatsService.publish(mContext);
2653        mAppOpsService.publish(mContext);
2654        Slog.d("AppOps", "AppOpsService published");
2655        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2656    }
2657
2658    void onUserStoppedLocked(int userId) {
2659        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2660    }
2661
2662    public void initPowerManagement() {
2663        mStackSupervisor.initPowerManagement();
2664        mBatteryStatsService.initPowerManagement();
2665        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2666        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2667        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2668        mVoiceWakeLock.setReferenceCounted(false);
2669    }
2670
2671    @Override
2672    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2673            throws RemoteException {
2674        if (code == SYSPROPS_TRANSACTION) {
2675            // We need to tell all apps about the system property change.
2676            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2677            synchronized(this) {
2678                final int NP = mProcessNames.getMap().size();
2679                for (int ip=0; ip<NP; ip++) {
2680                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2681                    final int NA = apps.size();
2682                    for (int ia=0; ia<NA; ia++) {
2683                        ProcessRecord app = apps.valueAt(ia);
2684                        if (app.thread != null) {
2685                            procs.add(app.thread.asBinder());
2686                        }
2687                    }
2688                }
2689            }
2690
2691            int N = procs.size();
2692            for (int i=0; i<N; i++) {
2693                Parcel data2 = Parcel.obtain();
2694                try {
2695                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2696                } catch (RemoteException e) {
2697                }
2698                data2.recycle();
2699            }
2700        }
2701        try {
2702            return super.onTransact(code, data, reply, flags);
2703        } catch (RuntimeException e) {
2704            // The activity manager only throws security exceptions, so let's
2705            // log all others.
2706            if (!(e instanceof SecurityException)) {
2707                Slog.wtf(TAG, "Activity Manager Crash", e);
2708            }
2709            throw e;
2710        }
2711    }
2712
2713    void updateCpuStats() {
2714        final long now = SystemClock.uptimeMillis();
2715        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2716            return;
2717        }
2718        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2719            synchronized (mProcessCpuThread) {
2720                mProcessCpuThread.notify();
2721            }
2722        }
2723    }
2724
2725    void updateCpuStatsNow() {
2726        synchronized (mProcessCpuTracker) {
2727            mProcessCpuMutexFree.set(false);
2728            final long now = SystemClock.uptimeMillis();
2729            boolean haveNewCpuStats = false;
2730
2731            if (MONITOR_CPU_USAGE &&
2732                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2733                mLastCpuTime.set(now);
2734                mProcessCpuTracker.update();
2735                if (mProcessCpuTracker.hasGoodLastStats()) {
2736                    haveNewCpuStats = true;
2737                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2738                    //Slog.i(TAG, "Total CPU usage: "
2739                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2740
2741                    // Slog the cpu usage if the property is set.
2742                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2743                        int user = mProcessCpuTracker.getLastUserTime();
2744                        int system = mProcessCpuTracker.getLastSystemTime();
2745                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2746                        int irq = mProcessCpuTracker.getLastIrqTime();
2747                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2748                        int idle = mProcessCpuTracker.getLastIdleTime();
2749
2750                        int total = user + system + iowait + irq + softIrq + idle;
2751                        if (total == 0) total = 1;
2752
2753                        EventLog.writeEvent(EventLogTags.CPU,
2754                                ((user+system+iowait+irq+softIrq) * 100) / total,
2755                                (user * 100) / total,
2756                                (system * 100) / total,
2757                                (iowait * 100) / total,
2758                                (irq * 100) / total,
2759                                (softIrq * 100) / total);
2760                    }
2761                }
2762            }
2763
2764            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2765            synchronized(bstats) {
2766                synchronized(mPidsSelfLocked) {
2767                    if (haveNewCpuStats) {
2768                        if (bstats.startAddingCpuLocked()) {
2769                            int totalUTime = 0;
2770                            int totalSTime = 0;
2771                            final int N = mProcessCpuTracker.countStats();
2772                            for (int i=0; i<N; i++) {
2773                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2774                                if (!st.working) {
2775                                    continue;
2776                                }
2777                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2778                                totalUTime += st.rel_utime;
2779                                totalSTime += st.rel_stime;
2780                                if (pr != null) {
2781                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2782                                    if (ps == null || !ps.isActive()) {
2783                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2784                                                pr.info.uid, pr.processName);
2785                                    }
2786                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2787                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2788                                } else {
2789                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2790                                    if (ps == null || !ps.isActive()) {
2791                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2792                                                bstats.mapUid(st.uid), st.name);
2793                                    }
2794                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2795                                }
2796                            }
2797                            final int userTime = mProcessCpuTracker.getLastUserTime();
2798                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2799                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2800                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2801                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2802                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2803                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2804                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2805                        }
2806                    }
2807                }
2808
2809                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2810                    mLastWriteTime = now;
2811                    mBatteryStatsService.scheduleWriteToDisk();
2812                }
2813            }
2814        }
2815    }
2816
2817    @Override
2818    public void batteryNeedsCpuUpdate() {
2819        updateCpuStatsNow();
2820    }
2821
2822    @Override
2823    public void batteryPowerChanged(boolean onBattery) {
2824        // When plugging in, update the CPU stats first before changing
2825        // the plug state.
2826        updateCpuStatsNow();
2827        synchronized (this) {
2828            synchronized(mPidsSelfLocked) {
2829                mOnBattery = DEBUG_POWER ? true : onBattery;
2830            }
2831        }
2832    }
2833
2834    @Override
2835    public void batterySendBroadcast(Intent intent) {
2836        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2837                AppOpsManager.OP_NONE, null, false, false,
2838                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2839    }
2840
2841    /**
2842     * Initialize the application bind args. These are passed to each
2843     * process when the bindApplication() IPC is sent to the process. They're
2844     * lazily setup to make sure the services are running when they're asked for.
2845     */
2846    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2847        if (mAppBindArgs == null) {
2848            mAppBindArgs = new HashMap<>();
2849
2850            // Isolated processes won't get this optimization, so that we don't
2851            // violate the rules about which services they have access to.
2852            if (!isolated) {
2853                // Setup the application init args
2854                mAppBindArgs.put("package", ServiceManager.getService("package"));
2855                mAppBindArgs.put("window", ServiceManager.getService("window"));
2856                mAppBindArgs.put(Context.ALARM_SERVICE,
2857                        ServiceManager.getService(Context.ALARM_SERVICE));
2858            }
2859        }
2860        return mAppBindArgs;
2861    }
2862
2863    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2864        if (r == null || mFocusedActivity == r) {
2865            return false;
2866        }
2867
2868        if (!r.isFocusable()) {
2869            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2870            return false;
2871        }
2872
2873        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2874
2875        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2876        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2877                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2878        mDoingSetFocusedActivity = true;
2879
2880        final ActivityRecord last = mFocusedActivity;
2881        mFocusedActivity = r;
2882        if (r.task.isApplicationTask()) {
2883            if (mCurAppTimeTracker != r.appTimeTracker) {
2884                // We are switching app tracking.  Complete the current one.
2885                if (mCurAppTimeTracker != null) {
2886                    mCurAppTimeTracker.stop();
2887                    mHandler.obtainMessage(
2888                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2889                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2890                    mCurAppTimeTracker = null;
2891                }
2892                if (r.appTimeTracker != null) {
2893                    mCurAppTimeTracker = r.appTimeTracker;
2894                    startTimeTrackingFocusedActivityLocked();
2895                }
2896            } else {
2897                startTimeTrackingFocusedActivityLocked();
2898            }
2899        } else {
2900            r.appTimeTracker = null;
2901        }
2902        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2903        // TODO: Probably not, because we don't want to resume voice on switching
2904        // back to this activity
2905        if (r.task.voiceInteractor != null) {
2906            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2907        } else {
2908            finishRunningVoiceLocked();
2909            IVoiceInteractionSession session;
2910            if (last != null && ((session = last.task.voiceSession) != null
2911                    || (session = last.voiceSession) != null)) {
2912                // We had been in a voice interaction session, but now focused has
2913                // move to something different.  Just finish the session, we can't
2914                // return to it and retain the proper state and synchronization with
2915                // the voice interaction service.
2916                finishVoiceTask(session);
2917            }
2918        }
2919        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2920            mWindowManager.setFocusedApp(r.appToken, true);
2921        }
2922        applyUpdateLockStateLocked(r);
2923        applyUpdateVrModeLocked(r);
2924        if (mFocusedActivity.userId != mLastFocusedUserId) {
2925            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2926            mHandler.obtainMessage(
2927                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2928            mLastFocusedUserId = mFocusedActivity.userId;
2929        }
2930
2931        // Log a warning if the focused app is changed during the process. This could
2932        // indicate a problem of the focus setting logic!
2933        if (mFocusedActivity != r) Slog.w(TAG,
2934                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2935        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2936
2937        EventLogTags.writeAmFocusedActivity(
2938                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2939                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2940                reason);
2941        return true;
2942    }
2943
2944    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2945        if (mFocusedActivity != goingAway) {
2946            return;
2947        }
2948
2949        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2950        if (focusedStack != null) {
2951            final ActivityRecord top = focusedStack.topActivity();
2952            if (top != null && top.userId != mLastFocusedUserId) {
2953                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2954                mHandler.sendMessage(
2955                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2956                mLastFocusedUserId = top.userId;
2957            }
2958        }
2959
2960        // Try to move focus to another activity if possible.
2961        if (setFocusedActivityLocked(
2962                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2963            return;
2964        }
2965
2966        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2967                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2968        mFocusedActivity = null;
2969        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2970    }
2971
2972    @Override
2973    public void setFocusedStack(int stackId) {
2974        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2975        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2976        final long callingId = Binder.clearCallingIdentity();
2977        try {
2978            synchronized (this) {
2979                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2980                if (stack == null) {
2981                    return;
2982                }
2983                final ActivityRecord r = stack.topRunningActivityLocked();
2984                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2985                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2986                }
2987            }
2988        } finally {
2989            Binder.restoreCallingIdentity(callingId);
2990        }
2991    }
2992
2993    @Override
2994    public void setFocusedTask(int taskId) {
2995        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2996        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2997        final long callingId = Binder.clearCallingIdentity();
2998        try {
2999            synchronized (this) {
3000                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3001                if (task == null) {
3002                    return;
3003                }
3004                final ActivityRecord r = task.topRunningActivityLocked();
3005                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3006                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3007                }
3008            }
3009        } finally {
3010            Binder.restoreCallingIdentity(callingId);
3011        }
3012    }
3013
3014    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3015    @Override
3016    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3017        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3018        synchronized (this) {
3019            if (listener != null) {
3020                mTaskStackListeners.register(listener);
3021            }
3022        }
3023    }
3024
3025    @Override
3026    public void notifyActivityDrawn(IBinder token) {
3027        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3028        synchronized (this) {
3029            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3030            if (r != null) {
3031                r.task.stack.notifyActivityDrawnLocked(r);
3032            }
3033        }
3034    }
3035
3036    final void applyUpdateLockStateLocked(ActivityRecord r) {
3037        // Modifications to the UpdateLock state are done on our handler, outside
3038        // the activity manager's locks.  The new state is determined based on the
3039        // state *now* of the relevant activity record.  The object is passed to
3040        // the handler solely for logging detail, not to be consulted/modified.
3041        final boolean nextState = r != null && r.immersive;
3042        mHandler.sendMessage(
3043                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3044    }
3045
3046    final void applyUpdateVrModeLocked(ActivityRecord r) {
3047        mHandler.sendMessage(
3048                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3049    }
3050
3051    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3052        mHandler.sendMessage(
3053                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3054    }
3055
3056    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3057        Message msg = Message.obtain();
3058        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3059        msg.obj = r.task.askedCompatMode ? null : r;
3060        mUiHandler.sendMessage(msg);
3061    }
3062
3063    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3064            String what, Object obj, ProcessRecord srcApp) {
3065        app.lastActivityTime = now;
3066
3067        if (app.activities.size() > 0) {
3068            // Don't want to touch dependent processes that are hosting activities.
3069            return index;
3070        }
3071
3072        int lrui = mLruProcesses.lastIndexOf(app);
3073        if (lrui < 0) {
3074            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3075                    + what + " " + obj + " from " + srcApp);
3076            return index;
3077        }
3078
3079        if (lrui >= index) {
3080            // Don't want to cause this to move dependent processes *back* in the
3081            // list as if they were less frequently used.
3082            return index;
3083        }
3084
3085        if (lrui >= mLruProcessActivityStart) {
3086            // Don't want to touch dependent processes that are hosting activities.
3087            return index;
3088        }
3089
3090        mLruProcesses.remove(lrui);
3091        if (index > 0) {
3092            index--;
3093        }
3094        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3095                + " in LRU list: " + app);
3096        mLruProcesses.add(index, app);
3097        return index;
3098    }
3099
3100    static void killProcessGroup(int uid, int pid) {
3101        if (sKillHandler != null) {
3102            sKillHandler.sendMessage(
3103                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3104        } else {
3105            Slog.w(TAG, "Asked to kill process group before system bringup!");
3106            Process.killProcessGroup(uid, pid);
3107        }
3108    }
3109
3110    final void removeLruProcessLocked(ProcessRecord app) {
3111        int lrui = mLruProcesses.lastIndexOf(app);
3112        if (lrui >= 0) {
3113            if (!app.killed) {
3114                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3115                Process.killProcessQuiet(app.pid);
3116                killProcessGroup(app.uid, app.pid);
3117            }
3118            if (lrui <= mLruProcessActivityStart) {
3119                mLruProcessActivityStart--;
3120            }
3121            if (lrui <= mLruProcessServiceStart) {
3122                mLruProcessServiceStart--;
3123            }
3124            mLruProcesses.remove(lrui);
3125        }
3126    }
3127
3128    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3129            ProcessRecord client) {
3130        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3131                || app.treatLikeActivity;
3132        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3133        if (!activityChange && hasActivity) {
3134            // The process has activities, so we are only allowing activity-based adjustments
3135            // to move it.  It should be kept in the front of the list with other
3136            // processes that have activities, and we don't want those to change their
3137            // order except due to activity operations.
3138            return;
3139        }
3140
3141        mLruSeq++;
3142        final long now = SystemClock.uptimeMillis();
3143        app.lastActivityTime = now;
3144
3145        // First a quick reject: if the app is already at the position we will
3146        // put it, then there is nothing to do.
3147        if (hasActivity) {
3148            final int N = mLruProcesses.size();
3149            if (N > 0 && mLruProcesses.get(N-1) == app) {
3150                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3151                return;
3152            }
3153        } else {
3154            if (mLruProcessServiceStart > 0
3155                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3156                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3157                return;
3158            }
3159        }
3160
3161        int lrui = mLruProcesses.lastIndexOf(app);
3162
3163        if (app.persistent && lrui >= 0) {
3164            // We don't care about the position of persistent processes, as long as
3165            // they are in the list.
3166            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3167            return;
3168        }
3169
3170        /* In progress: compute new position first, so we can avoid doing work
3171           if the process is not actually going to move.  Not yet working.
3172        int addIndex;
3173        int nextIndex;
3174        boolean inActivity = false, inService = false;
3175        if (hasActivity) {
3176            // Process has activities, put it at the very tipsy-top.
3177            addIndex = mLruProcesses.size();
3178            nextIndex = mLruProcessServiceStart;
3179            inActivity = true;
3180        } else if (hasService) {
3181            // Process has services, put it at the top of the service list.
3182            addIndex = mLruProcessActivityStart;
3183            nextIndex = mLruProcessServiceStart;
3184            inActivity = true;
3185            inService = true;
3186        } else  {
3187            // Process not otherwise of interest, it goes to the top of the non-service area.
3188            addIndex = mLruProcessServiceStart;
3189            if (client != null) {
3190                int clientIndex = mLruProcesses.lastIndexOf(client);
3191                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3192                        + app);
3193                if (clientIndex >= 0 && addIndex > clientIndex) {
3194                    addIndex = clientIndex;
3195                }
3196            }
3197            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3198        }
3199
3200        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3201                + mLruProcessActivityStart + "): " + app);
3202        */
3203
3204        if (lrui >= 0) {
3205            if (lrui < mLruProcessActivityStart) {
3206                mLruProcessActivityStart--;
3207            }
3208            if (lrui < mLruProcessServiceStart) {
3209                mLruProcessServiceStart--;
3210            }
3211            /*
3212            if (addIndex > lrui) {
3213                addIndex--;
3214            }
3215            if (nextIndex > lrui) {
3216                nextIndex--;
3217            }
3218            */
3219            mLruProcesses.remove(lrui);
3220        }
3221
3222        /*
3223        mLruProcesses.add(addIndex, app);
3224        if (inActivity) {
3225            mLruProcessActivityStart++;
3226        }
3227        if (inService) {
3228            mLruProcessActivityStart++;
3229        }
3230        */
3231
3232        int nextIndex;
3233        if (hasActivity) {
3234            final int N = mLruProcesses.size();
3235            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3236                // Process doesn't have activities, but has clients with
3237                // activities...  move it up, but one below the top (the top
3238                // should always have a real activity).
3239                if (DEBUG_LRU) Slog.d(TAG_LRU,
3240                        "Adding to second-top of LRU activity list: " + app);
3241                mLruProcesses.add(N - 1, app);
3242                // To keep it from spamming the LRU list (by making a bunch of clients),
3243                // we will push down any other entries owned by the app.
3244                final int uid = app.info.uid;
3245                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3246                    ProcessRecord subProc = mLruProcesses.get(i);
3247                    if (subProc.info.uid == uid) {
3248                        // We want to push this one down the list.  If the process after
3249                        // it is for the same uid, however, don't do so, because we don't
3250                        // want them internally to be re-ordered.
3251                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3252                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3253                                    "Pushing uid " + uid + " swapping at " + i + ": "
3254                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3255                            ProcessRecord tmp = mLruProcesses.get(i);
3256                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3257                            mLruProcesses.set(i - 1, tmp);
3258                            i--;
3259                        }
3260                    } else {
3261                        // A gap, we can stop here.
3262                        break;
3263                    }
3264                }
3265            } else {
3266                // Process has activities, put it at the very tipsy-top.
3267                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3268                mLruProcesses.add(app);
3269            }
3270            nextIndex = mLruProcessServiceStart;
3271        } else if (hasService) {
3272            // Process has services, put it at the top of the service list.
3273            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3274            mLruProcesses.add(mLruProcessActivityStart, app);
3275            nextIndex = mLruProcessServiceStart;
3276            mLruProcessActivityStart++;
3277        } else  {
3278            // Process not otherwise of interest, it goes to the top of the non-service area.
3279            int index = mLruProcessServiceStart;
3280            if (client != null) {
3281                // If there is a client, don't allow the process to be moved up higher
3282                // in the list than that client.
3283                int clientIndex = mLruProcesses.lastIndexOf(client);
3284                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3285                        + " when updating " + app);
3286                if (clientIndex <= lrui) {
3287                    // Don't allow the client index restriction to push it down farther in the
3288                    // list than it already is.
3289                    clientIndex = lrui;
3290                }
3291                if (clientIndex >= 0 && index > clientIndex) {
3292                    index = clientIndex;
3293                }
3294            }
3295            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3296            mLruProcesses.add(index, app);
3297            nextIndex = index-1;
3298            mLruProcessActivityStart++;
3299            mLruProcessServiceStart++;
3300        }
3301
3302        // If the app is currently using a content provider or service,
3303        // bump those processes as well.
3304        for (int j=app.connections.size()-1; j>=0; j--) {
3305            ConnectionRecord cr = app.connections.valueAt(j);
3306            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3307                    && cr.binding.service.app != null
3308                    && cr.binding.service.app.lruSeq != mLruSeq
3309                    && !cr.binding.service.app.persistent) {
3310                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3311                        "service connection", cr, app);
3312            }
3313        }
3314        for (int j=app.conProviders.size()-1; j>=0; j--) {
3315            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3316            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3317                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3318                        "provider reference", cpr, app);
3319            }
3320        }
3321    }
3322
3323    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3324        if (uid == Process.SYSTEM_UID) {
3325            // The system gets to run in any process.  If there are multiple
3326            // processes with the same uid, just pick the first (this
3327            // should never happen).
3328            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3329            if (procs == null) return null;
3330            final int procCount = procs.size();
3331            for (int i = 0; i < procCount; i++) {
3332                final int procUid = procs.keyAt(i);
3333                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3334                    // Don't use an app process or different user process for system component.
3335                    continue;
3336                }
3337                return procs.valueAt(i);
3338            }
3339        }
3340        ProcessRecord proc = mProcessNames.get(processName, uid);
3341        if (false && proc != null && !keepIfLarge
3342                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3343                && proc.lastCachedPss >= 4000) {
3344            // Turn this condition on to cause killing to happen regularly, for testing.
3345            if (proc.baseProcessTracker != null) {
3346                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3347            }
3348            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3349        } else if (proc != null && !keepIfLarge
3350                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3351                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3352            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3353            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3354                if (proc.baseProcessTracker != null) {
3355                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3356                }
3357                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3358            }
3359        }
3360        return proc;
3361    }
3362
3363    void notifyPackageUse(String packageName, int reason) {
3364        IPackageManager pm = AppGlobals.getPackageManager();
3365        try {
3366            pm.notifyPackageUse(packageName, reason);
3367        } catch (RemoteException e) {
3368        }
3369    }
3370
3371    boolean isNextTransitionForward() {
3372        int transit = mWindowManager.getPendingAppTransition();
3373        return transit == TRANSIT_ACTIVITY_OPEN
3374                || transit == TRANSIT_TASK_OPEN
3375                || transit == TRANSIT_TASK_TO_FRONT;
3376    }
3377
3378    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3379            String processName, String abiOverride, int uid, Runnable crashHandler) {
3380        synchronized(this) {
3381            ApplicationInfo info = new ApplicationInfo();
3382            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3383            // For isolated processes, the former contains the parent's uid and the latter the
3384            // actual uid of the isolated process.
3385            // In the special case introduced by this method (which is, starting an isolated
3386            // process directly from the SystemServer without an actual parent app process) the
3387            // closest thing to a parent's uid is SYSTEM_UID.
3388            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3389            // the |isolated| logic in the ProcessRecord constructor.
3390            info.uid = Process.SYSTEM_UID;
3391            info.processName = processName;
3392            info.className = entryPoint;
3393            info.packageName = "android";
3394            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3395                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3396                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3397                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3398                    crashHandler);
3399            return proc != null ? proc.pid : 0;
3400        }
3401    }
3402
3403    final ProcessRecord startProcessLocked(String processName,
3404            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3405            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3406            boolean isolated, boolean keepIfLarge) {
3407        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3408                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3409                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3410                null /* crashHandler */);
3411    }
3412
3413    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3414            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3415            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3416            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3417        long startTime = SystemClock.elapsedRealtime();
3418        ProcessRecord app;
3419        if (!isolated) {
3420            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3421            checkTime(startTime, "startProcess: after getProcessRecord");
3422
3423            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3424                // If we are in the background, then check to see if this process
3425                // is bad.  If so, we will just silently fail.
3426                if (mAppErrors.isBadProcessLocked(info)) {
3427                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3428                            + "/" + info.processName);
3429                    return null;
3430                }
3431            } else {
3432                // When the user is explicitly starting a process, then clear its
3433                // crash count so that we won't make it bad until they see at
3434                // least one crash dialog again, and make the process good again
3435                // if it had been bad.
3436                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3437                        + "/" + info.processName);
3438                mAppErrors.resetProcessCrashTimeLocked(info);
3439                if (mAppErrors.isBadProcessLocked(info)) {
3440                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3441                            UserHandle.getUserId(info.uid), info.uid,
3442                            info.processName);
3443                    mAppErrors.clearBadProcessLocked(info);
3444                    if (app != null) {
3445                        app.bad = false;
3446                    }
3447                }
3448            }
3449        } else {
3450            // If this is an isolated process, it can't re-use an existing process.
3451            app = null;
3452        }
3453
3454        // app launch boost for big.little configurations
3455        // use cpusets to migrate freshly launched tasks to big cores
3456        synchronized(ActivityManagerService.this) {
3457            nativeMigrateToBoost();
3458            mIsBoosted = true;
3459            mBoostStartTime = SystemClock.uptimeMillis();
3460            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3461            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3462        }
3463
3464        // We don't have to do anything more if:
3465        // (1) There is an existing application record; and
3466        // (2) The caller doesn't think it is dead, OR there is no thread
3467        //     object attached to it so we know it couldn't have crashed; and
3468        // (3) There is a pid assigned to it, so it is either starting or
3469        //     already running.
3470        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3471                + " app=" + app + " knownToBeDead=" + knownToBeDead
3472                + " thread=" + (app != null ? app.thread : null)
3473                + " pid=" + (app != null ? app.pid : -1));
3474        if (app != null && app.pid > 0) {
3475            if (!knownToBeDead || app.thread == null) {
3476                // We already have the app running, or are waiting for it to
3477                // come up (we have a pid but not yet its thread), so keep it.
3478                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3479                // If this is a new package in the process, add the package to the list
3480                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3481                checkTime(startTime, "startProcess: done, added package to proc");
3482                return app;
3483            }
3484
3485            // An application record is attached to a previous process,
3486            // clean it up now.
3487            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3488            checkTime(startTime, "startProcess: bad proc running, killing");
3489            killProcessGroup(app.uid, app.pid);
3490            handleAppDiedLocked(app, true, true);
3491            checkTime(startTime, "startProcess: done killing old proc");
3492        }
3493
3494        String hostingNameStr = hostingName != null
3495                ? hostingName.flattenToShortString() : null;
3496
3497        if (app == null) {
3498            checkTime(startTime, "startProcess: creating new process record");
3499            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3500            if (app == null) {
3501                Slog.w(TAG, "Failed making new process record for "
3502                        + processName + "/" + info.uid + " isolated=" + isolated);
3503                return null;
3504            }
3505            app.crashHandler = crashHandler;
3506            checkTime(startTime, "startProcess: done creating new process record");
3507        } else {
3508            // If this is a new package in the process, add the package to the list
3509            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3510            checkTime(startTime, "startProcess: added package to existing proc");
3511        }
3512
3513        // If the system is not ready yet, then hold off on starting this
3514        // process until it is.
3515        if (!mProcessesReady
3516                && !isAllowedWhileBooting(info)
3517                && !allowWhileBooting) {
3518            if (!mProcessesOnHold.contains(app)) {
3519                mProcessesOnHold.add(app);
3520            }
3521            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3522                    "System not ready, putting on hold: " + app);
3523            checkTime(startTime, "startProcess: returning with proc on hold");
3524            return app;
3525        }
3526
3527        checkTime(startTime, "startProcess: stepping in to startProcess");
3528        startProcessLocked(
3529                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3530        checkTime(startTime, "startProcess: done starting proc!");
3531        return (app.pid != 0) ? app : null;
3532    }
3533
3534    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3535        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3536    }
3537
3538    private final void startProcessLocked(ProcessRecord app,
3539            String hostingType, String hostingNameStr) {
3540        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3541                null /* entryPoint */, null /* entryPointArgs */);
3542    }
3543
3544    private final void startProcessLocked(ProcessRecord app, String hostingType,
3545            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3546        long startTime = SystemClock.elapsedRealtime();
3547        if (app.pid > 0 && app.pid != MY_PID) {
3548            checkTime(startTime, "startProcess: removing from pids map");
3549            synchronized (mPidsSelfLocked) {
3550                mPidsSelfLocked.remove(app.pid);
3551                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3552            }
3553            checkTime(startTime, "startProcess: done removing from pids map");
3554            app.setPid(0);
3555        }
3556
3557        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3558                "startProcessLocked removing on hold: " + app);
3559        mProcessesOnHold.remove(app);
3560
3561        checkTime(startTime, "startProcess: starting to update cpu stats");
3562        updateCpuStats();
3563        checkTime(startTime, "startProcess: done updating cpu stats");
3564
3565        try {
3566            try {
3567                final int userId = UserHandle.getUserId(app.uid);
3568                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3569            } catch (RemoteException e) {
3570                throw e.rethrowAsRuntimeException();
3571            }
3572
3573            int uid = app.uid;
3574            int[] gids = null;
3575            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3576            if (!app.isolated) {
3577                int[] permGids = null;
3578                try {
3579                    checkTime(startTime, "startProcess: getting gids from package manager");
3580                    final IPackageManager pm = AppGlobals.getPackageManager();
3581                    permGids = pm.getPackageGids(app.info.packageName,
3582                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3583                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3584                            MountServiceInternal.class);
3585                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3586                            app.info.packageName);
3587                } catch (RemoteException e) {
3588                    throw e.rethrowAsRuntimeException();
3589                }
3590
3591                /*
3592                 * Add shared application and profile GIDs so applications can share some
3593                 * resources like shared libraries and access user-wide resources
3594                 */
3595                if (ArrayUtils.isEmpty(permGids)) {
3596                    gids = new int[2];
3597                } else {
3598                    gids = new int[permGids.length + 2];
3599                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3600                }
3601                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3602                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3603            }
3604            checkTime(startTime, "startProcess: building args");
3605            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3606                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3607                        && mTopComponent != null
3608                        && app.processName.equals(mTopComponent.getPackageName())) {
3609                    uid = 0;
3610                }
3611                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3612                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3613                    uid = 0;
3614                }
3615            }
3616            int debugFlags = 0;
3617            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3618                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3619                // Also turn on CheckJNI for debuggable apps. It's quite
3620                // awkward to turn on otherwise.
3621                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3622            }
3623            // Run the app in safe mode if its manifest requests so or the
3624            // system is booted in safe mode.
3625            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3626                mSafeMode == true) {
3627                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3628            }
3629            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3630                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3631            }
3632            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3633            if ("true".equals(genDebugInfoProperty)) {
3634                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3635            }
3636            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3637                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3638            }
3639            if ("1".equals(SystemProperties.get("debug.assert"))) {
3640                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3641            }
3642            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3643                // Enable all debug flags required by the native debugger.
3644                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3645                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3646                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3647                mNativeDebuggingApp = null;
3648            }
3649
3650            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3651            if (requiredAbi == null) {
3652                requiredAbi = Build.SUPPORTED_ABIS[0];
3653            }
3654
3655            String instructionSet = null;
3656            if (app.info.primaryCpuAbi != null) {
3657                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3658            }
3659
3660            app.gids = gids;
3661            app.requiredAbi = requiredAbi;
3662            app.instructionSet = instructionSet;
3663
3664            // Start the process.  It will either succeed and return a result containing
3665            // the PID of the new process, or else throw a RuntimeException.
3666            boolean isActivityProcess = (entryPoint == null);
3667            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3668            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3669                    app.processName);
3670            checkTime(startTime, "startProcess: asking zygote to start proc");
3671            Process.ProcessStartResult startResult = Process.start(entryPoint,
3672                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3673                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3674                    app.info.dataDir, entryPointArgs);
3675            checkTime(startTime, "startProcess: returned from zygote!");
3676            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3677
3678            if (app.isolated) {
3679                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3680            }
3681            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3682            checkTime(startTime, "startProcess: done updating battery stats");
3683
3684            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3685                    UserHandle.getUserId(uid), startResult.pid, uid,
3686                    app.processName, hostingType,
3687                    hostingNameStr != null ? hostingNameStr : "");
3688
3689            try {
3690                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3691                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3692            } catch (RemoteException ex) {
3693                // Ignore
3694            }
3695
3696            if (app.persistent) {
3697                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3698            }
3699
3700            checkTime(startTime, "startProcess: building log message");
3701            StringBuilder buf = mStringBuilder;
3702            buf.setLength(0);
3703            buf.append("Start proc ");
3704            buf.append(startResult.pid);
3705            buf.append(':');
3706            buf.append(app.processName);
3707            buf.append('/');
3708            UserHandle.formatUid(buf, uid);
3709            if (!isActivityProcess) {
3710                buf.append(" [");
3711                buf.append(entryPoint);
3712                buf.append("]");
3713            }
3714            buf.append(" for ");
3715            buf.append(hostingType);
3716            if (hostingNameStr != null) {
3717                buf.append(" ");
3718                buf.append(hostingNameStr);
3719            }
3720            Slog.i(TAG, buf.toString());
3721            app.setPid(startResult.pid);
3722            app.usingWrapper = startResult.usingWrapper;
3723            app.removed = false;
3724            app.killed = false;
3725            app.killedByAm = false;
3726            checkTime(startTime, "startProcess: starting to update pids map");
3727            synchronized (mPidsSelfLocked) {
3728                this.mPidsSelfLocked.put(startResult.pid, app);
3729                if (isActivityProcess) {
3730                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3731                    msg.obj = app;
3732                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3733                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3734                }
3735            }
3736            checkTime(startTime, "startProcess: done updating pids map");
3737        } catch (RuntimeException e) {
3738            Slog.e(TAG, "Failure starting process " + app.processName, e);
3739
3740            // Something went very wrong while trying to start this process; one
3741            // common case is when the package is frozen due to an active
3742            // upgrade. To recover, clean up any active bookkeeping related to
3743            // starting this process. (We already invoked this method once when
3744            // the package was initially frozen through KILL_APPLICATION_MSG, so
3745            // it doesn't hurt to use it again.)
3746            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3747                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3748        }
3749    }
3750
3751    void updateUsageStats(ActivityRecord component, boolean resumed) {
3752        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3753                "updateUsageStats: comp=" + component + "res=" + resumed);
3754        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3755        if (resumed) {
3756            if (mUsageStatsService != null) {
3757                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3758                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3759            }
3760            synchronized (stats) {
3761                stats.noteActivityResumedLocked(component.app.uid);
3762            }
3763        } else {
3764            if (mUsageStatsService != null) {
3765                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3766                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3767            }
3768            synchronized (stats) {
3769                stats.noteActivityPausedLocked(component.app.uid);
3770            }
3771        }
3772    }
3773
3774    Intent getHomeIntent() {
3775        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3776        intent.setComponent(mTopComponent);
3777        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3778        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3779            intent.addCategory(Intent.CATEGORY_HOME);
3780        }
3781        return intent;
3782    }
3783
3784    boolean startHomeActivityLocked(int userId, String reason) {
3785        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3786                && mTopAction == null) {
3787            // We are running in factory test mode, but unable to find
3788            // the factory test app, so just sit around displaying the
3789            // error message and don't try to start anything.
3790            return false;
3791        }
3792        Intent intent = getHomeIntent();
3793        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3794        if (aInfo != null) {
3795            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3796            // Don't do this if the home app is currently being
3797            // instrumented.
3798            aInfo = new ActivityInfo(aInfo);
3799            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3800            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3801                    aInfo.applicationInfo.uid, true);
3802            if (app == null || app.instrumentationClass == null) {
3803                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3804                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3805            }
3806        } else {
3807            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3808        }
3809
3810        return true;
3811    }
3812
3813    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3814        ActivityInfo ai = null;
3815        ComponentName comp = intent.getComponent();
3816        try {
3817            if (comp != null) {
3818                // Factory test.
3819                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3820            } else {
3821                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3822                        intent,
3823                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3824                        flags, userId);
3825
3826                if (info != null) {
3827                    ai = info.activityInfo;
3828                }
3829            }
3830        } catch (RemoteException e) {
3831            // ignore
3832        }
3833
3834        return ai;
3835    }
3836
3837    /**
3838     * Starts the "new version setup screen" if appropriate.
3839     */
3840    void startSetupActivityLocked() {
3841        // Only do this once per boot.
3842        if (mCheckedForSetup) {
3843            return;
3844        }
3845
3846        // We will show this screen if the current one is a different
3847        // version than the last one shown, and we are not running in
3848        // low-level factory test mode.
3849        final ContentResolver resolver = mContext.getContentResolver();
3850        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3851                Settings.Global.getInt(resolver,
3852                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3853            mCheckedForSetup = true;
3854
3855            // See if we should be showing the platform update setup UI.
3856            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3857            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3858                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3859            if (!ris.isEmpty()) {
3860                final ResolveInfo ri = ris.get(0);
3861                String vers = ri.activityInfo.metaData != null
3862                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3863                        : null;
3864                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3865                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3866                            Intent.METADATA_SETUP_VERSION);
3867                }
3868                String lastVers = Settings.Secure.getString(
3869                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3870                if (vers != null && !vers.equals(lastVers)) {
3871                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3872                    intent.setComponent(new ComponentName(
3873                            ri.activityInfo.packageName, ri.activityInfo.name));
3874                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3875                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3876                            null, 0, 0, 0, null, false, false, null, null, null);
3877                }
3878            }
3879        }
3880    }
3881
3882    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3883        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3884    }
3885
3886    void enforceNotIsolatedCaller(String caller) {
3887        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3888            throw new SecurityException("Isolated process not allowed to call " + caller);
3889        }
3890    }
3891
3892    void enforceShellRestriction(String restriction, int userHandle) {
3893        if (Binder.getCallingUid() == Process.SHELL_UID) {
3894            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3895                throw new SecurityException("Shell does not have permission to access user "
3896                        + userHandle);
3897            }
3898        }
3899    }
3900
3901    @Override
3902    public int getFrontActivityScreenCompatMode() {
3903        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3904        synchronized (this) {
3905            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3906        }
3907    }
3908
3909    @Override
3910    public void setFrontActivityScreenCompatMode(int mode) {
3911        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3912                "setFrontActivityScreenCompatMode");
3913        synchronized (this) {
3914            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3915        }
3916    }
3917
3918    @Override
3919    public int getPackageScreenCompatMode(String packageName) {
3920        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3921        synchronized (this) {
3922            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3923        }
3924    }
3925
3926    @Override
3927    public void setPackageScreenCompatMode(String packageName, int mode) {
3928        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3929                "setPackageScreenCompatMode");
3930        synchronized (this) {
3931            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3932        }
3933    }
3934
3935    @Override
3936    public boolean getPackageAskScreenCompat(String packageName) {
3937        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3938        synchronized (this) {
3939            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3940        }
3941    }
3942
3943    @Override
3944    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3945        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3946                "setPackageAskScreenCompat");
3947        synchronized (this) {
3948            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3949        }
3950    }
3951
3952    private boolean hasUsageStatsPermission(String callingPackage) {
3953        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3954                Binder.getCallingUid(), callingPackage);
3955        if (mode == AppOpsManager.MODE_DEFAULT) {
3956            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3957                    == PackageManager.PERMISSION_GRANTED;
3958        }
3959        return mode == AppOpsManager.MODE_ALLOWED;
3960    }
3961
3962    @Override
3963    public int getPackageProcessState(String packageName, String callingPackage) {
3964        if (!hasUsageStatsPermission(callingPackage)) {
3965            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3966                    "getPackageProcessState");
3967        }
3968
3969        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3970        synchronized (this) {
3971            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3972                final ProcessRecord proc = mLruProcesses.get(i);
3973                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3974                        || procState > proc.setProcState) {
3975                    boolean found = false;
3976                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3977                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3978                            procState = proc.setProcState;
3979                            found = true;
3980                        }
3981                    }
3982                    if (proc.pkgDeps != null && !found) {
3983                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3984                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3985                                procState = proc.setProcState;
3986                                break;
3987                            }
3988                        }
3989                    }
3990                }
3991            }
3992        }
3993        return procState;
3994    }
3995
3996    @Override
3997    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3998        synchronized (this) {
3999            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4000            if (app == null) {
4001                return false;
4002            }
4003            if (app.trimMemoryLevel < level && app.thread != null &&
4004                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4005                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4006                try {
4007                    app.thread.scheduleTrimMemory(level);
4008                    app.trimMemoryLevel = level;
4009                    return true;
4010                } catch (RemoteException e) {
4011                    // Fallthrough to failure case.
4012                }
4013            }
4014        }
4015        return false;
4016    }
4017
4018    private void dispatchProcessesChanged() {
4019        int N;
4020        synchronized (this) {
4021            N = mPendingProcessChanges.size();
4022            if (mActiveProcessChanges.length < N) {
4023                mActiveProcessChanges = new ProcessChangeItem[N];
4024            }
4025            mPendingProcessChanges.toArray(mActiveProcessChanges);
4026            mPendingProcessChanges.clear();
4027            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4028                    "*** Delivering " + N + " process changes");
4029        }
4030
4031        int i = mProcessObservers.beginBroadcast();
4032        while (i > 0) {
4033            i--;
4034            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4035            if (observer != null) {
4036                try {
4037                    for (int j=0; j<N; j++) {
4038                        ProcessChangeItem item = mActiveProcessChanges[j];
4039                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4040                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4041                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4042                                    + item.uid + ": " + item.foregroundActivities);
4043                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4044                                    item.foregroundActivities);
4045                        }
4046                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4047                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4048                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4049                                    + ": " + item.processState);
4050                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4051                        }
4052                    }
4053                } catch (RemoteException e) {
4054                }
4055            }
4056        }
4057        mProcessObservers.finishBroadcast();
4058
4059        synchronized (this) {
4060            for (int j=0; j<N; j++) {
4061                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4062            }
4063        }
4064    }
4065
4066    private void dispatchProcessDied(int pid, int uid) {
4067        int i = mProcessObservers.beginBroadcast();
4068        while (i > 0) {
4069            i--;
4070            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4071            if (observer != null) {
4072                try {
4073                    observer.onProcessDied(pid, uid);
4074                } catch (RemoteException e) {
4075                }
4076            }
4077        }
4078        mProcessObservers.finishBroadcast();
4079    }
4080
4081    private void dispatchUidsChanged() {
4082        int N;
4083        synchronized (this) {
4084            N = mPendingUidChanges.size();
4085            if (mActiveUidChanges.length < N) {
4086                mActiveUidChanges = new UidRecord.ChangeItem[N];
4087            }
4088            for (int i=0; i<N; i++) {
4089                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4090                mActiveUidChanges[i] = change;
4091                if (change.uidRecord != null) {
4092                    change.uidRecord.pendingChange = null;
4093                    change.uidRecord = null;
4094                }
4095            }
4096            mPendingUidChanges.clear();
4097            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4098                    "*** Delivering " + N + " uid changes");
4099        }
4100
4101        if (mLocalPowerManager != null) {
4102            for (int j=0; j<N; j++) {
4103                UidRecord.ChangeItem item = mActiveUidChanges[j];
4104                if (item.change == UidRecord.CHANGE_GONE
4105                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4106                    mLocalPowerManager.uidGone(item.uid);
4107                } else {
4108                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4109                }
4110            }
4111        }
4112
4113        int i = mUidObservers.beginBroadcast();
4114        while (i > 0) {
4115            i--;
4116            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4117            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4118            if (observer != null) {
4119                try {
4120                    for (int j=0; j<N; j++) {
4121                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4122                        final int change = item.change;
4123                        UidRecord validateUid = null;
4124                        if (VALIDATE_UID_STATES && i == 0) {
4125                            validateUid = mValidateUids.get(item.uid);
4126                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4127                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4128                                validateUid = new UidRecord(item.uid);
4129                                mValidateUids.put(item.uid, validateUid);
4130                            }
4131                        }
4132                        if (change == UidRecord.CHANGE_IDLE
4133                                || change == UidRecord.CHANGE_GONE_IDLE) {
4134                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4135                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4136                                        "UID idle uid=" + item.uid);
4137                                observer.onUidIdle(item.uid);
4138                            }
4139                            if (VALIDATE_UID_STATES && i == 0) {
4140                                if (validateUid != null) {
4141                                    validateUid.idle = true;
4142                                }
4143                            }
4144                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4145                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4146                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4147                                        "UID active uid=" + item.uid);
4148                                observer.onUidActive(item.uid);
4149                            }
4150                            if (VALIDATE_UID_STATES && i == 0) {
4151                                validateUid.idle = false;
4152                            }
4153                        }
4154                        if (change == UidRecord.CHANGE_GONE
4155                                || change == UidRecord.CHANGE_GONE_IDLE) {
4156                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4157                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4158                                        "UID gone uid=" + item.uid);
4159                                observer.onUidGone(item.uid);
4160                            }
4161                            if (VALIDATE_UID_STATES && i == 0) {
4162                                if (validateUid != null) {
4163                                    mValidateUids.remove(item.uid);
4164                                }
4165                            }
4166                        } else {
4167                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4168                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4169                                        "UID CHANGED uid=" + item.uid
4170                                                + ": " + item.processState);
4171                                observer.onUidStateChanged(item.uid, item.processState);
4172                            }
4173                            if (VALIDATE_UID_STATES && i == 0) {
4174                                validateUid.curProcState = validateUid.setProcState
4175                                        = item.processState;
4176                            }
4177                        }
4178                    }
4179                } catch (RemoteException e) {
4180                }
4181            }
4182        }
4183        mUidObservers.finishBroadcast();
4184
4185        synchronized (this) {
4186            for (int j=0; j<N; j++) {
4187                mAvailUidChanges.add(mActiveUidChanges[j]);
4188            }
4189        }
4190    }
4191
4192    @Override
4193    public final int startActivity(IApplicationThread caller, String callingPackage,
4194            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4195            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4196        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4197                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4198                UserHandle.getCallingUserId());
4199    }
4200
4201    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4202        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4203        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4204                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4205                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4206
4207        // TODO: Switch to user app stacks here.
4208        String mimeType = intent.getType();
4209        final Uri data = intent.getData();
4210        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4211            mimeType = getProviderMimeType(data, userId);
4212        }
4213        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4214
4215        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4216        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4217                null, 0, 0, null, null, null, null, false, userId, container, null);
4218    }
4219
4220    @Override
4221    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4222            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4223            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4224        enforceNotIsolatedCaller("startActivity");
4225        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4226                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4227        // TODO: Switch to user app stacks here.
4228        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4229                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4230                profilerInfo, null, null, bOptions, false, userId, null, null);
4231    }
4232
4233    @Override
4234    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4235            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4236            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4237            int userId) {
4238
4239        // This is very dangerous -- it allows you to perform a start activity (including
4240        // permission grants) as any app that may launch one of your own activities.  So
4241        // we will only allow this to be done from activities that are part of the core framework,
4242        // and then only when they are running as the system.
4243        final ActivityRecord sourceRecord;
4244        final int targetUid;
4245        final String targetPackage;
4246        synchronized (this) {
4247            if (resultTo == null) {
4248                throw new SecurityException("Must be called from an activity");
4249            }
4250            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4251            if (sourceRecord == null) {
4252                throw new SecurityException("Called with bad activity token: " + resultTo);
4253            }
4254            if (!sourceRecord.info.packageName.equals("android")) {
4255                throw new SecurityException(
4256                        "Must be called from an activity that is declared in the android package");
4257            }
4258            if (sourceRecord.app == null) {
4259                throw new SecurityException("Called without a process attached to activity");
4260            }
4261            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4262                // This is still okay, as long as this activity is running under the
4263                // uid of the original calling activity.
4264                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4265                    throw new SecurityException(
4266                            "Calling activity in uid " + sourceRecord.app.uid
4267                                    + " must be system uid or original calling uid "
4268                                    + sourceRecord.launchedFromUid);
4269                }
4270            }
4271            if (ignoreTargetSecurity) {
4272                if (intent.getComponent() == null) {
4273                    throw new SecurityException(
4274                            "Component must be specified with ignoreTargetSecurity");
4275                }
4276                if (intent.getSelector() != null) {
4277                    throw new SecurityException(
4278                            "Selector not allowed with ignoreTargetSecurity");
4279                }
4280            }
4281            targetUid = sourceRecord.launchedFromUid;
4282            targetPackage = sourceRecord.launchedFromPackage;
4283        }
4284
4285        if (userId == UserHandle.USER_NULL) {
4286            userId = UserHandle.getUserId(sourceRecord.app.uid);
4287        }
4288
4289        // TODO: Switch to user app stacks here.
4290        try {
4291            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4292                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4293                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4294            return ret;
4295        } catch (SecurityException e) {
4296            // XXX need to figure out how to propagate to original app.
4297            // A SecurityException here is generally actually a fault of the original
4298            // calling activity (such as a fairly granting permissions), so propagate it
4299            // back to them.
4300            /*
4301            StringBuilder msg = new StringBuilder();
4302            msg.append("While launching");
4303            msg.append(intent.toString());
4304            msg.append(": ");
4305            msg.append(e.getMessage());
4306            */
4307            throw e;
4308        }
4309    }
4310
4311    @Override
4312    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4313            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4314            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4315        enforceNotIsolatedCaller("startActivityAndWait");
4316        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4317                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4318        WaitResult res = new WaitResult();
4319        // TODO: Switch to user app stacks here.
4320        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4321                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4322                bOptions, false, userId, null, null);
4323        return res;
4324    }
4325
4326    @Override
4327    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4328            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4329            int startFlags, Configuration config, Bundle bOptions, int userId) {
4330        enforceNotIsolatedCaller("startActivityWithConfig");
4331        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4332                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4333        // TODO: Switch to user app stacks here.
4334        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4335                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4336                null, null, config, bOptions, false, userId, null, null);
4337        return ret;
4338    }
4339
4340    @Override
4341    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4342            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4343            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4344            throws TransactionTooLargeException {
4345        enforceNotIsolatedCaller("startActivityIntentSender");
4346        // Refuse possible leaked file descriptors
4347        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4348            throw new IllegalArgumentException("File descriptors passed in Intent");
4349        }
4350
4351        IIntentSender sender = intent.getTarget();
4352        if (!(sender instanceof PendingIntentRecord)) {
4353            throw new IllegalArgumentException("Bad PendingIntent object");
4354        }
4355
4356        PendingIntentRecord pir = (PendingIntentRecord)sender;
4357
4358        synchronized (this) {
4359            // If this is coming from the currently resumed activity, it is
4360            // effectively saying that app switches are allowed at this point.
4361            final ActivityStack stack = getFocusedStack();
4362            if (stack.mResumedActivity != null &&
4363                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4364                mAppSwitchesAllowedTime = 0;
4365            }
4366        }
4367        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4368                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4369        return ret;
4370    }
4371
4372    @Override
4373    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4374            Intent intent, String resolvedType, IVoiceInteractionSession session,
4375            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4376            Bundle bOptions, int userId) {
4377        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4378                != PackageManager.PERMISSION_GRANTED) {
4379            String msg = "Permission Denial: startVoiceActivity() from pid="
4380                    + Binder.getCallingPid()
4381                    + ", uid=" + Binder.getCallingUid()
4382                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4383            Slog.w(TAG, msg);
4384            throw new SecurityException(msg);
4385        }
4386        if (session == null || interactor == null) {
4387            throw new NullPointerException("null session or interactor");
4388        }
4389        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4390                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4391        // TODO: Switch to user app stacks here.
4392        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4393                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4394                null, bOptions, false, userId, null, null);
4395    }
4396
4397    @Override
4398    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4399            throws RemoteException {
4400        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4401        synchronized (this) {
4402            ActivityRecord activity = getFocusedStack().topActivity();
4403            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4404                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4405            }
4406            if (mRunningVoice != null || activity.task.voiceSession != null
4407                    || activity.voiceSession != null) {
4408                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4409                return;
4410            }
4411            if (activity.pendingVoiceInteractionStart) {
4412                Slog.w(TAG, "Pending start of voice interaction already.");
4413                return;
4414            }
4415            activity.pendingVoiceInteractionStart = true;
4416        }
4417        LocalServices.getService(VoiceInteractionManagerInternal.class)
4418                .startLocalVoiceInteraction(callingActivity, options);
4419    }
4420
4421    @Override
4422    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4423        LocalServices.getService(VoiceInteractionManagerInternal.class)
4424                .stopLocalVoiceInteraction(callingActivity);
4425    }
4426
4427    @Override
4428    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4429        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4430                .supportsLocalVoiceInteraction();
4431    }
4432
4433    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4434            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4435        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4436        if (activityToCallback == null) return;
4437        activityToCallback.setVoiceSessionLocked(voiceSession);
4438
4439        // Inform the activity
4440        try {
4441            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4442                    voiceInteractor);
4443            long token = Binder.clearCallingIdentity();
4444            try {
4445                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4446            } finally {
4447                Binder.restoreCallingIdentity(token);
4448            }
4449            // TODO: VI Should we cache the activity so that it's easier to find later
4450            // rather than scan through all the stacks and activities?
4451        } catch (RemoteException re) {
4452            activityToCallback.clearVoiceSessionLocked();
4453            // TODO: VI Should this terminate the voice session?
4454        }
4455    }
4456
4457    @Override
4458    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4459        synchronized (this) {
4460            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4461                if (keepAwake) {
4462                    mVoiceWakeLock.acquire();
4463                } else {
4464                    mVoiceWakeLock.release();
4465                }
4466            }
4467        }
4468    }
4469
4470    @Override
4471    public boolean startNextMatchingActivity(IBinder callingActivity,
4472            Intent intent, Bundle bOptions) {
4473        // Refuse possible leaked file descriptors
4474        if (intent != null && intent.hasFileDescriptors() == true) {
4475            throw new IllegalArgumentException("File descriptors passed in Intent");
4476        }
4477        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4478
4479        synchronized (this) {
4480            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4481            if (r == null) {
4482                ActivityOptions.abort(options);
4483                return false;
4484            }
4485            if (r.app == null || r.app.thread == null) {
4486                // The caller is not running...  d'oh!
4487                ActivityOptions.abort(options);
4488                return false;
4489            }
4490            intent = new Intent(intent);
4491            // The caller is not allowed to change the data.
4492            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4493            // And we are resetting to find the next component...
4494            intent.setComponent(null);
4495
4496            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4497
4498            ActivityInfo aInfo = null;
4499            try {
4500                List<ResolveInfo> resolves =
4501                    AppGlobals.getPackageManager().queryIntentActivities(
4502                            intent, r.resolvedType,
4503                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4504                            UserHandle.getCallingUserId()).getList();
4505
4506                // Look for the original activity in the list...
4507                final int N = resolves != null ? resolves.size() : 0;
4508                for (int i=0; i<N; i++) {
4509                    ResolveInfo rInfo = resolves.get(i);
4510                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4511                            && rInfo.activityInfo.name.equals(r.info.name)) {
4512                        // We found the current one...  the next matching is
4513                        // after it.
4514                        i++;
4515                        if (i<N) {
4516                            aInfo = resolves.get(i).activityInfo;
4517                        }
4518                        if (debug) {
4519                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4520                                    + "/" + r.info.name);
4521                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4522                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4523                        }
4524                        break;
4525                    }
4526                }
4527            } catch (RemoteException e) {
4528            }
4529
4530            if (aInfo == null) {
4531                // Nobody who is next!
4532                ActivityOptions.abort(options);
4533                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4534                return false;
4535            }
4536
4537            intent.setComponent(new ComponentName(
4538                    aInfo.applicationInfo.packageName, aInfo.name));
4539            intent.setFlags(intent.getFlags()&~(
4540                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4541                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4542                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4543                    Intent.FLAG_ACTIVITY_NEW_TASK));
4544
4545            // Okay now we need to start the new activity, replacing the
4546            // currently running activity.  This is a little tricky because
4547            // we want to start the new one as if the current one is finished,
4548            // but not finish the current one first so that there is no flicker.
4549            // And thus...
4550            final boolean wasFinishing = r.finishing;
4551            r.finishing = true;
4552
4553            // Propagate reply information over to the new activity.
4554            final ActivityRecord resultTo = r.resultTo;
4555            final String resultWho = r.resultWho;
4556            final int requestCode = r.requestCode;
4557            r.resultTo = null;
4558            if (resultTo != null) {
4559                resultTo.removeResultsLocked(r, resultWho, requestCode);
4560            }
4561
4562            final long origId = Binder.clearCallingIdentity();
4563            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4564                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4565                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4566                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4567                    false, false, null, null, null);
4568            Binder.restoreCallingIdentity(origId);
4569
4570            r.finishing = wasFinishing;
4571            if (res != ActivityManager.START_SUCCESS) {
4572                return false;
4573            }
4574            return true;
4575        }
4576    }
4577
4578    @Override
4579    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4580        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4581            String msg = "Permission Denial: startActivityFromRecents called without " +
4582                    START_TASKS_FROM_RECENTS;
4583            Slog.w(TAG, msg);
4584            throw new SecurityException(msg);
4585        }
4586        final long origId = Binder.clearCallingIdentity();
4587        try {
4588            synchronized (this) {
4589                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4590            }
4591        } finally {
4592            Binder.restoreCallingIdentity(origId);
4593        }
4594    }
4595
4596    final int startActivityInPackage(int uid, String callingPackage,
4597            Intent intent, String resolvedType, IBinder resultTo,
4598            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4599            IActivityContainer container, TaskRecord inTask) {
4600
4601        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4602                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4603
4604        // TODO: Switch to user app stacks here.
4605        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4606                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4607                null, null, null, bOptions, false, userId, container, inTask);
4608        return ret;
4609    }
4610
4611    @Override
4612    public final int startActivities(IApplicationThread caller, String callingPackage,
4613            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4614            int userId) {
4615        enforceNotIsolatedCaller("startActivities");
4616        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4617                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4618        // TODO: Switch to user app stacks here.
4619        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4620                resolvedTypes, resultTo, bOptions, userId);
4621        return ret;
4622    }
4623
4624    final int startActivitiesInPackage(int uid, String callingPackage,
4625            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4626            Bundle bOptions, int userId) {
4627
4628        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4629                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4630        // TODO: Switch to user app stacks here.
4631        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4632                resultTo, bOptions, userId);
4633        return ret;
4634    }
4635
4636    @Override
4637    public void reportActivityFullyDrawn(IBinder token) {
4638        synchronized (this) {
4639            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4640            if (r == null) {
4641                return;
4642            }
4643            r.reportFullyDrawnLocked();
4644        }
4645    }
4646
4647    @Override
4648    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4649        synchronized (this) {
4650            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4651            if (r == null) {
4652                return;
4653            }
4654            TaskRecord task = r.task;
4655            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4656                // Fixed screen orientation isn't supported when activities aren't in full screen
4657                // mode.
4658                return;
4659            }
4660            final long origId = Binder.clearCallingIdentity();
4661            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4662            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4663                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4664            if (config != null) {
4665                r.frozenBeforeDestroy = true;
4666                if (!updateConfigurationLocked(config, r, false)) {
4667                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4668                }
4669            }
4670            Binder.restoreCallingIdentity(origId);
4671        }
4672    }
4673
4674    @Override
4675    public int getRequestedOrientation(IBinder token) {
4676        synchronized (this) {
4677            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4678            if (r == null) {
4679                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4680            }
4681            return mWindowManager.getAppOrientation(r.appToken);
4682        }
4683    }
4684
4685    /**
4686     * This is the internal entry point for handling Activity.finish().
4687     *
4688     * @param token The Binder token referencing the Activity we want to finish.
4689     * @param resultCode Result code, if any, from this Activity.
4690     * @param resultData Result data (Intent), if any, from this Activity.
4691     * @param finishTask Whether to finish the task associated with this Activity.
4692     *
4693     * @return Returns true if the activity successfully finished, or false if it is still running.
4694     */
4695    @Override
4696    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4697            int finishTask) {
4698        // Refuse possible leaked file descriptors
4699        if (resultData != null && resultData.hasFileDescriptors() == true) {
4700            throw new IllegalArgumentException("File descriptors passed in Intent");
4701        }
4702
4703        synchronized(this) {
4704            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4705            if (r == null) {
4706                return true;
4707            }
4708            // Keep track of the root activity of the task before we finish it
4709            TaskRecord tr = r.task;
4710            ActivityRecord rootR = tr.getRootActivity();
4711            if (rootR == null) {
4712                Slog.w(TAG, "Finishing task with all activities already finished");
4713            }
4714            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4715            // finish.
4716            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4717                    mStackSupervisor.isLastLockedTask(tr)) {
4718                Slog.i(TAG, "Not finishing task in lock task mode");
4719                mStackSupervisor.showLockTaskToast();
4720                return false;
4721            }
4722            if (mController != null) {
4723                // Find the first activity that is not finishing.
4724                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4725                if (next != null) {
4726                    // ask watcher if this is allowed
4727                    boolean resumeOK = true;
4728                    try {
4729                        resumeOK = mController.activityResuming(next.packageName);
4730                    } catch (RemoteException e) {
4731                        mController = null;
4732                        Watchdog.getInstance().setActivityController(null);
4733                    }
4734
4735                    if (!resumeOK) {
4736                        Slog.i(TAG, "Not finishing activity because controller resumed");
4737                        return false;
4738                    }
4739                }
4740            }
4741            final long origId = Binder.clearCallingIdentity();
4742            try {
4743                boolean res;
4744                final boolean finishWithRootActivity =
4745                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4746                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4747                        || (finishWithRootActivity && r == rootR)) {
4748                    // If requested, remove the task that is associated to this activity only if it
4749                    // was the root activity in the task. The result code and data is ignored
4750                    // because we don't support returning them across task boundaries. Also, to
4751                    // keep backwards compatibility we remove the task from recents when finishing
4752                    // task with root activity.
4753                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4754                    if (!res) {
4755                        Slog.i(TAG, "Removing task failed to finish activity");
4756                    }
4757                } else {
4758                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4759                            resultData, "app-request", true);
4760                    if (!res) {
4761                        Slog.i(TAG, "Failed to finish by app-request");
4762                    }
4763                }
4764                return res;
4765            } finally {
4766                Binder.restoreCallingIdentity(origId);
4767            }
4768        }
4769    }
4770
4771    @Override
4772    public final void finishHeavyWeightApp() {
4773        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4774                != PackageManager.PERMISSION_GRANTED) {
4775            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4776                    + Binder.getCallingPid()
4777                    + ", uid=" + Binder.getCallingUid()
4778                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4779            Slog.w(TAG, msg);
4780            throw new SecurityException(msg);
4781        }
4782
4783        synchronized(this) {
4784            if (mHeavyWeightProcess == null) {
4785                return;
4786            }
4787
4788            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4789            for (int i = 0; i < activities.size(); i++) {
4790                ActivityRecord r = activities.get(i);
4791                if (!r.finishing && r.isInStackLocked()) {
4792                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4793                            null, "finish-heavy", true);
4794                }
4795            }
4796
4797            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4798                    mHeavyWeightProcess.userId, 0));
4799            mHeavyWeightProcess = null;
4800        }
4801    }
4802
4803    @Override
4804    public void crashApplication(int uid, int initialPid, String packageName,
4805            String message) {
4806        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4807                != PackageManager.PERMISSION_GRANTED) {
4808            String msg = "Permission Denial: crashApplication() from pid="
4809                    + Binder.getCallingPid()
4810                    + ", uid=" + Binder.getCallingUid()
4811                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4812            Slog.w(TAG, msg);
4813            throw new SecurityException(msg);
4814        }
4815
4816        synchronized(this) {
4817            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4818        }
4819    }
4820
4821    @Override
4822    public final void finishSubActivity(IBinder token, String resultWho,
4823            int requestCode) {
4824        synchronized(this) {
4825            final long origId = Binder.clearCallingIdentity();
4826            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4827            if (r != null) {
4828                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4829            }
4830            Binder.restoreCallingIdentity(origId);
4831        }
4832    }
4833
4834    @Override
4835    public boolean finishActivityAffinity(IBinder token) {
4836        synchronized(this) {
4837            final long origId = Binder.clearCallingIdentity();
4838            try {
4839                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4840                if (r == null) {
4841                    return false;
4842                }
4843
4844                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4845                // can finish.
4846                final TaskRecord task = r.task;
4847                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4848                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4849                    mStackSupervisor.showLockTaskToast();
4850                    return false;
4851                }
4852                return task.stack.finishActivityAffinityLocked(r);
4853            } finally {
4854                Binder.restoreCallingIdentity(origId);
4855            }
4856        }
4857    }
4858
4859    @Override
4860    public void finishVoiceTask(IVoiceInteractionSession session) {
4861        synchronized (this) {
4862            final long origId = Binder.clearCallingIdentity();
4863            try {
4864                // TODO: VI Consider treating local voice interactions and voice tasks
4865                // differently here
4866                mStackSupervisor.finishVoiceTask(session);
4867            } finally {
4868                Binder.restoreCallingIdentity(origId);
4869            }
4870        }
4871
4872    }
4873
4874    @Override
4875    public boolean releaseActivityInstance(IBinder token) {
4876        synchronized(this) {
4877            final long origId = Binder.clearCallingIdentity();
4878            try {
4879                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4880                if (r == null) {
4881                    return false;
4882                }
4883                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4884            } finally {
4885                Binder.restoreCallingIdentity(origId);
4886            }
4887        }
4888    }
4889
4890    @Override
4891    public void releaseSomeActivities(IApplicationThread appInt) {
4892        synchronized(this) {
4893            final long origId = Binder.clearCallingIdentity();
4894            try {
4895                ProcessRecord app = getRecordForAppLocked(appInt);
4896                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4897            } finally {
4898                Binder.restoreCallingIdentity(origId);
4899            }
4900        }
4901    }
4902
4903    @Override
4904    public boolean willActivityBeVisible(IBinder token) {
4905        synchronized(this) {
4906            ActivityStack stack = ActivityRecord.getStackLocked(token);
4907            if (stack != null) {
4908                return stack.willActivityBeVisibleLocked(token);
4909            }
4910            return false;
4911        }
4912    }
4913
4914    @Override
4915    public void overridePendingTransition(IBinder token, String packageName,
4916            int enterAnim, int exitAnim) {
4917        synchronized(this) {
4918            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4919            if (self == null) {
4920                return;
4921            }
4922
4923            final long origId = Binder.clearCallingIdentity();
4924
4925            if (self.state == ActivityState.RESUMED
4926                    || self.state == ActivityState.PAUSING) {
4927                mWindowManager.overridePendingAppTransition(packageName,
4928                        enterAnim, exitAnim, null);
4929            }
4930
4931            Binder.restoreCallingIdentity(origId);
4932        }
4933    }
4934
4935    /**
4936     * Main function for removing an existing process from the activity manager
4937     * as a result of that process going away.  Clears out all connections
4938     * to the process.
4939     */
4940    private final void handleAppDiedLocked(ProcessRecord app,
4941            boolean restarting, boolean allowRestart) {
4942        int pid = app.pid;
4943        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4944        if (!kept && !restarting) {
4945            removeLruProcessLocked(app);
4946            if (pid > 0) {
4947                ProcessList.remove(pid);
4948            }
4949        }
4950
4951        if (mProfileProc == app) {
4952            clearProfilerLocked();
4953        }
4954
4955        // Remove this application's activities from active lists.
4956        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4957
4958        app.activities.clear();
4959
4960        if (app.instrumentationClass != null) {
4961            Slog.w(TAG, "Crash of app " + app.processName
4962                  + " running instrumentation " + app.instrumentationClass);
4963            Bundle info = new Bundle();
4964            info.putString("shortMsg", "Process crashed.");
4965            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4966        }
4967
4968        if (!restarting && hasVisibleActivities
4969                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4970            // If there was nothing to resume, and we are not already restarting this process, but
4971            // there is a visible activity that is hosted by the process...  then make sure all
4972            // visible activities are running, taking care of restarting this process.
4973            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4974        }
4975    }
4976
4977    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4978        IBinder threadBinder = thread.asBinder();
4979        // Find the application record.
4980        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4981            ProcessRecord rec = mLruProcesses.get(i);
4982            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4983                return i;
4984            }
4985        }
4986        return -1;
4987    }
4988
4989    final ProcessRecord getRecordForAppLocked(
4990            IApplicationThread thread) {
4991        if (thread == null) {
4992            return null;
4993        }
4994
4995        int appIndex = getLRURecordIndexForAppLocked(thread);
4996        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4997    }
4998
4999    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5000        // If there are no longer any background processes running,
5001        // and the app that died was not running instrumentation,
5002        // then tell everyone we are now low on memory.
5003        boolean haveBg = false;
5004        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5005            ProcessRecord rec = mLruProcesses.get(i);
5006            if (rec.thread != null
5007                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5008                haveBg = true;
5009                break;
5010            }
5011        }
5012
5013        if (!haveBg) {
5014            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5015            if (doReport) {
5016                long now = SystemClock.uptimeMillis();
5017                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5018                    doReport = false;
5019                } else {
5020                    mLastMemUsageReportTime = now;
5021                }
5022            }
5023            final ArrayList<ProcessMemInfo> memInfos
5024                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5025            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5026            long now = SystemClock.uptimeMillis();
5027            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5028                ProcessRecord rec = mLruProcesses.get(i);
5029                if (rec == dyingProc || rec.thread == null) {
5030                    continue;
5031                }
5032                if (doReport) {
5033                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5034                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5035                }
5036                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5037                    // The low memory report is overriding any current
5038                    // state for a GC request.  Make sure to do
5039                    // heavy/important/visible/foreground processes first.
5040                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5041                        rec.lastRequestedGc = 0;
5042                    } else {
5043                        rec.lastRequestedGc = rec.lastLowMemory;
5044                    }
5045                    rec.reportLowMemory = true;
5046                    rec.lastLowMemory = now;
5047                    mProcessesToGc.remove(rec);
5048                    addProcessToGcListLocked(rec);
5049                }
5050            }
5051            if (doReport) {
5052                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5053                mHandler.sendMessage(msg);
5054            }
5055            scheduleAppGcsLocked();
5056        }
5057    }
5058
5059    final void appDiedLocked(ProcessRecord app) {
5060       appDiedLocked(app, app.pid, app.thread, false);
5061    }
5062
5063    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5064            boolean fromBinderDied) {
5065        // First check if this ProcessRecord is actually active for the pid.
5066        synchronized (mPidsSelfLocked) {
5067            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5068            if (curProc != app) {
5069                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5070                return;
5071            }
5072        }
5073
5074        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5075        synchronized (stats) {
5076            stats.noteProcessDiedLocked(app.info.uid, pid);
5077        }
5078
5079        if (!app.killed) {
5080            if (!fromBinderDied) {
5081                Process.killProcessQuiet(pid);
5082            }
5083            killProcessGroup(app.uid, pid);
5084            app.killed = true;
5085        }
5086
5087        // Clean up already done if the process has been re-started.
5088        if (app.pid == pid && app.thread != null &&
5089                app.thread.asBinder() == thread.asBinder()) {
5090            boolean doLowMem = app.instrumentationClass == null;
5091            boolean doOomAdj = doLowMem;
5092            if (!app.killedByAm) {
5093                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5094                        + ") has died");
5095                mAllowLowerMemLevel = true;
5096            } else {
5097                // Note that we always want to do oom adj to update our state with the
5098                // new number of procs.
5099                mAllowLowerMemLevel = false;
5100                doLowMem = false;
5101            }
5102            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5103            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5104                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5105            handleAppDiedLocked(app, false, true);
5106
5107            if (doOomAdj) {
5108                updateOomAdjLocked();
5109            }
5110            if (doLowMem) {
5111                doLowMemReportIfNeededLocked(app);
5112            }
5113        } else if (app.pid != pid) {
5114            // A new process has already been started.
5115            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5116                    + ") has died and restarted (pid " + app.pid + ").");
5117            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5118        } else if (DEBUG_PROCESSES) {
5119            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5120                    + thread.asBinder());
5121        }
5122    }
5123
5124    /**
5125     * If a stack trace dump file is configured, dump process stack traces.
5126     * @param clearTraces causes the dump file to be erased prior to the new
5127     *    traces being written, if true; when false, the new traces will be
5128     *    appended to any existing file content.
5129     * @param firstPids of dalvik VM processes to dump stack traces for first
5130     * @param lastPids of dalvik VM processes to dump stack traces for last
5131     * @param nativeProcs optional list of native process names to dump stack crawls
5132     * @return file containing stack traces, or null if no dump file is configured
5133     */
5134    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5135            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5136        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5137        if (tracesPath == null || tracesPath.length() == 0) {
5138            return null;
5139        }
5140
5141        File tracesFile = new File(tracesPath);
5142        try {
5143            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5144            tracesFile.createNewFile();
5145            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5146        } catch (IOException e) {
5147            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5148            return null;
5149        }
5150
5151        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5152        return tracesFile;
5153    }
5154
5155    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5156            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5157        // Use a FileObserver to detect when traces finish writing.
5158        // The order of traces is considered important to maintain for legibility.
5159        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5160            @Override
5161            public synchronized void onEvent(int event, String path) { notify(); }
5162        };
5163
5164        try {
5165            observer.startWatching();
5166
5167            // First collect all of the stacks of the most important pids.
5168            if (firstPids != null) {
5169                try {
5170                    int num = firstPids.size();
5171                    for (int i = 0; i < num; i++) {
5172                        synchronized (observer) {
5173                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5174                                    + firstPids.get(i));
5175                            final long sime = SystemClock.elapsedRealtime();
5176                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5177                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5178                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5179                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5180                        }
5181                    }
5182                } catch (InterruptedException e) {
5183                    Slog.wtf(TAG, e);
5184                }
5185            }
5186
5187            // Next collect the stacks of the native pids
5188            if (nativeProcs != null) {
5189                int[] pids = Process.getPidsForCommands(nativeProcs);
5190                if (pids != null) {
5191                    for (int pid : pids) {
5192                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5193                        final long sime = SystemClock.elapsedRealtime();
5194                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5195                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5196                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5197                    }
5198                }
5199            }
5200
5201            // Lastly, measure CPU usage.
5202            if (processCpuTracker != null) {
5203                processCpuTracker.init();
5204                System.gc();
5205                processCpuTracker.update();
5206                try {
5207                    synchronized (processCpuTracker) {
5208                        processCpuTracker.wait(500); // measure over 1/2 second.
5209                    }
5210                } catch (InterruptedException e) {
5211                }
5212                processCpuTracker.update();
5213
5214                // We'll take the stack crawls of just the top apps using CPU.
5215                final int N = processCpuTracker.countWorkingStats();
5216                int numProcs = 0;
5217                for (int i=0; i<N && numProcs<5; i++) {
5218                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5219                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5220                        numProcs++;
5221                        try {
5222                            synchronized (observer) {
5223                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5224                                        + stats.pid);
5225                                final long stime = SystemClock.elapsedRealtime();
5226                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5227                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5228                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5229                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5230                            }
5231                        } catch (InterruptedException e) {
5232                            Slog.wtf(TAG, e);
5233                        }
5234                    } else if (DEBUG_ANR) {
5235                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5236                                + stats.pid);
5237                    }
5238                }
5239            }
5240        } finally {
5241            observer.stopWatching();
5242        }
5243    }
5244
5245    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5246        if (true || IS_USER_BUILD) {
5247            return;
5248        }
5249        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5250        if (tracesPath == null || tracesPath.length() == 0) {
5251            return;
5252        }
5253
5254        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5255        StrictMode.allowThreadDiskWrites();
5256        try {
5257            final File tracesFile = new File(tracesPath);
5258            final File tracesDir = tracesFile.getParentFile();
5259            final File tracesTmp = new File(tracesDir, "__tmp__");
5260            try {
5261                if (tracesFile.exists()) {
5262                    tracesTmp.delete();
5263                    tracesFile.renameTo(tracesTmp);
5264                }
5265                StringBuilder sb = new StringBuilder();
5266                Time tobj = new Time();
5267                tobj.set(System.currentTimeMillis());
5268                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5269                sb.append(": ");
5270                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5271                sb.append(" since ");
5272                sb.append(msg);
5273                FileOutputStream fos = new FileOutputStream(tracesFile);
5274                fos.write(sb.toString().getBytes());
5275                if (app == null) {
5276                    fos.write("\n*** No application process!".getBytes());
5277                }
5278                fos.close();
5279                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5280            } catch (IOException e) {
5281                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5282                return;
5283            }
5284
5285            if (app != null) {
5286                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5287                firstPids.add(app.pid);
5288                dumpStackTraces(tracesPath, firstPids, null, null, null);
5289            }
5290
5291            File lastTracesFile = null;
5292            File curTracesFile = null;
5293            for (int i=9; i>=0; i--) {
5294                String name = String.format(Locale.US, "slow%02d.txt", i);
5295                curTracesFile = new File(tracesDir, name);
5296                if (curTracesFile.exists()) {
5297                    if (lastTracesFile != null) {
5298                        curTracesFile.renameTo(lastTracesFile);
5299                    } else {
5300                        curTracesFile.delete();
5301                    }
5302                }
5303                lastTracesFile = curTracesFile;
5304            }
5305            tracesFile.renameTo(curTracesFile);
5306            if (tracesTmp.exists()) {
5307                tracesTmp.renameTo(tracesFile);
5308            }
5309        } finally {
5310            StrictMode.setThreadPolicy(oldPolicy);
5311        }
5312    }
5313
5314    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5315        if (!mLaunchWarningShown) {
5316            mLaunchWarningShown = true;
5317            mUiHandler.post(new Runnable() {
5318                @Override
5319                public void run() {
5320                    synchronized (ActivityManagerService.this) {
5321                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5322                        d.show();
5323                        mUiHandler.postDelayed(new Runnable() {
5324                            @Override
5325                            public void run() {
5326                                synchronized (ActivityManagerService.this) {
5327                                    d.dismiss();
5328                                    mLaunchWarningShown = false;
5329                                }
5330                            }
5331                        }, 4000);
5332                    }
5333                }
5334            });
5335        }
5336    }
5337
5338    @Override
5339    public boolean clearApplicationUserData(final String packageName,
5340            final IPackageDataObserver observer, int userId) {
5341        enforceNotIsolatedCaller("clearApplicationUserData");
5342        int uid = Binder.getCallingUid();
5343        int pid = Binder.getCallingPid();
5344        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5345                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5346
5347        final DevicePolicyManagerInternal dpmi = LocalServices
5348                .getService(DevicePolicyManagerInternal.class);
5349        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5350            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5351        }
5352
5353        long callingId = Binder.clearCallingIdentity();
5354        try {
5355            IPackageManager pm = AppGlobals.getPackageManager();
5356            int pkgUid = -1;
5357            synchronized(this) {
5358                try {
5359                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5360                } catch (RemoteException e) {
5361                }
5362                if (pkgUid == -1) {
5363                    Slog.w(TAG, "Invalid packageName: " + packageName);
5364                    if (observer != null) {
5365                        try {
5366                            observer.onRemoveCompleted(packageName, false);
5367                        } catch (RemoteException e) {
5368                            Slog.i(TAG, "Observer no longer exists.");
5369                        }
5370                    }
5371                    return false;
5372                }
5373                if (uid == pkgUid || checkComponentPermission(
5374                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5375                        pid, uid, -1, true)
5376                        == PackageManager.PERMISSION_GRANTED) {
5377                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5378                } else {
5379                    throw new SecurityException("PID " + pid + " does not have permission "
5380                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5381                                    + " of package " + packageName);
5382                }
5383
5384                // Remove all tasks match the cleared application package and user
5385                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5386                    final TaskRecord tr = mRecentTasks.get(i);
5387                    final String taskPackageName =
5388                            tr.getBaseIntent().getComponent().getPackageName();
5389                    if (tr.userId != userId) continue;
5390                    if (!taskPackageName.equals(packageName)) continue;
5391                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5392                }
5393            }
5394
5395            try {
5396                // Clear application user data
5397                pm.clearApplicationUserData(packageName, observer, userId);
5398
5399                synchronized(this) {
5400                    // Remove all permissions granted from/to this package
5401                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5402                }
5403
5404                // Remove all zen rules created by this package; revoke it's zen access.
5405                INotificationManager inm = NotificationManager.getService();
5406                inm.removeAutomaticZenRules(packageName);
5407                inm.setNotificationPolicyAccessGranted(packageName, false);
5408
5409                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5410                        Uri.fromParts("package", packageName, null));
5411                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5412                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5413                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5414                        null, null, 0, null, null, null, null, false, false, userId);
5415            } catch (RemoteException e) {
5416            }
5417        } finally {
5418            Binder.restoreCallingIdentity(callingId);
5419        }
5420        return true;
5421    }
5422
5423    @Override
5424    public void killBackgroundProcesses(final String packageName, int userId) {
5425        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5426                != PackageManager.PERMISSION_GRANTED &&
5427                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5428                        != PackageManager.PERMISSION_GRANTED) {
5429            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5430                    + Binder.getCallingPid()
5431                    + ", uid=" + Binder.getCallingUid()
5432                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5433            Slog.w(TAG, msg);
5434            throw new SecurityException(msg);
5435        }
5436
5437        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5438                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5439        long callingId = Binder.clearCallingIdentity();
5440        try {
5441            IPackageManager pm = AppGlobals.getPackageManager();
5442            synchronized(this) {
5443                int appId = -1;
5444                try {
5445                    appId = UserHandle.getAppId(
5446                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5447                } catch (RemoteException e) {
5448                }
5449                if (appId == -1) {
5450                    Slog.w(TAG, "Invalid packageName: " + packageName);
5451                    return;
5452                }
5453                killPackageProcessesLocked(packageName, appId, userId,
5454                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5455            }
5456        } finally {
5457            Binder.restoreCallingIdentity(callingId);
5458        }
5459    }
5460
5461    @Override
5462    public void killAllBackgroundProcesses() {
5463        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5464                != PackageManager.PERMISSION_GRANTED) {
5465            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5466                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5467                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5468            Slog.w(TAG, msg);
5469            throw new SecurityException(msg);
5470        }
5471
5472        final long callingId = Binder.clearCallingIdentity();
5473        try {
5474            synchronized (this) {
5475                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5476                final int NP = mProcessNames.getMap().size();
5477                for (int ip = 0; ip < NP; ip++) {
5478                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5479                    final int NA = apps.size();
5480                    for (int ia = 0; ia < NA; ia++) {
5481                        final ProcessRecord app = apps.valueAt(ia);
5482                        if (app.persistent) {
5483                            // We don't kill persistent processes.
5484                            continue;
5485                        }
5486                        if (app.removed) {
5487                            procs.add(app);
5488                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5489                            app.removed = true;
5490                            procs.add(app);
5491                        }
5492                    }
5493                }
5494
5495                final int N = procs.size();
5496                for (int i = 0; i < N; i++) {
5497                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5498                }
5499
5500                mAllowLowerMemLevel = true;
5501
5502                updateOomAdjLocked();
5503                doLowMemReportIfNeededLocked(null);
5504            }
5505        } finally {
5506            Binder.restoreCallingIdentity(callingId);
5507        }
5508    }
5509
5510    /**
5511     * Kills all background processes, except those matching any of the
5512     * specified properties.
5513     *
5514     * @param minTargetSdk the target SDK version at or above which to preserve
5515     *                     processes, or {@code -1} to ignore the target SDK
5516     * @param maxProcState the process state at or below which to preserve
5517     *                     processes, or {@code -1} to ignore the process state
5518     */
5519    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5520        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5521                != PackageManager.PERMISSION_GRANTED) {
5522            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5523                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5524                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5525            Slog.w(TAG, msg);
5526            throw new SecurityException(msg);
5527        }
5528
5529        final long callingId = Binder.clearCallingIdentity();
5530        try {
5531            synchronized (this) {
5532                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5533                final int NP = mProcessNames.getMap().size();
5534                for (int ip = 0; ip < NP; ip++) {
5535                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5536                    final int NA = apps.size();
5537                    for (int ia = 0; ia < NA; ia++) {
5538                        final ProcessRecord app = apps.valueAt(ia);
5539                        if (app.removed) {
5540                            procs.add(app);
5541                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5542                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5543                            app.removed = true;
5544                            procs.add(app);
5545                        }
5546                    }
5547                }
5548
5549                final int N = procs.size();
5550                for (int i = 0; i < N; i++) {
5551                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5552                }
5553            }
5554        } finally {
5555            Binder.restoreCallingIdentity(callingId);
5556        }
5557    }
5558
5559    @Override
5560    public void forceStopPackage(final String packageName, int userId) {
5561        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5562                != PackageManager.PERMISSION_GRANTED) {
5563            String msg = "Permission Denial: forceStopPackage() from pid="
5564                    + Binder.getCallingPid()
5565                    + ", uid=" + Binder.getCallingUid()
5566                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5567            Slog.w(TAG, msg);
5568            throw new SecurityException(msg);
5569        }
5570        final int callingPid = Binder.getCallingPid();
5571        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5572                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5573        long callingId = Binder.clearCallingIdentity();
5574        try {
5575            IPackageManager pm = AppGlobals.getPackageManager();
5576            synchronized(this) {
5577                int[] users = userId == UserHandle.USER_ALL
5578                        ? mUserController.getUsers() : new int[] { userId };
5579                for (int user : users) {
5580                    int pkgUid = -1;
5581                    try {
5582                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5583                                user);
5584                    } catch (RemoteException e) {
5585                    }
5586                    if (pkgUid == -1) {
5587                        Slog.w(TAG, "Invalid packageName: " + packageName);
5588                        continue;
5589                    }
5590                    try {
5591                        pm.setPackageStoppedState(packageName, true, user);
5592                    } catch (RemoteException e) {
5593                    } catch (IllegalArgumentException e) {
5594                        Slog.w(TAG, "Failed trying to unstop package "
5595                                + packageName + ": " + e);
5596                    }
5597                    if (mUserController.isUserRunningLocked(user, 0)) {
5598                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5599                    }
5600                }
5601            }
5602        } finally {
5603            Binder.restoreCallingIdentity(callingId);
5604        }
5605    }
5606
5607    @Override
5608    public void addPackageDependency(String packageName) {
5609        synchronized (this) {
5610            int callingPid = Binder.getCallingPid();
5611            if (callingPid == Process.myPid()) {
5612                //  Yeah, um, no.
5613                return;
5614            }
5615            ProcessRecord proc;
5616            synchronized (mPidsSelfLocked) {
5617                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5618            }
5619            if (proc != null) {
5620                if (proc.pkgDeps == null) {
5621                    proc.pkgDeps = new ArraySet<String>(1);
5622                }
5623                proc.pkgDeps.add(packageName);
5624            }
5625        }
5626    }
5627
5628    /*
5629     * The pkg name and app id have to be specified.
5630     */
5631    @Override
5632    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5633        if (pkg == null) {
5634            return;
5635        }
5636        // Make sure the uid is valid.
5637        if (appid < 0) {
5638            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5639            return;
5640        }
5641        int callerUid = Binder.getCallingUid();
5642        // Only the system server can kill an application
5643        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5644            // Post an aysnc message to kill the application
5645            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5646            msg.arg1 = appid;
5647            msg.arg2 = 0;
5648            Bundle bundle = new Bundle();
5649            bundle.putString("pkg", pkg);
5650            bundle.putString("reason", reason);
5651            msg.obj = bundle;
5652            mHandler.sendMessage(msg);
5653        } else {
5654            throw new SecurityException(callerUid + " cannot kill pkg: " +
5655                    pkg);
5656        }
5657    }
5658
5659    @Override
5660    public void closeSystemDialogs(String reason) {
5661        enforceNotIsolatedCaller("closeSystemDialogs");
5662
5663        final int pid = Binder.getCallingPid();
5664        final int uid = Binder.getCallingUid();
5665        final long origId = Binder.clearCallingIdentity();
5666        try {
5667            synchronized (this) {
5668                // Only allow this from foreground processes, so that background
5669                // applications can't abuse it to prevent system UI from being shown.
5670                if (uid >= Process.FIRST_APPLICATION_UID) {
5671                    ProcessRecord proc;
5672                    synchronized (mPidsSelfLocked) {
5673                        proc = mPidsSelfLocked.get(pid);
5674                    }
5675                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5676                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5677                                + " from background process " + proc);
5678                        return;
5679                    }
5680                }
5681                closeSystemDialogsLocked(reason);
5682            }
5683        } finally {
5684            Binder.restoreCallingIdentity(origId);
5685        }
5686    }
5687
5688    void closeSystemDialogsLocked(String reason) {
5689        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5690        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5691                | Intent.FLAG_RECEIVER_FOREGROUND);
5692        if (reason != null) {
5693            intent.putExtra("reason", reason);
5694        }
5695        mWindowManager.closeSystemDialogs(reason);
5696
5697        mStackSupervisor.closeSystemDialogsLocked();
5698
5699        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5700                AppOpsManager.OP_NONE, null, false, false,
5701                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5702    }
5703
5704    @Override
5705    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5706        enforceNotIsolatedCaller("getProcessMemoryInfo");
5707        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5708        for (int i=pids.length-1; i>=0; i--) {
5709            ProcessRecord proc;
5710            int oomAdj;
5711            synchronized (this) {
5712                synchronized (mPidsSelfLocked) {
5713                    proc = mPidsSelfLocked.get(pids[i]);
5714                    oomAdj = proc != null ? proc.setAdj : 0;
5715                }
5716            }
5717            infos[i] = new Debug.MemoryInfo();
5718            Debug.getMemoryInfo(pids[i], infos[i]);
5719            if (proc != null) {
5720                synchronized (this) {
5721                    if (proc.thread != null && proc.setAdj == oomAdj) {
5722                        // Record this for posterity if the process has been stable.
5723                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5724                                infos[i].getTotalUss(), false, proc.pkgList);
5725                    }
5726                }
5727            }
5728        }
5729        return infos;
5730    }
5731
5732    @Override
5733    public long[] getProcessPss(int[] pids) {
5734        enforceNotIsolatedCaller("getProcessPss");
5735        long[] pss = new long[pids.length];
5736        for (int i=pids.length-1; i>=0; i--) {
5737            ProcessRecord proc;
5738            int oomAdj;
5739            synchronized (this) {
5740                synchronized (mPidsSelfLocked) {
5741                    proc = mPidsSelfLocked.get(pids[i]);
5742                    oomAdj = proc != null ? proc.setAdj : 0;
5743                }
5744            }
5745            long[] tmpUss = new long[1];
5746            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5747            if (proc != null) {
5748                synchronized (this) {
5749                    if (proc.thread != null && proc.setAdj == oomAdj) {
5750                        // Record this for posterity if the process has been stable.
5751                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5752                    }
5753                }
5754            }
5755        }
5756        return pss;
5757    }
5758
5759    @Override
5760    public void killApplicationProcess(String processName, int uid) {
5761        if (processName == null) {
5762            return;
5763        }
5764
5765        int callerUid = Binder.getCallingUid();
5766        // Only the system server can kill an application
5767        if (callerUid == Process.SYSTEM_UID) {
5768            synchronized (this) {
5769                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5770                if (app != null && app.thread != null) {
5771                    try {
5772                        app.thread.scheduleSuicide();
5773                    } catch (RemoteException e) {
5774                        // If the other end already died, then our work here is done.
5775                    }
5776                } else {
5777                    Slog.w(TAG, "Process/uid not found attempting kill of "
5778                            + processName + " / " + uid);
5779                }
5780            }
5781        } else {
5782            throw new SecurityException(callerUid + " cannot kill app process: " +
5783                    processName);
5784        }
5785    }
5786
5787    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5788        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5789                false, true, false, false, UserHandle.getUserId(uid), reason);
5790        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5791                Uri.fromParts("package", packageName, null));
5792        if (!mProcessesReady) {
5793            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5794                    | Intent.FLAG_RECEIVER_FOREGROUND);
5795        }
5796        intent.putExtra(Intent.EXTRA_UID, uid);
5797        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5798        broadcastIntentLocked(null, null, intent,
5799                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5800                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5801    }
5802
5803
5804    private final boolean killPackageProcessesLocked(String packageName, int appId,
5805            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5806            boolean doit, boolean evenPersistent, String reason) {
5807        ArrayList<ProcessRecord> procs = new ArrayList<>();
5808
5809        // Remove all processes this package may have touched: all with the
5810        // same UID (except for the system or root user), and all whose name
5811        // matches the package name.
5812        final int NP = mProcessNames.getMap().size();
5813        for (int ip=0; ip<NP; ip++) {
5814            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5815            final int NA = apps.size();
5816            for (int ia=0; ia<NA; ia++) {
5817                ProcessRecord app = apps.valueAt(ia);
5818                if (app.persistent && !evenPersistent) {
5819                    // we don't kill persistent processes
5820                    continue;
5821                }
5822                if (app.removed) {
5823                    if (doit) {
5824                        procs.add(app);
5825                    }
5826                    continue;
5827                }
5828
5829                // Skip process if it doesn't meet our oom adj requirement.
5830                if (app.setAdj < minOomAdj) {
5831                    continue;
5832                }
5833
5834                // If no package is specified, we call all processes under the
5835                // give user id.
5836                if (packageName == null) {
5837                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5838                        continue;
5839                    }
5840                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5841                        continue;
5842                    }
5843                // Package has been specified, we want to hit all processes
5844                // that match it.  We need to qualify this by the processes
5845                // that are running under the specified app and user ID.
5846                } else {
5847                    final boolean isDep = app.pkgDeps != null
5848                            && app.pkgDeps.contains(packageName);
5849                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5850                        continue;
5851                    }
5852                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5853                        continue;
5854                    }
5855                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5856                        continue;
5857                    }
5858                }
5859
5860                // Process has passed all conditions, kill it!
5861                if (!doit) {
5862                    return true;
5863                }
5864                app.removed = true;
5865                procs.add(app);
5866            }
5867        }
5868
5869        int N = procs.size();
5870        for (int i=0; i<N; i++) {
5871            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5872        }
5873        updateOomAdjLocked();
5874        return N > 0;
5875    }
5876
5877    private void cleanupDisabledPackageComponentsLocked(
5878            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5879
5880        Set<String> disabledClasses = null;
5881        boolean packageDisabled = false;
5882        IPackageManager pm = AppGlobals.getPackageManager();
5883
5884        if (changedClasses == null) {
5885            // Nothing changed...
5886            return;
5887        }
5888
5889        // Determine enable/disable state of the package and its components.
5890        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5891        for (int i = changedClasses.length - 1; i >= 0; i--) {
5892            final String changedClass = changedClasses[i];
5893
5894            if (changedClass.equals(packageName)) {
5895                try {
5896                    // Entire package setting changed
5897                    enabled = pm.getApplicationEnabledSetting(packageName,
5898                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5899                } catch (Exception e) {
5900                    // No such package/component; probably racing with uninstall.  In any
5901                    // event it means we have nothing further to do here.
5902                    return;
5903                }
5904                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5905                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5906                if (packageDisabled) {
5907                    // Entire package is disabled.
5908                    // No need to continue to check component states.
5909                    disabledClasses = null;
5910                    break;
5911                }
5912            } else {
5913                try {
5914                    enabled = pm.getComponentEnabledSetting(
5915                            new ComponentName(packageName, changedClass),
5916                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5917                } catch (Exception e) {
5918                    // As above, probably racing with uninstall.
5919                    return;
5920                }
5921                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5922                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5923                    if (disabledClasses == null) {
5924                        disabledClasses = new ArraySet<>(changedClasses.length);
5925                    }
5926                    disabledClasses.add(changedClass);
5927                }
5928            }
5929        }
5930
5931        if (!packageDisabled && disabledClasses == null) {
5932            // Nothing to do here...
5933            return;
5934        }
5935
5936        // Clean-up disabled activities.
5937        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5938                packageName, disabledClasses, true, false, userId) && mBooted) {
5939            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5940            mStackSupervisor.scheduleIdleLocked();
5941        }
5942
5943        // Clean-up disabled tasks
5944        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5945
5946        // Clean-up disabled services.
5947        mServices.bringDownDisabledPackageServicesLocked(
5948                packageName, disabledClasses, userId, false, killProcess, true);
5949
5950        // Clean-up disabled providers.
5951        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5952        mProviderMap.collectPackageProvidersLocked(
5953                packageName, disabledClasses, true, false, userId, providers);
5954        for (int i = providers.size() - 1; i >= 0; i--) {
5955            removeDyingProviderLocked(null, providers.get(i), true);
5956        }
5957
5958        // Clean-up disabled broadcast receivers.
5959        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5960            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5961                    packageName, disabledClasses, userId, true);
5962        }
5963
5964    }
5965
5966    final boolean clearBroadcastQueueForUserLocked(int userId) {
5967        boolean didSomething = false;
5968        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5969            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5970                    null, null, userId, true);
5971        }
5972        return didSomething;
5973    }
5974
5975    final boolean forceStopPackageLocked(String packageName, int appId,
5976            boolean callerWillRestart, boolean purgeCache, boolean doit,
5977            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5978        int i;
5979
5980        if (userId == UserHandle.USER_ALL && packageName == null) {
5981            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5982        }
5983
5984        if (appId < 0 && packageName != null) {
5985            try {
5986                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5987                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5988            } catch (RemoteException e) {
5989            }
5990        }
5991
5992        if (doit) {
5993            if (packageName != null) {
5994                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5995                        + " user=" + userId + ": " + reason);
5996            } else {
5997                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5998            }
5999
6000            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6001        }
6002
6003        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6004                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6005                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6006
6007        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6008                packageName, null, doit, evenPersistent, userId)) {
6009            if (!doit) {
6010                return true;
6011            }
6012            didSomething = true;
6013        }
6014
6015        if (mServices.bringDownDisabledPackageServicesLocked(
6016                packageName, null, userId, evenPersistent, true, doit)) {
6017            if (!doit) {
6018                return true;
6019            }
6020            didSomething = true;
6021        }
6022
6023        if (packageName == null) {
6024            // Remove all sticky broadcasts from this user.
6025            mStickyBroadcasts.remove(userId);
6026        }
6027
6028        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6029        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6030                userId, providers)) {
6031            if (!doit) {
6032                return true;
6033            }
6034            didSomething = true;
6035        }
6036        for (i = providers.size() - 1; i >= 0; i--) {
6037            removeDyingProviderLocked(null, providers.get(i), true);
6038        }
6039
6040        // Remove transient permissions granted from/to this package/user
6041        removeUriPermissionsForPackageLocked(packageName, userId, false);
6042
6043        if (doit) {
6044            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6045                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6046                        packageName, null, userId, doit);
6047            }
6048        }
6049
6050        if (packageName == null || uninstalling) {
6051            // Remove pending intents.  For now we only do this when force
6052            // stopping users, because we have some problems when doing this
6053            // for packages -- app widgets are not currently cleaned up for
6054            // such packages, so they can be left with bad pending intents.
6055            if (mIntentSenderRecords.size() > 0) {
6056                Iterator<WeakReference<PendingIntentRecord>> it
6057                        = mIntentSenderRecords.values().iterator();
6058                while (it.hasNext()) {
6059                    WeakReference<PendingIntentRecord> wpir = it.next();
6060                    if (wpir == null) {
6061                        it.remove();
6062                        continue;
6063                    }
6064                    PendingIntentRecord pir = wpir.get();
6065                    if (pir == null) {
6066                        it.remove();
6067                        continue;
6068                    }
6069                    if (packageName == null) {
6070                        // Stopping user, remove all objects for the user.
6071                        if (pir.key.userId != userId) {
6072                            // Not the same user, skip it.
6073                            continue;
6074                        }
6075                    } else {
6076                        if (UserHandle.getAppId(pir.uid) != appId) {
6077                            // Different app id, skip it.
6078                            continue;
6079                        }
6080                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6081                            // Different user, skip it.
6082                            continue;
6083                        }
6084                        if (!pir.key.packageName.equals(packageName)) {
6085                            // Different package, skip it.
6086                            continue;
6087                        }
6088                    }
6089                    if (!doit) {
6090                        return true;
6091                    }
6092                    didSomething = true;
6093                    it.remove();
6094                    pir.canceled = true;
6095                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6096                        pir.key.activity.pendingResults.remove(pir.ref);
6097                    }
6098                }
6099            }
6100        }
6101
6102        if (doit) {
6103            if (purgeCache && packageName != null) {
6104                AttributeCache ac = AttributeCache.instance();
6105                if (ac != null) {
6106                    ac.removePackage(packageName);
6107                }
6108            }
6109            if (mBooted) {
6110                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6111                mStackSupervisor.scheduleIdleLocked();
6112            }
6113        }
6114
6115        return didSomething;
6116    }
6117
6118    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6119        ProcessRecord old = mProcessNames.remove(name, uid);
6120        if (old != null) {
6121            old.uidRecord.numProcs--;
6122            if (old.uidRecord.numProcs == 0) {
6123                // No more processes using this uid, tell clients it is gone.
6124                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6125                        "No more processes in " + old.uidRecord);
6126                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6127                mActiveUids.remove(uid);
6128                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6129            }
6130            old.uidRecord = null;
6131        }
6132        mIsolatedProcesses.remove(uid);
6133        return old;
6134    }
6135
6136    private final void addProcessNameLocked(ProcessRecord proc) {
6137        // We shouldn't already have a process under this name, but just in case we
6138        // need to clean up whatever may be there now.
6139        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6140        if (old == proc && proc.persistent) {
6141            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6142            Slog.w(TAG, "Re-adding persistent process " + proc);
6143        } else if (old != null) {
6144            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6145        }
6146        UidRecord uidRec = mActiveUids.get(proc.uid);
6147        if (uidRec == null) {
6148            uidRec = new UidRecord(proc.uid);
6149            // This is the first appearance of the uid, report it now!
6150            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6151                    "Creating new process uid: " + uidRec);
6152            mActiveUids.put(proc.uid, uidRec);
6153            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6154            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6155        }
6156        proc.uidRecord = uidRec;
6157        uidRec.numProcs++;
6158        mProcessNames.put(proc.processName, proc.uid, proc);
6159        if (proc.isolated) {
6160            mIsolatedProcesses.put(proc.uid, proc);
6161        }
6162    }
6163
6164    boolean removeProcessLocked(ProcessRecord app,
6165            boolean callerWillRestart, boolean allowRestart, String reason) {
6166        final String name = app.processName;
6167        final int uid = app.uid;
6168        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6169            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6170
6171        removeProcessNameLocked(name, uid);
6172        if (mHeavyWeightProcess == app) {
6173            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6174                    mHeavyWeightProcess.userId, 0));
6175            mHeavyWeightProcess = null;
6176        }
6177        boolean needRestart = false;
6178        if (app.pid > 0 && app.pid != MY_PID) {
6179            int pid = app.pid;
6180            synchronized (mPidsSelfLocked) {
6181                mPidsSelfLocked.remove(pid);
6182                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6183            }
6184            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6185            if (app.isolated) {
6186                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6187            }
6188            boolean willRestart = false;
6189            if (app.persistent && !app.isolated) {
6190                if (!callerWillRestart) {
6191                    willRestart = true;
6192                } else {
6193                    needRestart = true;
6194                }
6195            }
6196            app.kill(reason, true);
6197            handleAppDiedLocked(app, willRestart, allowRestart);
6198            if (willRestart) {
6199                removeLruProcessLocked(app);
6200                addAppLocked(app.info, false, null /* ABI override */);
6201            }
6202        } else {
6203            mRemovedProcesses.add(app);
6204        }
6205
6206        return needRestart;
6207    }
6208
6209    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6210        cleanupAppInLaunchingProvidersLocked(app, true);
6211        removeProcessLocked(app, false, true, "timeout publishing content providers");
6212    }
6213
6214    private final void processStartTimedOutLocked(ProcessRecord app) {
6215        final int pid = app.pid;
6216        boolean gone = false;
6217        synchronized (mPidsSelfLocked) {
6218            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6219            if (knownApp != null && knownApp.thread == null) {
6220                mPidsSelfLocked.remove(pid);
6221                gone = true;
6222            }
6223        }
6224
6225        if (gone) {
6226            Slog.w(TAG, "Process " + app + " failed to attach");
6227            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6228                    pid, app.uid, app.processName);
6229            removeProcessNameLocked(app.processName, app.uid);
6230            if (mHeavyWeightProcess == app) {
6231                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6232                        mHeavyWeightProcess.userId, 0));
6233                mHeavyWeightProcess = null;
6234            }
6235            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6236            if (app.isolated) {
6237                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6238            }
6239            // Take care of any launching providers waiting for this process.
6240            cleanupAppInLaunchingProvidersLocked(app, true);
6241            // Take care of any services that are waiting for the process.
6242            mServices.processStartTimedOutLocked(app);
6243            app.kill("start timeout", true);
6244            removeLruProcessLocked(app);
6245            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6246                Slog.w(TAG, "Unattached app died before backup, skipping");
6247                try {
6248                    IBackupManager bm = IBackupManager.Stub.asInterface(
6249                            ServiceManager.getService(Context.BACKUP_SERVICE));
6250                    bm.agentDisconnected(app.info.packageName);
6251                } catch (RemoteException e) {
6252                    // Can't happen; the backup manager is local
6253                }
6254            }
6255            if (isPendingBroadcastProcessLocked(pid)) {
6256                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6257                skipPendingBroadcastLocked(pid);
6258            }
6259        } else {
6260            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6261        }
6262    }
6263
6264    private final boolean attachApplicationLocked(IApplicationThread thread,
6265            int pid) {
6266
6267        // Find the application record that is being attached...  either via
6268        // the pid if we are running in multiple processes, or just pull the
6269        // next app record if we are emulating process with anonymous threads.
6270        ProcessRecord app;
6271        if (pid != MY_PID && pid >= 0) {
6272            synchronized (mPidsSelfLocked) {
6273                app = mPidsSelfLocked.get(pid);
6274            }
6275        } else {
6276            app = null;
6277        }
6278
6279        if (app == null) {
6280            Slog.w(TAG, "No pending application record for pid " + pid
6281                    + " (IApplicationThread " + thread + "); dropping process");
6282            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6283            if (pid > 0 && pid != MY_PID) {
6284                Process.killProcessQuiet(pid);
6285                //TODO: killProcessGroup(app.info.uid, pid);
6286            } else {
6287                try {
6288                    thread.scheduleExit();
6289                } catch (Exception e) {
6290                    // Ignore exceptions.
6291                }
6292            }
6293            return false;
6294        }
6295
6296        // If this application record is still attached to a previous
6297        // process, clean it up now.
6298        if (app.thread != null) {
6299            handleAppDiedLocked(app, true, true);
6300        }
6301
6302        // Tell the process all about itself.
6303
6304        if (DEBUG_ALL) Slog.v(
6305                TAG, "Binding process pid " + pid + " to record " + app);
6306
6307        final String processName = app.processName;
6308        try {
6309            AppDeathRecipient adr = new AppDeathRecipient(
6310                    app, pid, thread);
6311            thread.asBinder().linkToDeath(adr, 0);
6312            app.deathRecipient = adr;
6313        } catch (RemoteException e) {
6314            app.resetPackageList(mProcessStats);
6315            startProcessLocked(app, "link fail", processName);
6316            return false;
6317        }
6318
6319        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6320
6321        app.makeActive(thread, mProcessStats);
6322        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6323        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6324        app.forcingToForeground = null;
6325        updateProcessForegroundLocked(app, false, false);
6326        app.hasShownUi = false;
6327        app.debugging = false;
6328        app.cached = false;
6329        app.killedByAm = false;
6330
6331        // We carefully use the same state that PackageManager uses for
6332        // filtering, since we use this flag to decide if we need to install
6333        // providers when user is unlocked later
6334        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6335
6336        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6337
6338        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6339        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6340
6341        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6342            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6343            msg.obj = app;
6344            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6345        }
6346
6347        if (!normalMode) {
6348            Slog.i(TAG, "Launching preboot mode app: " + app);
6349        }
6350
6351        if (DEBUG_ALL) Slog.v(
6352            TAG, "New app record " + app
6353            + " thread=" + thread.asBinder() + " pid=" + pid);
6354        try {
6355            int testMode = IApplicationThread.DEBUG_OFF;
6356            if (mDebugApp != null && mDebugApp.equals(processName)) {
6357                testMode = mWaitForDebugger
6358                    ? IApplicationThread.DEBUG_WAIT
6359                    : IApplicationThread.DEBUG_ON;
6360                app.debugging = true;
6361                if (mDebugTransient) {
6362                    mDebugApp = mOrigDebugApp;
6363                    mWaitForDebugger = mOrigWaitForDebugger;
6364                }
6365            }
6366            String profileFile = app.instrumentationProfileFile;
6367            ParcelFileDescriptor profileFd = null;
6368            int samplingInterval = 0;
6369            boolean profileAutoStop = false;
6370            if (mProfileApp != null && mProfileApp.equals(processName)) {
6371                mProfileProc = app;
6372                profileFile = mProfileFile;
6373                profileFd = mProfileFd;
6374                samplingInterval = mSamplingInterval;
6375                profileAutoStop = mAutoStopProfiler;
6376            }
6377            boolean enableTrackAllocation = false;
6378            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6379                enableTrackAllocation = true;
6380                mTrackAllocationApp = null;
6381            }
6382
6383            // If the app is being launched for restore or full backup, set it up specially
6384            boolean isRestrictedBackupMode = false;
6385            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6386                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6387                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6388                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6389                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6390            }
6391
6392            if (app.instrumentationClass != null) {
6393                notifyPackageUse(app.instrumentationClass.getPackageName(),
6394                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6395            }
6396            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6397                    + processName + " with config " + mConfiguration);
6398            ApplicationInfo appInfo = app.instrumentationInfo != null
6399                    ? app.instrumentationInfo : app.info;
6400            app.compat = compatibilityInfoForPackageLocked(appInfo);
6401            if (profileFd != null) {
6402                profileFd = profileFd.dup();
6403            }
6404            ProfilerInfo profilerInfo = profileFile == null ? null
6405                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6406            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6407                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6408                    app.instrumentationUiAutomationConnection, testMode,
6409                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6410                    isRestrictedBackupMode || !normalMode, app.persistent,
6411                    new Configuration(mConfiguration), app.compat,
6412                    getCommonServicesLocked(app.isolated),
6413                    mCoreSettingsObserver.getCoreSettingsLocked());
6414            updateLruProcessLocked(app, false, null);
6415            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6416        } catch (Exception e) {
6417            // todo: Yikes!  What should we do?  For now we will try to
6418            // start another process, but that could easily get us in
6419            // an infinite loop of restarting processes...
6420            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6421
6422            app.resetPackageList(mProcessStats);
6423            app.unlinkDeathRecipient();
6424            startProcessLocked(app, "bind fail", processName);
6425            return false;
6426        }
6427
6428        // Remove this record from the list of starting applications.
6429        mPersistentStartingProcesses.remove(app);
6430        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6431                "Attach application locked removing on hold: " + app);
6432        mProcessesOnHold.remove(app);
6433
6434        boolean badApp = false;
6435        boolean didSomething = false;
6436
6437        // See if the top visible activity is waiting to run in this process...
6438        if (normalMode) {
6439            try {
6440                if (mStackSupervisor.attachApplicationLocked(app)) {
6441                    didSomething = true;
6442                }
6443            } catch (Exception e) {
6444                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6445                badApp = true;
6446            }
6447        }
6448
6449        // Find any services that should be running in this process...
6450        if (!badApp) {
6451            try {
6452                didSomething |= mServices.attachApplicationLocked(app, processName);
6453            } catch (Exception e) {
6454                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6455                badApp = true;
6456            }
6457        }
6458
6459        // Check if a next-broadcast receiver is in this process...
6460        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6461            try {
6462                didSomething |= sendPendingBroadcastsLocked(app);
6463            } catch (Exception e) {
6464                // If the app died trying to launch the receiver we declare it 'bad'
6465                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6466                badApp = true;
6467            }
6468        }
6469
6470        // Check whether the next backup agent is in this process...
6471        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6472            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6473                    "New app is backup target, launching agent for " + app);
6474            notifyPackageUse(mBackupTarget.appInfo.packageName,
6475                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6476            try {
6477                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6478                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6479                        mBackupTarget.backupMode);
6480            } catch (Exception e) {
6481                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6482                badApp = true;
6483            }
6484        }
6485
6486        if (badApp) {
6487            app.kill("error during init", true);
6488            handleAppDiedLocked(app, false, true);
6489            return false;
6490        }
6491
6492        if (!didSomething) {
6493            updateOomAdjLocked();
6494        }
6495
6496        return true;
6497    }
6498
6499    @Override
6500    public final void attachApplication(IApplicationThread thread) {
6501        synchronized (this) {
6502            int callingPid = Binder.getCallingPid();
6503            final long origId = Binder.clearCallingIdentity();
6504            attachApplicationLocked(thread, callingPid);
6505            Binder.restoreCallingIdentity(origId);
6506        }
6507    }
6508
6509    @Override
6510    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6511        final long origId = Binder.clearCallingIdentity();
6512        synchronized (this) {
6513            ActivityStack stack = ActivityRecord.getStackLocked(token);
6514            if (stack != null) {
6515                ActivityRecord r =
6516                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6517                if (stopProfiling) {
6518                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6519                        try {
6520                            mProfileFd.close();
6521                        } catch (IOException e) {
6522                        }
6523                        clearProfilerLocked();
6524                    }
6525                }
6526            }
6527        }
6528        Binder.restoreCallingIdentity(origId);
6529    }
6530
6531    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6532        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6533                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6534    }
6535
6536    void enableScreenAfterBoot() {
6537        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6538                SystemClock.uptimeMillis());
6539        mWindowManager.enableScreenAfterBoot();
6540
6541        synchronized (this) {
6542            updateEventDispatchingLocked();
6543        }
6544    }
6545
6546    @Override
6547    public void showBootMessage(final CharSequence msg, final boolean always) {
6548        if (Binder.getCallingUid() != Process.myUid()) {
6549            // These days only the core system can call this, so apps can't get in
6550            // the way of what we show about running them.
6551        }
6552        mWindowManager.showBootMessage(msg, always);
6553    }
6554
6555    @Override
6556    public void keyguardWaitingForActivityDrawn() {
6557        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6558        final long token = Binder.clearCallingIdentity();
6559        try {
6560            synchronized (this) {
6561                if (DEBUG_LOCKSCREEN) logLockScreen("");
6562                mWindowManager.keyguardWaitingForActivityDrawn();
6563                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6564                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6565                    updateSleepIfNeededLocked();
6566                }
6567            }
6568        } finally {
6569            Binder.restoreCallingIdentity(token);
6570        }
6571    }
6572
6573    @Override
6574    public void keyguardGoingAway(int flags) {
6575        enforceNotIsolatedCaller("keyguardGoingAway");
6576        final long token = Binder.clearCallingIdentity();
6577        try {
6578            synchronized (this) {
6579                if (DEBUG_LOCKSCREEN) logLockScreen("");
6580                mWindowManager.keyguardGoingAway(flags);
6581                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6582                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6583                    updateSleepIfNeededLocked();
6584
6585                    // Some stack visibility might change (e.g. docked stack)
6586                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6587                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6588                }
6589            }
6590        } finally {
6591            Binder.restoreCallingIdentity(token);
6592        }
6593    }
6594
6595    final void finishBooting() {
6596        synchronized (this) {
6597            if (!mBootAnimationComplete) {
6598                mCallFinishBooting = true;
6599                return;
6600            }
6601            mCallFinishBooting = false;
6602        }
6603
6604        ArraySet<String> completedIsas = new ArraySet<String>();
6605        for (String abi : Build.SUPPORTED_ABIS) {
6606            Process.establishZygoteConnectionForAbi(abi);
6607            final String instructionSet = VMRuntime.getInstructionSet(abi);
6608            if (!completedIsas.contains(instructionSet)) {
6609                try {
6610                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6611                } catch (InstallerException e) {
6612                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6613                            e.getMessage() +")");
6614                }
6615                completedIsas.add(instructionSet);
6616            }
6617        }
6618
6619        IntentFilter pkgFilter = new IntentFilter();
6620        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6621        pkgFilter.addDataScheme("package");
6622        mContext.registerReceiver(new BroadcastReceiver() {
6623            @Override
6624            public void onReceive(Context context, Intent intent) {
6625                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6626                if (pkgs != null) {
6627                    for (String pkg : pkgs) {
6628                        synchronized (ActivityManagerService.this) {
6629                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6630                                    0, "query restart")) {
6631                                setResultCode(Activity.RESULT_OK);
6632                                return;
6633                            }
6634                        }
6635                    }
6636                }
6637            }
6638        }, pkgFilter);
6639
6640        IntentFilter dumpheapFilter = new IntentFilter();
6641        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6642        mContext.registerReceiver(new BroadcastReceiver() {
6643            @Override
6644            public void onReceive(Context context, Intent intent) {
6645                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6646                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6647                } else {
6648                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6649                }
6650            }
6651        }, dumpheapFilter);
6652
6653        // Let system services know.
6654        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6655
6656        synchronized (this) {
6657            // Ensure that any processes we had put on hold are now started
6658            // up.
6659            final int NP = mProcessesOnHold.size();
6660            if (NP > 0) {
6661                ArrayList<ProcessRecord> procs =
6662                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6663                for (int ip=0; ip<NP; ip++) {
6664                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6665                            + procs.get(ip));
6666                    startProcessLocked(procs.get(ip), "on-hold", null);
6667                }
6668            }
6669
6670            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6671                // Start looking for apps that are abusing wake locks.
6672                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6673                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6674                // Tell anyone interested that we are done booting!
6675                SystemProperties.set("sys.boot_completed", "1");
6676
6677                // And trigger dev.bootcomplete if we are not showing encryption progress
6678                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6679                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6680                    SystemProperties.set("dev.bootcomplete", "1");
6681                }
6682                mUserController.sendBootCompletedLocked(
6683                        new IIntentReceiver.Stub() {
6684                            @Override
6685                            public void performReceive(Intent intent, int resultCode,
6686                                    String data, Bundle extras, boolean ordered,
6687                                    boolean sticky, int sendingUser) {
6688                                synchronized (ActivityManagerService.this) {
6689                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6690                                            true, false);
6691                                }
6692                            }
6693                        });
6694                scheduleStartProfilesLocked();
6695            }
6696        }
6697    }
6698
6699    @Override
6700    public void bootAnimationComplete() {
6701        final boolean callFinishBooting;
6702        synchronized (this) {
6703            callFinishBooting = mCallFinishBooting;
6704            mBootAnimationComplete = true;
6705        }
6706        if (callFinishBooting) {
6707            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6708            finishBooting();
6709            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6710        }
6711    }
6712
6713    final void ensureBootCompleted() {
6714        boolean booting;
6715        boolean enableScreen;
6716        synchronized (this) {
6717            booting = mBooting;
6718            mBooting = false;
6719            enableScreen = !mBooted;
6720            mBooted = true;
6721        }
6722
6723        if (booting) {
6724            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6725            finishBooting();
6726            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6727        }
6728
6729        if (enableScreen) {
6730            enableScreenAfterBoot();
6731        }
6732    }
6733
6734    @Override
6735    public final void activityResumed(IBinder token) {
6736        final long origId = Binder.clearCallingIdentity();
6737        synchronized(this) {
6738            ActivityStack stack = ActivityRecord.getStackLocked(token);
6739            if (stack != null) {
6740                stack.activityResumedLocked(token);
6741            }
6742        }
6743        Binder.restoreCallingIdentity(origId);
6744    }
6745
6746    @Override
6747    public final void activityPaused(IBinder token) {
6748        final long origId = Binder.clearCallingIdentity();
6749        synchronized(this) {
6750            ActivityStack stack = ActivityRecord.getStackLocked(token);
6751            if (stack != null) {
6752                stack.activityPausedLocked(token, false);
6753            }
6754        }
6755        Binder.restoreCallingIdentity(origId);
6756    }
6757
6758    @Override
6759    public final void activityStopped(IBinder token, Bundle icicle,
6760            PersistableBundle persistentState, CharSequence description) {
6761        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6762
6763        // Refuse possible leaked file descriptors
6764        if (icicle != null && icicle.hasFileDescriptors()) {
6765            throw new IllegalArgumentException("File descriptors passed in Bundle");
6766        }
6767
6768        final long origId = Binder.clearCallingIdentity();
6769
6770        synchronized (this) {
6771            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6772            if (r != null) {
6773                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6774            }
6775        }
6776
6777        trimApplications();
6778
6779        Binder.restoreCallingIdentity(origId);
6780    }
6781
6782    @Override
6783    public final void activityDestroyed(IBinder token) {
6784        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6785        synchronized (this) {
6786            ActivityStack stack = ActivityRecord.getStackLocked(token);
6787            if (stack != null) {
6788                stack.activityDestroyedLocked(token, "activityDestroyed");
6789            }
6790        }
6791    }
6792
6793    @Override
6794    public final void activityRelaunched(IBinder token) {
6795        final long origId = Binder.clearCallingIdentity();
6796        synchronized (this) {
6797            mStackSupervisor.activityRelaunchedLocked(token);
6798        }
6799        Binder.restoreCallingIdentity(origId);
6800    }
6801
6802    @Override
6803    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6804            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6805        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6806                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6807        synchronized (this) {
6808            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6809            if (record == null) {
6810                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6811                        + "found for: " + token);
6812            }
6813            record.setSizeConfigurations(horizontalSizeConfiguration,
6814                    verticalSizeConfigurations, smallestSizeConfigurations);
6815        }
6816    }
6817
6818    @Override
6819    public final void backgroundResourcesReleased(IBinder token) {
6820        final long origId = Binder.clearCallingIdentity();
6821        try {
6822            synchronized (this) {
6823                ActivityStack stack = ActivityRecord.getStackLocked(token);
6824                if (stack != null) {
6825                    stack.backgroundResourcesReleased();
6826                }
6827            }
6828        } finally {
6829            Binder.restoreCallingIdentity(origId);
6830        }
6831    }
6832
6833    @Override
6834    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6835        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6836    }
6837
6838    @Override
6839    public final void notifyEnterAnimationComplete(IBinder token) {
6840        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6841    }
6842
6843    @Override
6844    public String getCallingPackage(IBinder token) {
6845        synchronized (this) {
6846            ActivityRecord r = getCallingRecordLocked(token);
6847            return r != null ? r.info.packageName : null;
6848        }
6849    }
6850
6851    @Override
6852    public ComponentName getCallingActivity(IBinder token) {
6853        synchronized (this) {
6854            ActivityRecord r = getCallingRecordLocked(token);
6855            return r != null ? r.intent.getComponent() : null;
6856        }
6857    }
6858
6859    private ActivityRecord getCallingRecordLocked(IBinder token) {
6860        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6861        if (r == null) {
6862            return null;
6863        }
6864        return r.resultTo;
6865    }
6866
6867    @Override
6868    public ComponentName getActivityClassForToken(IBinder token) {
6869        synchronized(this) {
6870            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6871            if (r == null) {
6872                return null;
6873            }
6874            return r.intent.getComponent();
6875        }
6876    }
6877
6878    @Override
6879    public String getPackageForToken(IBinder token) {
6880        synchronized(this) {
6881            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6882            if (r == null) {
6883                return null;
6884            }
6885            return r.packageName;
6886        }
6887    }
6888
6889    @Override
6890    public boolean isRootVoiceInteraction(IBinder token) {
6891        synchronized(this) {
6892            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6893            if (r == null) {
6894                return false;
6895            }
6896            return r.rootVoiceInteraction;
6897        }
6898    }
6899
6900    @Override
6901    public IIntentSender getIntentSender(int type,
6902            String packageName, IBinder token, String resultWho,
6903            int requestCode, Intent[] intents, String[] resolvedTypes,
6904            int flags, Bundle bOptions, int userId) {
6905        enforceNotIsolatedCaller("getIntentSender");
6906        // Refuse possible leaked file descriptors
6907        if (intents != null) {
6908            if (intents.length < 1) {
6909                throw new IllegalArgumentException("Intents array length must be >= 1");
6910            }
6911            for (int i=0; i<intents.length; i++) {
6912                Intent intent = intents[i];
6913                if (intent != null) {
6914                    if (intent.hasFileDescriptors()) {
6915                        throw new IllegalArgumentException("File descriptors passed in Intent");
6916                    }
6917                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6918                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6919                        throw new IllegalArgumentException(
6920                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6921                    }
6922                    intents[i] = new Intent(intent);
6923                }
6924            }
6925            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6926                throw new IllegalArgumentException(
6927                        "Intent array length does not match resolvedTypes length");
6928            }
6929        }
6930        if (bOptions != null) {
6931            if (bOptions.hasFileDescriptors()) {
6932                throw new IllegalArgumentException("File descriptors passed in options");
6933            }
6934        }
6935
6936        synchronized(this) {
6937            int callingUid = Binder.getCallingUid();
6938            int origUserId = userId;
6939            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6940                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6941                    ALLOW_NON_FULL, "getIntentSender", null);
6942            if (origUserId == UserHandle.USER_CURRENT) {
6943                // We don't want to evaluate this until the pending intent is
6944                // actually executed.  However, we do want to always do the
6945                // security checking for it above.
6946                userId = UserHandle.USER_CURRENT;
6947            }
6948            try {
6949                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6950                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6951                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6952                    if (!UserHandle.isSameApp(callingUid, uid)) {
6953                        String msg = "Permission Denial: getIntentSender() from pid="
6954                            + Binder.getCallingPid()
6955                            + ", uid=" + Binder.getCallingUid()
6956                            + ", (need uid=" + uid + ")"
6957                            + " is not allowed to send as package " + packageName;
6958                        Slog.w(TAG, msg);
6959                        throw new SecurityException(msg);
6960                    }
6961                }
6962
6963                return getIntentSenderLocked(type, packageName, callingUid, userId,
6964                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6965
6966            } catch (RemoteException e) {
6967                throw new SecurityException(e);
6968            }
6969        }
6970    }
6971
6972    IIntentSender getIntentSenderLocked(int type, String packageName,
6973            int callingUid, int userId, IBinder token, String resultWho,
6974            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6975            Bundle bOptions) {
6976        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6977        ActivityRecord activity = null;
6978        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6979            activity = ActivityRecord.isInStackLocked(token);
6980            if (activity == null) {
6981                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6982                return null;
6983            }
6984            if (activity.finishing) {
6985                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6986                return null;
6987            }
6988        }
6989
6990        // We're going to be splicing together extras before sending, so we're
6991        // okay poking into any contained extras.
6992        if (intents != null) {
6993            for (int i = 0; i < intents.length; i++) {
6994                intents[i].setDefusable(true);
6995            }
6996        }
6997        Bundle.setDefusable(bOptions, true);
6998
6999        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7000        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7001        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7002        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7003                |PendingIntent.FLAG_UPDATE_CURRENT);
7004
7005        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7006                type, packageName, activity, resultWho,
7007                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7008        WeakReference<PendingIntentRecord> ref;
7009        ref = mIntentSenderRecords.get(key);
7010        PendingIntentRecord rec = ref != null ? ref.get() : null;
7011        if (rec != null) {
7012            if (!cancelCurrent) {
7013                if (updateCurrent) {
7014                    if (rec.key.requestIntent != null) {
7015                        rec.key.requestIntent.replaceExtras(intents != null ?
7016                                intents[intents.length - 1] : null);
7017                    }
7018                    if (intents != null) {
7019                        intents[intents.length-1] = rec.key.requestIntent;
7020                        rec.key.allIntents = intents;
7021                        rec.key.allResolvedTypes = resolvedTypes;
7022                    } else {
7023                        rec.key.allIntents = null;
7024                        rec.key.allResolvedTypes = null;
7025                    }
7026                }
7027                return rec;
7028            }
7029            rec.canceled = true;
7030            mIntentSenderRecords.remove(key);
7031        }
7032        if (noCreate) {
7033            return rec;
7034        }
7035        rec = new PendingIntentRecord(this, key, callingUid);
7036        mIntentSenderRecords.put(key, rec.ref);
7037        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7038            if (activity.pendingResults == null) {
7039                activity.pendingResults
7040                        = new HashSet<WeakReference<PendingIntentRecord>>();
7041            }
7042            activity.pendingResults.add(rec.ref);
7043        }
7044        return rec;
7045    }
7046
7047    @Override
7048    public void cancelIntentSender(IIntentSender sender) {
7049        if (!(sender instanceof PendingIntentRecord)) {
7050            return;
7051        }
7052        synchronized(this) {
7053            PendingIntentRecord rec = (PendingIntentRecord)sender;
7054            try {
7055                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7056                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7057                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7058                    String msg = "Permission Denial: cancelIntentSender() from pid="
7059                        + Binder.getCallingPid()
7060                        + ", uid=" + Binder.getCallingUid()
7061                        + " is not allowed to cancel packges "
7062                        + rec.key.packageName;
7063                    Slog.w(TAG, msg);
7064                    throw new SecurityException(msg);
7065                }
7066            } catch (RemoteException e) {
7067                throw new SecurityException(e);
7068            }
7069            cancelIntentSenderLocked(rec, true);
7070        }
7071    }
7072
7073    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7074        rec.canceled = true;
7075        mIntentSenderRecords.remove(rec.key);
7076        if (cleanActivity && rec.key.activity != null) {
7077            rec.key.activity.pendingResults.remove(rec.ref);
7078        }
7079    }
7080
7081    @Override
7082    public String getPackageForIntentSender(IIntentSender pendingResult) {
7083        if (!(pendingResult instanceof PendingIntentRecord)) {
7084            return null;
7085        }
7086        try {
7087            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7088            return res.key.packageName;
7089        } catch (ClassCastException e) {
7090        }
7091        return null;
7092    }
7093
7094    @Override
7095    public int getUidForIntentSender(IIntentSender sender) {
7096        if (sender instanceof PendingIntentRecord) {
7097            try {
7098                PendingIntentRecord res = (PendingIntentRecord)sender;
7099                return res.uid;
7100            } catch (ClassCastException e) {
7101            }
7102        }
7103        return -1;
7104    }
7105
7106    @Override
7107    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7108        if (!(pendingResult instanceof PendingIntentRecord)) {
7109            return false;
7110        }
7111        try {
7112            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7113            if (res.key.allIntents == null) {
7114                return false;
7115            }
7116            for (int i=0; i<res.key.allIntents.length; i++) {
7117                Intent intent = res.key.allIntents[i];
7118                if (intent.getPackage() != null && intent.getComponent() != null) {
7119                    return false;
7120                }
7121            }
7122            return true;
7123        } catch (ClassCastException e) {
7124        }
7125        return false;
7126    }
7127
7128    @Override
7129    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7130        if (!(pendingResult instanceof PendingIntentRecord)) {
7131            return false;
7132        }
7133        try {
7134            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7135            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7136                return true;
7137            }
7138            return false;
7139        } catch (ClassCastException e) {
7140        }
7141        return false;
7142    }
7143
7144    @Override
7145    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7146        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7147                "getIntentForIntentSender()");
7148        if (!(pendingResult instanceof PendingIntentRecord)) {
7149            return null;
7150        }
7151        try {
7152            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7153            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7154        } catch (ClassCastException e) {
7155        }
7156        return null;
7157    }
7158
7159    @Override
7160    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7161        if (!(pendingResult instanceof PendingIntentRecord)) {
7162            return null;
7163        }
7164        try {
7165            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7166            synchronized (this) {
7167                return getTagForIntentSenderLocked(res, prefix);
7168            }
7169        } catch (ClassCastException e) {
7170        }
7171        return null;
7172    }
7173
7174    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7175        final Intent intent = res.key.requestIntent;
7176        if (intent != null) {
7177            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7178                    || res.lastTagPrefix.equals(prefix))) {
7179                return res.lastTag;
7180            }
7181            res.lastTagPrefix = prefix;
7182            final StringBuilder sb = new StringBuilder(128);
7183            if (prefix != null) {
7184                sb.append(prefix);
7185            }
7186            if (intent.getAction() != null) {
7187                sb.append(intent.getAction());
7188            } else if (intent.getComponent() != null) {
7189                intent.getComponent().appendShortString(sb);
7190            } else {
7191                sb.append("?");
7192            }
7193            return res.lastTag = sb.toString();
7194        }
7195        return null;
7196    }
7197
7198    @Override
7199    public void setProcessLimit(int max) {
7200        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7201                "setProcessLimit()");
7202        synchronized (this) {
7203            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7204            mProcessLimitOverride = max;
7205        }
7206        trimApplications();
7207    }
7208
7209    @Override
7210    public int getProcessLimit() {
7211        synchronized (this) {
7212            return mProcessLimitOverride;
7213        }
7214    }
7215
7216    void foregroundTokenDied(ForegroundToken token) {
7217        synchronized (ActivityManagerService.this) {
7218            synchronized (mPidsSelfLocked) {
7219                ForegroundToken cur
7220                    = mForegroundProcesses.get(token.pid);
7221                if (cur != token) {
7222                    return;
7223                }
7224                mForegroundProcesses.remove(token.pid);
7225                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7226                if (pr == null) {
7227                    return;
7228                }
7229                pr.forcingToForeground = null;
7230                updateProcessForegroundLocked(pr, false, false);
7231            }
7232            updateOomAdjLocked();
7233        }
7234    }
7235
7236    @Override
7237    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7238        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7239                "setProcessForeground()");
7240        synchronized(this) {
7241            boolean changed = false;
7242
7243            synchronized (mPidsSelfLocked) {
7244                ProcessRecord pr = mPidsSelfLocked.get(pid);
7245                if (pr == null && isForeground) {
7246                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7247                    return;
7248                }
7249                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7250                if (oldToken != null) {
7251                    oldToken.token.unlinkToDeath(oldToken, 0);
7252                    mForegroundProcesses.remove(pid);
7253                    if (pr != null) {
7254                        pr.forcingToForeground = null;
7255                    }
7256                    changed = true;
7257                }
7258                if (isForeground && token != null) {
7259                    ForegroundToken newToken = new ForegroundToken() {
7260                        @Override
7261                        public void binderDied() {
7262                            foregroundTokenDied(this);
7263                        }
7264                    };
7265                    newToken.pid = pid;
7266                    newToken.token = token;
7267                    try {
7268                        token.linkToDeath(newToken, 0);
7269                        mForegroundProcesses.put(pid, newToken);
7270                        pr.forcingToForeground = token;
7271                        changed = true;
7272                    } catch (RemoteException e) {
7273                        // If the process died while doing this, we will later
7274                        // do the cleanup with the process death link.
7275                    }
7276                }
7277            }
7278
7279            if (changed) {
7280                updateOomAdjLocked();
7281            }
7282        }
7283    }
7284
7285    @Override
7286    public boolean isAppForeground(int uid) throws RemoteException {
7287        synchronized (this) {
7288            UidRecord uidRec = mActiveUids.get(uid);
7289            if (uidRec == null || uidRec.idle) {
7290                return false;
7291            }
7292            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7293        }
7294    }
7295
7296    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7297    // be guarded by permission checking.
7298    int getUidState(int uid) {
7299        synchronized (this) {
7300            UidRecord uidRec = mActiveUids.get(uid);
7301            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7302        }
7303    }
7304
7305    @Override
7306    public boolean isInMultiWindowMode(IBinder token) {
7307        final long origId = Binder.clearCallingIdentity();
7308        try {
7309            synchronized(this) {
7310                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7311                if (r == null) {
7312                    return false;
7313                }
7314                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7315                return !r.task.mFullscreen;
7316            }
7317        } finally {
7318            Binder.restoreCallingIdentity(origId);
7319        }
7320    }
7321
7322    @Override
7323    public boolean isInPictureInPictureMode(IBinder token) {
7324        final long origId = Binder.clearCallingIdentity();
7325        try {
7326            synchronized(this) {
7327                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7328                if (stack == null) {
7329                    return false;
7330                }
7331                return stack.mStackId == PINNED_STACK_ID;
7332            }
7333        } finally {
7334            Binder.restoreCallingIdentity(origId);
7335        }
7336    }
7337
7338    @Override
7339    public void enterPictureInPictureMode(IBinder token) {
7340        final long origId = Binder.clearCallingIdentity();
7341        try {
7342            synchronized(this) {
7343                if (!mSupportsPictureInPicture) {
7344                    throw new IllegalStateException("enterPictureInPictureMode: "
7345                            + "Device doesn't support picture-in-picture mode.");
7346                }
7347
7348                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7349
7350                if (r == null) {
7351                    throw new IllegalStateException("enterPictureInPictureMode: "
7352                            + "Can't find activity for token=" + token);
7353                }
7354
7355                if (!r.supportsPictureInPicture()) {
7356                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7357                            + "Picture-In-Picture not supported for r=" + r);
7358                }
7359
7360                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7361                // current bounds.
7362                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7363                final Rect bounds = (pinnedStack != null)
7364                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7365
7366                mStackSupervisor.moveActivityToPinnedStackLocked(
7367                        r, "enterPictureInPictureMode", bounds);
7368            }
7369        } finally {
7370            Binder.restoreCallingIdentity(origId);
7371        }
7372    }
7373
7374    // =========================================================
7375    // PROCESS INFO
7376    // =========================================================
7377
7378    static class ProcessInfoService extends IProcessInfoService.Stub {
7379        final ActivityManagerService mActivityManagerService;
7380        ProcessInfoService(ActivityManagerService activityManagerService) {
7381            mActivityManagerService = activityManagerService;
7382        }
7383
7384        @Override
7385        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7386            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7387                    /*in*/ pids, /*out*/ states, null);
7388        }
7389
7390        @Override
7391        public void getProcessStatesAndOomScoresFromPids(
7392                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7393            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7394                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7395        }
7396    }
7397
7398    /**
7399     * For each PID in the given input array, write the current process state
7400     * for that process into the states array, or -1 to indicate that no
7401     * process with the given PID exists. If scores array is provided, write
7402     * the oom score for the process into the scores array, with INVALID_ADJ
7403     * indicating the PID doesn't exist.
7404     */
7405    public void getProcessStatesAndOomScoresForPIDs(
7406            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7407        if (scores != null) {
7408            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7409                    "getProcessStatesAndOomScoresForPIDs()");
7410        }
7411
7412        if (pids == null) {
7413            throw new NullPointerException("pids");
7414        } else if (states == null) {
7415            throw new NullPointerException("states");
7416        } else if (pids.length != states.length) {
7417            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7418        } else if (scores != null && pids.length != scores.length) {
7419            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7420        }
7421
7422        synchronized (mPidsSelfLocked) {
7423            for (int i = 0; i < pids.length; i++) {
7424                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7425                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7426                        pr.curProcState;
7427                if (scores != null) {
7428                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7429                }
7430            }
7431        }
7432    }
7433
7434    // =========================================================
7435    // PERMISSIONS
7436    // =========================================================
7437
7438    static class PermissionController extends IPermissionController.Stub {
7439        ActivityManagerService mActivityManagerService;
7440        PermissionController(ActivityManagerService activityManagerService) {
7441            mActivityManagerService = activityManagerService;
7442        }
7443
7444        @Override
7445        public boolean checkPermission(String permission, int pid, int uid) {
7446            return mActivityManagerService.checkPermission(permission, pid,
7447                    uid) == PackageManager.PERMISSION_GRANTED;
7448        }
7449
7450        @Override
7451        public String[] getPackagesForUid(int uid) {
7452            return mActivityManagerService.mContext.getPackageManager()
7453                    .getPackagesForUid(uid);
7454        }
7455
7456        @Override
7457        public boolean isRuntimePermission(String permission) {
7458            try {
7459                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7460                        .getPermissionInfo(permission, 0);
7461                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7462            } catch (NameNotFoundException nnfe) {
7463                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7464            }
7465            return false;
7466        }
7467    }
7468
7469    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7470        @Override
7471        public int checkComponentPermission(String permission, int pid, int uid,
7472                int owningUid, boolean exported) {
7473            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7474                    owningUid, exported);
7475        }
7476
7477        @Override
7478        public Object getAMSLock() {
7479            return ActivityManagerService.this;
7480        }
7481    }
7482
7483    /**
7484     * This can be called with or without the global lock held.
7485     */
7486    int checkComponentPermission(String permission, int pid, int uid,
7487            int owningUid, boolean exported) {
7488        if (pid == MY_PID) {
7489            return PackageManager.PERMISSION_GRANTED;
7490        }
7491        return ActivityManager.checkComponentPermission(permission, uid,
7492                owningUid, exported);
7493    }
7494
7495    /**
7496     * As the only public entry point for permissions checking, this method
7497     * can enforce the semantic that requesting a check on a null global
7498     * permission is automatically denied.  (Internally a null permission
7499     * string is used when calling {@link #checkComponentPermission} in cases
7500     * when only uid-based security is needed.)
7501     *
7502     * This can be called with or without the global lock held.
7503     */
7504    @Override
7505    public int checkPermission(String permission, int pid, int uid) {
7506        if (permission == null) {
7507            return PackageManager.PERMISSION_DENIED;
7508        }
7509        return checkComponentPermission(permission, pid, uid, -1, true);
7510    }
7511
7512    @Override
7513    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7514        if (permission == null) {
7515            return PackageManager.PERMISSION_DENIED;
7516        }
7517
7518        // We might be performing an operation on behalf of an indirect binder
7519        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7520        // client identity accordingly before proceeding.
7521        Identity tlsIdentity = sCallerIdentity.get();
7522        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7523            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7524                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7525            uid = tlsIdentity.uid;
7526            pid = tlsIdentity.pid;
7527        }
7528
7529        return checkComponentPermission(permission, pid, uid, -1, true);
7530    }
7531
7532    /**
7533     * Binder IPC calls go through the public entry point.
7534     * This can be called with or without the global lock held.
7535     */
7536    int checkCallingPermission(String permission) {
7537        return checkPermission(permission,
7538                Binder.getCallingPid(),
7539                UserHandle.getAppId(Binder.getCallingUid()));
7540    }
7541
7542    /**
7543     * This can be called with or without the global lock held.
7544     */
7545    void enforceCallingPermission(String permission, String func) {
7546        if (checkCallingPermission(permission)
7547                == PackageManager.PERMISSION_GRANTED) {
7548            return;
7549        }
7550
7551        String msg = "Permission Denial: " + func + " from pid="
7552                + Binder.getCallingPid()
7553                + ", uid=" + Binder.getCallingUid()
7554                + " requires " + permission;
7555        Slog.w(TAG, msg);
7556        throw new SecurityException(msg);
7557    }
7558
7559    /**
7560     * Determine if UID is holding permissions required to access {@link Uri} in
7561     * the given {@link ProviderInfo}. Final permission checking is always done
7562     * in {@link ContentProvider}.
7563     */
7564    private final boolean checkHoldingPermissionsLocked(
7565            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7566        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7567                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7568        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7569            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7570                    != PERMISSION_GRANTED) {
7571                return false;
7572            }
7573        }
7574        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7575    }
7576
7577    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7578            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7579        if (pi.applicationInfo.uid == uid) {
7580            return true;
7581        } else if (!pi.exported) {
7582            return false;
7583        }
7584
7585        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7586        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7587        try {
7588            // check if target holds top-level <provider> permissions
7589            if (!readMet && pi.readPermission != null && considerUidPermissions
7590                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7591                readMet = true;
7592            }
7593            if (!writeMet && pi.writePermission != null && considerUidPermissions
7594                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7595                writeMet = true;
7596            }
7597
7598            // track if unprotected read/write is allowed; any denied
7599            // <path-permission> below removes this ability
7600            boolean allowDefaultRead = pi.readPermission == null;
7601            boolean allowDefaultWrite = pi.writePermission == null;
7602
7603            // check if target holds any <path-permission> that match uri
7604            final PathPermission[] pps = pi.pathPermissions;
7605            if (pps != null) {
7606                final String path = grantUri.uri.getPath();
7607                int i = pps.length;
7608                while (i > 0 && (!readMet || !writeMet)) {
7609                    i--;
7610                    PathPermission pp = pps[i];
7611                    if (pp.match(path)) {
7612                        if (!readMet) {
7613                            final String pprperm = pp.getReadPermission();
7614                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7615                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7616                                    + ": match=" + pp.match(path)
7617                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7618                            if (pprperm != null) {
7619                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7620                                        == PERMISSION_GRANTED) {
7621                                    readMet = true;
7622                                } else {
7623                                    allowDefaultRead = false;
7624                                }
7625                            }
7626                        }
7627                        if (!writeMet) {
7628                            final String ppwperm = pp.getWritePermission();
7629                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7630                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7631                                    + ": match=" + pp.match(path)
7632                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7633                            if (ppwperm != null) {
7634                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7635                                        == PERMISSION_GRANTED) {
7636                                    writeMet = true;
7637                                } else {
7638                                    allowDefaultWrite = false;
7639                                }
7640                            }
7641                        }
7642                    }
7643                }
7644            }
7645
7646            // grant unprotected <provider> read/write, if not blocked by
7647            // <path-permission> above
7648            if (allowDefaultRead) readMet = true;
7649            if (allowDefaultWrite) writeMet = true;
7650
7651        } catch (RemoteException e) {
7652            return false;
7653        }
7654
7655        return readMet && writeMet;
7656    }
7657
7658    public int getAppStartMode(int uid, String packageName) {
7659        synchronized (this) {
7660            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7661        }
7662    }
7663
7664    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7665            boolean allowWhenForeground) {
7666        UidRecord uidRec = mActiveUids.get(uid);
7667        if (!mLenientBackgroundCheck) {
7668            if (!allowWhenForeground || uidRec == null
7669                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7670                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7671                        packageName) != AppOpsManager.MODE_ALLOWED) {
7672                    return ActivityManager.APP_START_MODE_DELAYED;
7673                }
7674            }
7675
7676        } else if (uidRec == null || uidRec.idle) {
7677            if (callingPid >= 0) {
7678                ProcessRecord proc;
7679                synchronized (mPidsSelfLocked) {
7680                    proc = mPidsSelfLocked.get(callingPid);
7681                }
7682                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7683                    // Whoever is instigating this is in the foreground, so we will allow it
7684                    // to go through.
7685                    return ActivityManager.APP_START_MODE_NORMAL;
7686                }
7687            }
7688            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7689                    != AppOpsManager.MODE_ALLOWED) {
7690                return ActivityManager.APP_START_MODE_DELAYED;
7691            }
7692        }
7693        return ActivityManager.APP_START_MODE_NORMAL;
7694    }
7695
7696    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7697        ProviderInfo pi = null;
7698        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7699        if (cpr != null) {
7700            pi = cpr.info;
7701        } else {
7702            try {
7703                pi = AppGlobals.getPackageManager().resolveContentProvider(
7704                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7705            } catch (RemoteException ex) {
7706            }
7707        }
7708        return pi;
7709    }
7710
7711    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7712        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7713        if (targetUris != null) {
7714            return targetUris.get(grantUri);
7715        }
7716        return null;
7717    }
7718
7719    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7720            String targetPkg, int targetUid, GrantUri grantUri) {
7721        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7722        if (targetUris == null) {
7723            targetUris = Maps.newArrayMap();
7724            mGrantedUriPermissions.put(targetUid, targetUris);
7725        }
7726
7727        UriPermission perm = targetUris.get(grantUri);
7728        if (perm == null) {
7729            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7730            targetUris.put(grantUri, perm);
7731        }
7732
7733        return perm;
7734    }
7735
7736    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7737            final int modeFlags) {
7738        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7739        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7740                : UriPermission.STRENGTH_OWNED;
7741
7742        // Root gets to do everything.
7743        if (uid == 0) {
7744            return true;
7745        }
7746
7747        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7748        if (perms == null) return false;
7749
7750        // First look for exact match
7751        final UriPermission exactPerm = perms.get(grantUri);
7752        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7753            return true;
7754        }
7755
7756        // No exact match, look for prefixes
7757        final int N = perms.size();
7758        for (int i = 0; i < N; i++) {
7759            final UriPermission perm = perms.valueAt(i);
7760            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7761                    && perm.getStrength(modeFlags) >= minStrength) {
7762                return true;
7763            }
7764        }
7765
7766        return false;
7767    }
7768
7769    /**
7770     * @param uri This uri must NOT contain an embedded userId.
7771     * @param userId The userId in which the uri is to be resolved.
7772     */
7773    @Override
7774    public int checkUriPermission(Uri uri, int pid, int uid,
7775            final int modeFlags, int userId, IBinder callerToken) {
7776        enforceNotIsolatedCaller("checkUriPermission");
7777
7778        // Another redirected-binder-call permissions check as in
7779        // {@link checkPermissionWithToken}.
7780        Identity tlsIdentity = sCallerIdentity.get();
7781        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7782            uid = tlsIdentity.uid;
7783            pid = tlsIdentity.pid;
7784        }
7785
7786        // Our own process gets to do everything.
7787        if (pid == MY_PID) {
7788            return PackageManager.PERMISSION_GRANTED;
7789        }
7790        synchronized (this) {
7791            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7792                    ? PackageManager.PERMISSION_GRANTED
7793                    : PackageManager.PERMISSION_DENIED;
7794        }
7795    }
7796
7797    /**
7798     * Check if the targetPkg can be granted permission to access uri by
7799     * the callingUid using the given modeFlags.  Throws a security exception
7800     * if callingUid is not allowed to do this.  Returns the uid of the target
7801     * if the URI permission grant should be performed; returns -1 if it is not
7802     * needed (for example targetPkg already has permission to access the URI).
7803     * If you already know the uid of the target, you can supply it in
7804     * lastTargetUid else set that to -1.
7805     */
7806    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7807            final int modeFlags, int lastTargetUid) {
7808        if (!Intent.isAccessUriMode(modeFlags)) {
7809            return -1;
7810        }
7811
7812        if (targetPkg != null) {
7813            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7814                    "Checking grant " + targetPkg + " permission to " + grantUri);
7815        }
7816
7817        final IPackageManager pm = AppGlobals.getPackageManager();
7818
7819        // If this is not a content: uri, we can't do anything with it.
7820        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7821            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7822                    "Can't grant URI permission for non-content URI: " + grantUri);
7823            return -1;
7824        }
7825
7826        final String authority = grantUri.uri.getAuthority();
7827        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7828        if (pi == null) {
7829            Slog.w(TAG, "No content provider found for permission check: " +
7830                    grantUri.uri.toSafeString());
7831            return -1;
7832        }
7833
7834        int targetUid = lastTargetUid;
7835        if (targetUid < 0 && targetPkg != null) {
7836            try {
7837                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7838                        UserHandle.getUserId(callingUid));
7839                if (targetUid < 0) {
7840                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7841                            "Can't grant URI permission no uid for: " + targetPkg);
7842                    return -1;
7843                }
7844            } catch (RemoteException ex) {
7845                return -1;
7846            }
7847        }
7848
7849        if (targetUid >= 0) {
7850            // First...  does the target actually need this permission?
7851            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7852                // No need to grant the target this permission.
7853                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7854                        "Target " + targetPkg + " already has full permission to " + grantUri);
7855                return -1;
7856            }
7857        } else {
7858            // First...  there is no target package, so can anyone access it?
7859            boolean allowed = pi.exported;
7860            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7861                if (pi.readPermission != null) {
7862                    allowed = false;
7863                }
7864            }
7865            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7866                if (pi.writePermission != null) {
7867                    allowed = false;
7868                }
7869            }
7870            if (allowed) {
7871                return -1;
7872            }
7873        }
7874
7875        /* There is a special cross user grant if:
7876         * - The target is on another user.
7877         * - Apps on the current user can access the uri without any uid permissions.
7878         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7879         * grant uri permissions.
7880         */
7881        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7882                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7883                modeFlags, false /*without considering the uid permissions*/);
7884
7885        // Second...  is the provider allowing granting of URI permissions?
7886        if (!specialCrossUserGrant) {
7887            if (!pi.grantUriPermissions) {
7888                throw new SecurityException("Provider " + pi.packageName
7889                        + "/" + pi.name
7890                        + " does not allow granting of Uri permissions (uri "
7891                        + grantUri + ")");
7892            }
7893            if (pi.uriPermissionPatterns != null) {
7894                final int N = pi.uriPermissionPatterns.length;
7895                boolean allowed = false;
7896                for (int i=0; i<N; i++) {
7897                    if (pi.uriPermissionPatterns[i] != null
7898                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7899                        allowed = true;
7900                        break;
7901                    }
7902                }
7903                if (!allowed) {
7904                    throw new SecurityException("Provider " + pi.packageName
7905                            + "/" + pi.name
7906                            + " does not allow granting of permission to path of Uri "
7907                            + grantUri);
7908                }
7909            }
7910        }
7911
7912        // Third...  does the caller itself have permission to access
7913        // this uri?
7914        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7915            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7916                // Require they hold a strong enough Uri permission
7917                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7918                    throw new SecurityException("Uid " + callingUid
7919                            + " does not have permission to uri " + grantUri);
7920                }
7921            }
7922        }
7923        return targetUid;
7924    }
7925
7926    /**
7927     * @param uri This uri must NOT contain an embedded userId.
7928     * @param userId The userId in which the uri is to be resolved.
7929     */
7930    @Override
7931    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7932            final int modeFlags, int userId) {
7933        enforceNotIsolatedCaller("checkGrantUriPermission");
7934        synchronized(this) {
7935            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7936                    new GrantUri(userId, uri, false), modeFlags, -1);
7937        }
7938    }
7939
7940    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7941            final int modeFlags, UriPermissionOwner owner) {
7942        if (!Intent.isAccessUriMode(modeFlags)) {
7943            return;
7944        }
7945
7946        // So here we are: the caller has the assumed permission
7947        // to the uri, and the target doesn't.  Let's now give this to
7948        // the target.
7949
7950        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7951                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7952
7953        final String authority = grantUri.uri.getAuthority();
7954        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7955        if (pi == null) {
7956            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7957            return;
7958        }
7959
7960        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7961            grantUri.prefix = true;
7962        }
7963        final UriPermission perm = findOrCreateUriPermissionLocked(
7964                pi.packageName, targetPkg, targetUid, grantUri);
7965        perm.grantModes(modeFlags, owner);
7966    }
7967
7968    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7969            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7970        if (targetPkg == null) {
7971            throw new NullPointerException("targetPkg");
7972        }
7973        int targetUid;
7974        final IPackageManager pm = AppGlobals.getPackageManager();
7975        try {
7976            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7977        } catch (RemoteException ex) {
7978            return;
7979        }
7980
7981        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7982                targetUid);
7983        if (targetUid < 0) {
7984            return;
7985        }
7986
7987        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7988                owner);
7989    }
7990
7991    static class NeededUriGrants extends ArrayList<GrantUri> {
7992        final String targetPkg;
7993        final int targetUid;
7994        final int flags;
7995
7996        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7997            this.targetPkg = targetPkg;
7998            this.targetUid = targetUid;
7999            this.flags = flags;
8000        }
8001    }
8002
8003    /**
8004     * Like checkGrantUriPermissionLocked, but takes an Intent.
8005     */
8006    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8007            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8008        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8009                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8010                + " clip=" + (intent != null ? intent.getClipData() : null)
8011                + " from " + intent + "; flags=0x"
8012                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8013
8014        if (targetPkg == null) {
8015            throw new NullPointerException("targetPkg");
8016        }
8017
8018        if (intent == null) {
8019            return null;
8020        }
8021        Uri data = intent.getData();
8022        ClipData clip = intent.getClipData();
8023        if (data == null && clip == null) {
8024            return null;
8025        }
8026        // Default userId for uris in the intent (if they don't specify it themselves)
8027        int contentUserHint = intent.getContentUserHint();
8028        if (contentUserHint == UserHandle.USER_CURRENT) {
8029            contentUserHint = UserHandle.getUserId(callingUid);
8030        }
8031        final IPackageManager pm = AppGlobals.getPackageManager();
8032        int targetUid;
8033        if (needed != null) {
8034            targetUid = needed.targetUid;
8035        } else {
8036            try {
8037                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8038                        targetUserId);
8039            } catch (RemoteException ex) {
8040                return null;
8041            }
8042            if (targetUid < 0) {
8043                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8044                        "Can't grant URI permission no uid for: " + targetPkg
8045                        + " on user " + targetUserId);
8046                return null;
8047            }
8048        }
8049        if (data != null) {
8050            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8051            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8052                    targetUid);
8053            if (targetUid > 0) {
8054                if (needed == null) {
8055                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8056                }
8057                needed.add(grantUri);
8058            }
8059        }
8060        if (clip != null) {
8061            for (int i=0; i<clip.getItemCount(); i++) {
8062                Uri uri = clip.getItemAt(i).getUri();
8063                if (uri != null) {
8064                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8065                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8066                            targetUid);
8067                    if (targetUid > 0) {
8068                        if (needed == null) {
8069                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8070                        }
8071                        needed.add(grantUri);
8072                    }
8073                } else {
8074                    Intent clipIntent = clip.getItemAt(i).getIntent();
8075                    if (clipIntent != null) {
8076                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8077                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8078                        if (newNeeded != null) {
8079                            needed = newNeeded;
8080                        }
8081                    }
8082                }
8083            }
8084        }
8085
8086        return needed;
8087    }
8088
8089    /**
8090     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8091     */
8092    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8093            UriPermissionOwner owner) {
8094        if (needed != null) {
8095            for (int i=0; i<needed.size(); i++) {
8096                GrantUri grantUri = needed.get(i);
8097                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8098                        grantUri, needed.flags, owner);
8099            }
8100        }
8101    }
8102
8103    void grantUriPermissionFromIntentLocked(int callingUid,
8104            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8105        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8106                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8107        if (needed == null) {
8108            return;
8109        }
8110
8111        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8112    }
8113
8114    /**
8115     * @param uri This uri must NOT contain an embedded userId.
8116     * @param userId The userId in which the uri is to be resolved.
8117     */
8118    @Override
8119    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8120            final int modeFlags, int userId) {
8121        enforceNotIsolatedCaller("grantUriPermission");
8122        GrantUri grantUri = new GrantUri(userId, uri, false);
8123        synchronized(this) {
8124            final ProcessRecord r = getRecordForAppLocked(caller);
8125            if (r == null) {
8126                throw new SecurityException("Unable to find app for caller "
8127                        + caller
8128                        + " when granting permission to uri " + grantUri);
8129            }
8130            if (targetPkg == null) {
8131                throw new IllegalArgumentException("null target");
8132            }
8133            if (grantUri == null) {
8134                throw new IllegalArgumentException("null uri");
8135            }
8136
8137            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8138                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8139                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8140                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8141
8142            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8143                    UserHandle.getUserId(r.uid));
8144        }
8145    }
8146
8147    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8148        if (perm.modeFlags == 0) {
8149            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8150                    perm.targetUid);
8151            if (perms != null) {
8152                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8153                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8154
8155                perms.remove(perm.uri);
8156                if (perms.isEmpty()) {
8157                    mGrantedUriPermissions.remove(perm.targetUid);
8158                }
8159            }
8160        }
8161    }
8162
8163    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8164        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8165                "Revoking all granted permissions to " + grantUri);
8166
8167        final IPackageManager pm = AppGlobals.getPackageManager();
8168        final String authority = grantUri.uri.getAuthority();
8169        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8170        if (pi == null) {
8171            Slog.w(TAG, "No content provider found for permission revoke: "
8172                    + grantUri.toSafeString());
8173            return;
8174        }
8175
8176        // Does the caller have this permission on the URI?
8177        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8178            // If they don't have direct access to the URI, then revoke any
8179            // ownerless URI permissions that have been granted to them.
8180            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8181            if (perms != null) {
8182                boolean persistChanged = false;
8183                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8184                    final UriPermission perm = it.next();
8185                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8186                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8187                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8188                                "Revoking non-owned " + perm.targetUid
8189                                + " permission to " + perm.uri);
8190                        persistChanged |= perm.revokeModes(
8191                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8192                        if (perm.modeFlags == 0) {
8193                            it.remove();
8194                        }
8195                    }
8196                }
8197                if (perms.isEmpty()) {
8198                    mGrantedUriPermissions.remove(callingUid);
8199                }
8200                if (persistChanged) {
8201                    schedulePersistUriGrants();
8202                }
8203            }
8204            return;
8205        }
8206
8207        boolean persistChanged = false;
8208
8209        // Go through all of the permissions and remove any that match.
8210        int N = mGrantedUriPermissions.size();
8211        for (int i = 0; i < N; i++) {
8212            final int targetUid = mGrantedUriPermissions.keyAt(i);
8213            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8214
8215            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8216                final UriPermission perm = it.next();
8217                if (perm.uri.sourceUserId == grantUri.sourceUserId
8218                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8219                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8220                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8221                    persistChanged |= perm.revokeModes(
8222                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8223                    if (perm.modeFlags == 0) {
8224                        it.remove();
8225                    }
8226                }
8227            }
8228
8229            if (perms.isEmpty()) {
8230                mGrantedUriPermissions.remove(targetUid);
8231                N--;
8232                i--;
8233            }
8234        }
8235
8236        if (persistChanged) {
8237            schedulePersistUriGrants();
8238        }
8239    }
8240
8241    /**
8242     * @param uri This uri must NOT contain an embedded userId.
8243     * @param userId The userId in which the uri is to be resolved.
8244     */
8245    @Override
8246    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8247            int userId) {
8248        enforceNotIsolatedCaller("revokeUriPermission");
8249        synchronized(this) {
8250            final ProcessRecord r = getRecordForAppLocked(caller);
8251            if (r == null) {
8252                throw new SecurityException("Unable to find app for caller "
8253                        + caller
8254                        + " when revoking permission to uri " + uri);
8255            }
8256            if (uri == null) {
8257                Slog.w(TAG, "revokeUriPermission: null uri");
8258                return;
8259            }
8260
8261            if (!Intent.isAccessUriMode(modeFlags)) {
8262                return;
8263            }
8264
8265            final String authority = uri.getAuthority();
8266            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8267            if (pi == null) {
8268                Slog.w(TAG, "No content provider found for permission revoke: "
8269                        + uri.toSafeString());
8270                return;
8271            }
8272
8273            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8274        }
8275    }
8276
8277    /**
8278     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8279     * given package.
8280     *
8281     * @param packageName Package name to match, or {@code null} to apply to all
8282     *            packages.
8283     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8284     *            to all users.
8285     * @param persistable If persistable grants should be removed.
8286     */
8287    private void removeUriPermissionsForPackageLocked(
8288            String packageName, int userHandle, boolean persistable) {
8289        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8290            throw new IllegalArgumentException("Must narrow by either package or user");
8291        }
8292
8293        boolean persistChanged = false;
8294
8295        int N = mGrantedUriPermissions.size();
8296        for (int i = 0; i < N; i++) {
8297            final int targetUid = mGrantedUriPermissions.keyAt(i);
8298            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8299
8300            // Only inspect grants matching user
8301            if (userHandle == UserHandle.USER_ALL
8302                    || userHandle == UserHandle.getUserId(targetUid)) {
8303                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8304                    final UriPermission perm = it.next();
8305
8306                    // Only inspect grants matching package
8307                    if (packageName == null || perm.sourcePkg.equals(packageName)
8308                            || perm.targetPkg.equals(packageName)) {
8309                        persistChanged |= perm.revokeModes(persistable
8310                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8311
8312                        // Only remove when no modes remain; any persisted grants
8313                        // will keep this alive.
8314                        if (perm.modeFlags == 0) {
8315                            it.remove();
8316                        }
8317                    }
8318                }
8319
8320                if (perms.isEmpty()) {
8321                    mGrantedUriPermissions.remove(targetUid);
8322                    N--;
8323                    i--;
8324                }
8325            }
8326        }
8327
8328        if (persistChanged) {
8329            schedulePersistUriGrants();
8330        }
8331    }
8332
8333    @Override
8334    public IBinder newUriPermissionOwner(String name) {
8335        enforceNotIsolatedCaller("newUriPermissionOwner");
8336        synchronized(this) {
8337            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8338            return owner.getExternalTokenLocked();
8339        }
8340    }
8341
8342    @Override
8343    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8344        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8345        synchronized(this) {
8346            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8347            if (r == null) {
8348                throw new IllegalArgumentException("Activity does not exist; token="
8349                        + activityToken);
8350            }
8351            return r.getUriPermissionsLocked().getExternalTokenLocked();
8352        }
8353    }
8354    /**
8355     * @param uri This uri must NOT contain an embedded userId.
8356     * @param sourceUserId The userId in which the uri is to be resolved.
8357     * @param targetUserId The userId of the app that receives the grant.
8358     */
8359    @Override
8360    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8361            final int modeFlags, int sourceUserId, int targetUserId) {
8362        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8363                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8364                "grantUriPermissionFromOwner", null);
8365        synchronized(this) {
8366            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8367            if (owner == null) {
8368                throw new IllegalArgumentException("Unknown owner: " + token);
8369            }
8370            if (fromUid != Binder.getCallingUid()) {
8371                if (Binder.getCallingUid() != Process.myUid()) {
8372                    // Only system code can grant URI permissions on behalf
8373                    // of other users.
8374                    throw new SecurityException("nice try");
8375                }
8376            }
8377            if (targetPkg == null) {
8378                throw new IllegalArgumentException("null target");
8379            }
8380            if (uri == null) {
8381                throw new IllegalArgumentException("null uri");
8382            }
8383
8384            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8385                    modeFlags, owner, targetUserId);
8386        }
8387    }
8388
8389    /**
8390     * @param uri This uri must NOT contain an embedded userId.
8391     * @param userId The userId in which the uri is to be resolved.
8392     */
8393    @Override
8394    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8395        synchronized(this) {
8396            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8397            if (owner == null) {
8398                throw new IllegalArgumentException("Unknown owner: " + token);
8399            }
8400
8401            if (uri == null) {
8402                owner.removeUriPermissionsLocked(mode);
8403            } else {
8404                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8405            }
8406        }
8407    }
8408
8409    private void schedulePersistUriGrants() {
8410        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8411            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8412                    10 * DateUtils.SECOND_IN_MILLIS);
8413        }
8414    }
8415
8416    private void writeGrantedUriPermissions() {
8417        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8418
8419        // Snapshot permissions so we can persist without lock
8420        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8421        synchronized (this) {
8422            final int size = mGrantedUriPermissions.size();
8423            for (int i = 0; i < size; i++) {
8424                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8425                for (UriPermission perm : perms.values()) {
8426                    if (perm.persistedModeFlags != 0) {
8427                        persist.add(perm.snapshot());
8428                    }
8429                }
8430            }
8431        }
8432
8433        FileOutputStream fos = null;
8434        try {
8435            fos = mGrantFile.startWrite();
8436
8437            XmlSerializer out = new FastXmlSerializer();
8438            out.setOutput(fos, StandardCharsets.UTF_8.name());
8439            out.startDocument(null, true);
8440            out.startTag(null, TAG_URI_GRANTS);
8441            for (UriPermission.Snapshot perm : persist) {
8442                out.startTag(null, TAG_URI_GRANT);
8443                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8444                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8445                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8446                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8447                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8448                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8449                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8450                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8451                out.endTag(null, TAG_URI_GRANT);
8452            }
8453            out.endTag(null, TAG_URI_GRANTS);
8454            out.endDocument();
8455
8456            mGrantFile.finishWrite(fos);
8457        } catch (IOException e) {
8458            if (fos != null) {
8459                mGrantFile.failWrite(fos);
8460            }
8461        }
8462    }
8463
8464    private void readGrantedUriPermissionsLocked() {
8465        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8466
8467        final long now = System.currentTimeMillis();
8468
8469        FileInputStream fis = null;
8470        try {
8471            fis = mGrantFile.openRead();
8472            final XmlPullParser in = Xml.newPullParser();
8473            in.setInput(fis, StandardCharsets.UTF_8.name());
8474
8475            int type;
8476            while ((type = in.next()) != END_DOCUMENT) {
8477                final String tag = in.getName();
8478                if (type == START_TAG) {
8479                    if (TAG_URI_GRANT.equals(tag)) {
8480                        final int sourceUserId;
8481                        final int targetUserId;
8482                        final int userHandle = readIntAttribute(in,
8483                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8484                        if (userHandle != UserHandle.USER_NULL) {
8485                            // For backwards compatibility.
8486                            sourceUserId = userHandle;
8487                            targetUserId = userHandle;
8488                        } else {
8489                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8490                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8491                        }
8492                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8493                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8494                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8495                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8496                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8497                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8498
8499                        // Sanity check that provider still belongs to source package
8500                        final ProviderInfo pi = getProviderInfoLocked(
8501                                uri.getAuthority(), sourceUserId);
8502                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8503                            int targetUid = -1;
8504                            try {
8505                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8506                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8507                            } catch (RemoteException e) {
8508                            }
8509                            if (targetUid != -1) {
8510                                final UriPermission perm = findOrCreateUriPermissionLocked(
8511                                        sourcePkg, targetPkg, targetUid,
8512                                        new GrantUri(sourceUserId, uri, prefix));
8513                                perm.initPersistedModes(modeFlags, createdTime);
8514                            }
8515                        } else {
8516                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8517                                    + " but instead found " + pi);
8518                        }
8519                    }
8520                }
8521            }
8522        } catch (FileNotFoundException e) {
8523            // Missing grants is okay
8524        } catch (IOException e) {
8525            Slog.wtf(TAG, "Failed reading Uri grants", e);
8526        } catch (XmlPullParserException e) {
8527            Slog.wtf(TAG, "Failed reading Uri grants", e);
8528        } finally {
8529            IoUtils.closeQuietly(fis);
8530        }
8531    }
8532
8533    /**
8534     * @param uri This uri must NOT contain an embedded userId.
8535     * @param userId The userId in which the uri is to be resolved.
8536     */
8537    @Override
8538    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8539        enforceNotIsolatedCaller("takePersistableUriPermission");
8540
8541        Preconditions.checkFlagsArgument(modeFlags,
8542                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8543
8544        synchronized (this) {
8545            final int callingUid = Binder.getCallingUid();
8546            boolean persistChanged = false;
8547            GrantUri grantUri = new GrantUri(userId, uri, false);
8548
8549            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8550                    new GrantUri(userId, uri, false));
8551            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8552                    new GrantUri(userId, uri, true));
8553
8554            final boolean exactValid = (exactPerm != null)
8555                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8556            final boolean prefixValid = (prefixPerm != null)
8557                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8558
8559            if (!(exactValid || prefixValid)) {
8560                throw new SecurityException("No persistable permission grants found for UID "
8561                        + callingUid + " and Uri " + grantUri.toSafeString());
8562            }
8563
8564            if (exactValid) {
8565                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8566            }
8567            if (prefixValid) {
8568                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8569            }
8570
8571            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8572
8573            if (persistChanged) {
8574                schedulePersistUriGrants();
8575            }
8576        }
8577    }
8578
8579    /**
8580     * @param uri This uri must NOT contain an embedded userId.
8581     * @param userId The userId in which the uri is to be resolved.
8582     */
8583    @Override
8584    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8585        enforceNotIsolatedCaller("releasePersistableUriPermission");
8586
8587        Preconditions.checkFlagsArgument(modeFlags,
8588                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8589
8590        synchronized (this) {
8591            final int callingUid = Binder.getCallingUid();
8592            boolean persistChanged = false;
8593
8594            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8595                    new GrantUri(userId, uri, false));
8596            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8597                    new GrantUri(userId, uri, true));
8598            if (exactPerm == null && prefixPerm == null) {
8599                throw new SecurityException("No permission grants found for UID " + callingUid
8600                        + " and Uri " + uri.toSafeString());
8601            }
8602
8603            if (exactPerm != null) {
8604                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8605                removeUriPermissionIfNeededLocked(exactPerm);
8606            }
8607            if (prefixPerm != null) {
8608                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8609                removeUriPermissionIfNeededLocked(prefixPerm);
8610            }
8611
8612            if (persistChanged) {
8613                schedulePersistUriGrants();
8614            }
8615        }
8616    }
8617
8618    /**
8619     * Prune any older {@link UriPermission} for the given UID until outstanding
8620     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8621     *
8622     * @return if any mutations occured that require persisting.
8623     */
8624    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8625        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8626        if (perms == null) return false;
8627        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8628
8629        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8630        for (UriPermission perm : perms.values()) {
8631            if (perm.persistedModeFlags != 0) {
8632                persisted.add(perm);
8633            }
8634        }
8635
8636        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8637        if (trimCount <= 0) return false;
8638
8639        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8640        for (int i = 0; i < trimCount; i++) {
8641            final UriPermission perm = persisted.get(i);
8642
8643            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8644                    "Trimming grant created at " + perm.persistedCreateTime);
8645
8646            perm.releasePersistableModes(~0);
8647            removeUriPermissionIfNeededLocked(perm);
8648        }
8649
8650        return true;
8651    }
8652
8653    @Override
8654    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8655            String packageName, boolean incoming) {
8656        enforceNotIsolatedCaller("getPersistedUriPermissions");
8657        Preconditions.checkNotNull(packageName, "packageName");
8658
8659        final int callingUid = Binder.getCallingUid();
8660        final IPackageManager pm = AppGlobals.getPackageManager();
8661        try {
8662            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8663                    UserHandle.getUserId(callingUid));
8664            if (packageUid != callingUid) {
8665                throw new SecurityException(
8666                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8667            }
8668        } catch (RemoteException e) {
8669            throw new SecurityException("Failed to verify package name ownership");
8670        }
8671
8672        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8673        synchronized (this) {
8674            if (incoming) {
8675                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8676                        callingUid);
8677                if (perms == null) {
8678                    Slog.w(TAG, "No permission grants found for " + packageName);
8679                } else {
8680                    for (UriPermission perm : perms.values()) {
8681                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8682                            result.add(perm.buildPersistedPublicApiObject());
8683                        }
8684                    }
8685                }
8686            } else {
8687                final int size = mGrantedUriPermissions.size();
8688                for (int i = 0; i < size; i++) {
8689                    final ArrayMap<GrantUri, UriPermission> perms =
8690                            mGrantedUriPermissions.valueAt(i);
8691                    for (UriPermission perm : perms.values()) {
8692                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8693                            result.add(perm.buildPersistedPublicApiObject());
8694                        }
8695                    }
8696                }
8697            }
8698        }
8699        return new ParceledListSlice<android.content.UriPermission>(result);
8700    }
8701
8702    @Override
8703    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8704            String packageName, int userId) {
8705        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8706                "getGrantedUriPermissions");
8707
8708        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8709        synchronized (this) {
8710            final int size = mGrantedUriPermissions.size();
8711            for (int i = 0; i < size; i++) {
8712                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8713                for (UriPermission perm : perms.values()) {
8714                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8715                            && perm.persistedModeFlags != 0) {
8716                        result.add(perm.buildPersistedPublicApiObject());
8717                    }
8718                }
8719            }
8720        }
8721        return new ParceledListSlice<android.content.UriPermission>(result);
8722    }
8723
8724    @Override
8725    public void clearGrantedUriPermissions(String packageName, int userId) {
8726        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8727                "clearGrantedUriPermissions");
8728        removeUriPermissionsForPackageLocked(packageName, userId, true);
8729    }
8730
8731    @Override
8732    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8733        synchronized (this) {
8734            ProcessRecord app =
8735                who != null ? getRecordForAppLocked(who) : null;
8736            if (app == null) return;
8737
8738            Message msg = Message.obtain();
8739            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8740            msg.obj = app;
8741            msg.arg1 = waiting ? 1 : 0;
8742            mUiHandler.sendMessage(msg);
8743        }
8744    }
8745
8746    @Override
8747    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8748        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8749        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8750        outInfo.availMem = Process.getFreeMemory();
8751        outInfo.totalMem = Process.getTotalMemory();
8752        outInfo.threshold = homeAppMem;
8753        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8754        outInfo.hiddenAppThreshold = cachedAppMem;
8755        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8756                ProcessList.SERVICE_ADJ);
8757        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8758                ProcessList.VISIBLE_APP_ADJ);
8759        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8760                ProcessList.FOREGROUND_APP_ADJ);
8761    }
8762
8763    // =========================================================
8764    // TASK MANAGEMENT
8765    // =========================================================
8766
8767    @Override
8768    public List<IAppTask> getAppTasks(String callingPackage) {
8769        int callingUid = Binder.getCallingUid();
8770        long ident = Binder.clearCallingIdentity();
8771
8772        synchronized(this) {
8773            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8774            try {
8775                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8776
8777                final int N = mRecentTasks.size();
8778                for (int i = 0; i < N; i++) {
8779                    TaskRecord tr = mRecentTasks.get(i);
8780                    // Skip tasks that do not match the caller.  We don't need to verify
8781                    // callingPackage, because we are also limiting to callingUid and know
8782                    // that will limit to the correct security sandbox.
8783                    if (tr.effectiveUid != callingUid) {
8784                        continue;
8785                    }
8786                    Intent intent = tr.getBaseIntent();
8787                    if (intent == null ||
8788                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8789                        continue;
8790                    }
8791                    ActivityManager.RecentTaskInfo taskInfo =
8792                            createRecentTaskInfoFromTaskRecord(tr);
8793                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8794                    list.add(taskImpl);
8795                }
8796            } finally {
8797                Binder.restoreCallingIdentity(ident);
8798            }
8799            return list;
8800        }
8801    }
8802
8803    @Override
8804    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8805        final int callingUid = Binder.getCallingUid();
8806        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8807
8808        synchronized(this) {
8809            if (DEBUG_ALL) Slog.v(
8810                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8811
8812            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8813                    callingUid);
8814
8815            // TODO: Improve with MRU list from all ActivityStacks.
8816            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8817        }
8818
8819        return list;
8820    }
8821
8822    /**
8823     * Creates a new RecentTaskInfo from a TaskRecord.
8824     */
8825    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8826        // Update the task description to reflect any changes in the task stack
8827        tr.updateTaskDescription();
8828
8829        // Compose the recent task info
8830        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8831        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8832        rti.persistentId = tr.taskId;
8833        rti.baseIntent = new Intent(tr.getBaseIntent());
8834        rti.origActivity = tr.origActivity;
8835        rti.realActivity = tr.realActivity;
8836        rti.description = tr.lastDescription;
8837        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8838        rti.userId = tr.userId;
8839        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8840        rti.firstActiveTime = tr.firstActiveTime;
8841        rti.lastActiveTime = tr.lastActiveTime;
8842        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8843        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8844        rti.numActivities = 0;
8845        if (tr.mBounds != null) {
8846            rti.bounds = new Rect(tr.mBounds);
8847        }
8848        rti.isDockable = tr.canGoInDockedStack();
8849        rti.resizeMode = tr.mResizeMode;
8850
8851        ActivityRecord base = null;
8852        ActivityRecord top = null;
8853        ActivityRecord tmp;
8854
8855        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8856            tmp = tr.mActivities.get(i);
8857            if (tmp.finishing) {
8858                continue;
8859            }
8860            base = tmp;
8861            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8862                top = base;
8863            }
8864            rti.numActivities++;
8865        }
8866
8867        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8868        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8869
8870        return rti;
8871    }
8872
8873    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8874        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8875                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8876        if (!allowed) {
8877            if (checkPermission(android.Manifest.permission.GET_TASKS,
8878                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8879                // Temporary compatibility: some existing apps on the system image may
8880                // still be requesting the old permission and not switched to the new
8881                // one; if so, we'll still allow them full access.  This means we need
8882                // to see if they are holding the old permission and are a system app.
8883                try {
8884                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8885                        allowed = true;
8886                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8887                                + " is using old GET_TASKS but privileged; allowing");
8888                    }
8889                } catch (RemoteException e) {
8890                }
8891            }
8892        }
8893        if (!allowed) {
8894            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8895                    + " does not hold REAL_GET_TASKS; limiting output");
8896        }
8897        return allowed;
8898    }
8899
8900    @Override
8901    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8902        final int callingUid = Binder.getCallingUid();
8903        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8904                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8905
8906        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8907        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8908        synchronized (this) {
8909            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8910                    callingUid);
8911            final boolean detailed = checkCallingPermission(
8912                    android.Manifest.permission.GET_DETAILED_TASKS)
8913                    == PackageManager.PERMISSION_GRANTED;
8914
8915            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8916                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8917                return Collections.emptyList();
8918            }
8919            mRecentTasks.loadUserRecentsLocked(userId);
8920
8921            final int recentsCount = mRecentTasks.size();
8922            ArrayList<ActivityManager.RecentTaskInfo> res =
8923                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8924
8925            final Set<Integer> includedUsers;
8926            if (includeProfiles) {
8927                includedUsers = mUserController.getProfileIds(userId);
8928            } else {
8929                includedUsers = new HashSet<>();
8930            }
8931            includedUsers.add(Integer.valueOf(userId));
8932
8933            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8934                TaskRecord tr = mRecentTasks.get(i);
8935                // Only add calling user or related users recent tasks
8936                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8937                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8938                    continue;
8939                }
8940
8941                if (tr.realActivitySuspended) {
8942                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8943                    continue;
8944                }
8945
8946                // Return the entry if desired by the caller.  We always return
8947                // the first entry, because callers always expect this to be the
8948                // foreground app.  We may filter others if the caller has
8949                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8950                // we should exclude the entry.
8951
8952                if (i == 0
8953                        || withExcluded
8954                        || (tr.intent == null)
8955                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8956                                == 0)) {
8957                    if (!allowed) {
8958                        // If the caller doesn't have the GET_TASKS permission, then only
8959                        // allow them to see a small subset of tasks -- their own and home.
8960                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8961                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8962                            continue;
8963                        }
8964                    }
8965                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8966                        if (tr.stack != null && tr.stack.isHomeStack()) {
8967                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8968                                    "Skipping, home stack task: " + tr);
8969                            continue;
8970                        }
8971                    }
8972                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8973                        final ActivityStack stack = tr.stack;
8974                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8975                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8976                                    "Skipping, top task in docked stack: " + tr);
8977                            continue;
8978                        }
8979                    }
8980                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8981                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8982                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8983                                    "Skipping, pinned stack task: " + tr);
8984                            continue;
8985                        }
8986                    }
8987                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8988                        // Don't include auto remove tasks that are finished or finishing.
8989                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8990                                "Skipping, auto-remove without activity: " + tr);
8991                        continue;
8992                    }
8993                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8994                            && !tr.isAvailable) {
8995                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8996                                "Skipping, unavail real act: " + tr);
8997                        continue;
8998                    }
8999
9000                    if (!tr.mUserSetupComplete) {
9001                        // Don't include task launched while user is not done setting-up.
9002                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9003                                "Skipping, user setup not complete: " + tr);
9004                        continue;
9005                    }
9006
9007                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9008                    if (!detailed) {
9009                        rti.baseIntent.replaceExtras((Bundle)null);
9010                    }
9011
9012                    res.add(rti);
9013                    maxNum--;
9014                }
9015            }
9016            return res;
9017        }
9018    }
9019
9020    @Override
9021    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9022        synchronized (this) {
9023            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9024                    "getTaskThumbnail()");
9025            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9026                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9027            if (tr != null) {
9028                return tr.getTaskThumbnailLocked();
9029            }
9030        }
9031        return null;
9032    }
9033
9034    @Override
9035    public int addAppTask(IBinder activityToken, Intent intent,
9036            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9037        final int callingUid = Binder.getCallingUid();
9038        final long callingIdent = Binder.clearCallingIdentity();
9039
9040        try {
9041            synchronized (this) {
9042                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9043                if (r == null) {
9044                    throw new IllegalArgumentException("Activity does not exist; token="
9045                            + activityToken);
9046                }
9047                ComponentName comp = intent.getComponent();
9048                if (comp == null) {
9049                    throw new IllegalArgumentException("Intent " + intent
9050                            + " must specify explicit component");
9051                }
9052                if (thumbnail.getWidth() != mThumbnailWidth
9053                        || thumbnail.getHeight() != mThumbnailHeight) {
9054                    throw new IllegalArgumentException("Bad thumbnail size: got "
9055                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9056                            + mThumbnailWidth + "x" + mThumbnailHeight);
9057                }
9058                if (intent.getSelector() != null) {
9059                    intent.setSelector(null);
9060                }
9061                if (intent.getSourceBounds() != null) {
9062                    intent.setSourceBounds(null);
9063                }
9064                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9065                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9066                        // The caller has added this as an auto-remove task...  that makes no
9067                        // sense, so turn off auto-remove.
9068                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9069                    }
9070                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9071                    // Must be a new task.
9072                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9073                }
9074                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9075                    mLastAddedTaskActivity = null;
9076                }
9077                ActivityInfo ainfo = mLastAddedTaskActivity;
9078                if (ainfo == null) {
9079                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9080                            comp, 0, UserHandle.getUserId(callingUid));
9081                    if (ainfo.applicationInfo.uid != callingUid) {
9082                        throw new SecurityException(
9083                                "Can't add task for another application: target uid="
9084                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9085                    }
9086                }
9087
9088                // Use the full screen as the context for the task thumbnail
9089                final Point displaySize = new Point();
9090                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9091                r.task.stack.getDisplaySize(displaySize);
9092                thumbnailInfo.taskWidth = displaySize.x;
9093                thumbnailInfo.taskHeight = displaySize.y;
9094                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9095
9096                TaskRecord task = new TaskRecord(this,
9097                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9098                        ainfo, intent, description, thumbnailInfo);
9099
9100                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9101                if (trimIdx >= 0) {
9102                    // If this would have caused a trim, then we'll abort because that
9103                    // means it would be added at the end of the list but then just removed.
9104                    return INVALID_TASK_ID;
9105                }
9106
9107                final int N = mRecentTasks.size();
9108                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9109                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9110                    tr.removedFromRecents();
9111                }
9112
9113                task.inRecents = true;
9114                mRecentTasks.add(task);
9115                r.task.stack.addTask(task, false, "addAppTask");
9116
9117                task.setLastThumbnailLocked(thumbnail);
9118                task.freeLastThumbnail();
9119
9120                return task.taskId;
9121            }
9122        } finally {
9123            Binder.restoreCallingIdentity(callingIdent);
9124        }
9125    }
9126
9127    @Override
9128    public Point getAppTaskThumbnailSize() {
9129        synchronized (this) {
9130            return new Point(mThumbnailWidth,  mThumbnailHeight);
9131        }
9132    }
9133
9134    @Override
9135    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9136        synchronized (this) {
9137            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9138            if (r != null) {
9139                r.setTaskDescription(td);
9140                r.task.updateTaskDescription();
9141            }
9142        }
9143    }
9144
9145    @Override
9146    public void setTaskResizeable(int taskId, int resizeableMode) {
9147        synchronized (this) {
9148            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9149                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9150            if (task == null) {
9151                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9152                return;
9153            }
9154            if (task.mResizeMode != resizeableMode) {
9155                task.mResizeMode = resizeableMode;
9156                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9157                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9158                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9159            }
9160        }
9161    }
9162
9163    @Override
9164    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9165        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9166        long ident = Binder.clearCallingIdentity();
9167        try {
9168            synchronized (this) {
9169                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9170                if (task == null) {
9171                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9172                    return;
9173                }
9174                int stackId = task.stack.mStackId;
9175                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9176                // in crop windows resize mode or if the task size is affected by the docked stack
9177                // changing size. No need to update configuration.
9178                if (bounds != null && task.inCropWindowsResizeMode()
9179                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9180                    mWindowManager.scrollTask(task.taskId, bounds);
9181                    return;
9182                }
9183
9184                // Place the task in the right stack if it isn't there already based on
9185                // the requested bounds.
9186                // The stack transition logic is:
9187                // - a null bounds on a freeform task moves that task to fullscreen
9188                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9189                //   that task to freeform
9190                // - otherwise the task is not moved
9191                if (!StackId.isTaskResizeAllowed(stackId)) {
9192                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9193                }
9194                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9195                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9196                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9197                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9198                }
9199                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9200                if (stackId != task.stack.mStackId) {
9201                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9202                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9203                    preserveWindow = false;
9204                }
9205
9206                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9207                        false /* deferResume */);
9208            }
9209        } finally {
9210            Binder.restoreCallingIdentity(ident);
9211        }
9212    }
9213
9214    @Override
9215    public Rect getTaskBounds(int taskId) {
9216        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9217        long ident = Binder.clearCallingIdentity();
9218        Rect rect = new Rect();
9219        try {
9220            synchronized (this) {
9221                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9222                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9223                if (task == null) {
9224                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9225                    return rect;
9226                }
9227                if (task.stack != null) {
9228                    // Return the bounds from window manager since it will be adjusted for various
9229                    // things like the presense of a docked stack for tasks that aren't resizeable.
9230                    mWindowManager.getTaskBounds(task.taskId, rect);
9231                } else {
9232                    // Task isn't in window manager yet since it isn't associated with a stack.
9233                    // Return the persist value from activity manager
9234                    if (task.mBounds != null) {
9235                        rect.set(task.mBounds);
9236                    } else if (task.mLastNonFullscreenBounds != null) {
9237                        rect.set(task.mLastNonFullscreenBounds);
9238                    }
9239                }
9240            }
9241        } finally {
9242            Binder.restoreCallingIdentity(ident);
9243        }
9244        return rect;
9245    }
9246
9247    @Override
9248    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9249        if (userId != UserHandle.getCallingUserId()) {
9250            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9251                    "getTaskDescriptionIcon");
9252        }
9253        final File passedIconFile = new File(filePath);
9254        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9255                passedIconFile.getName());
9256        if (!legitIconFile.getPath().equals(filePath)
9257                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9258            throw new IllegalArgumentException("Bad file path: " + filePath
9259                    + " passed for userId " + userId);
9260        }
9261        return mRecentTasks.getTaskDescriptionIcon(filePath);
9262    }
9263
9264    @Override
9265    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9266            throws RemoteException {
9267        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9268                opts.getCustomInPlaceResId() == 0) {
9269            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9270                    "with valid animation");
9271        }
9272        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9273        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9274                opts.getCustomInPlaceResId());
9275        mWindowManager.executeAppTransition();
9276    }
9277
9278    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9279            boolean removeFromRecents) {
9280        if (removeFromRecents) {
9281            mRecentTasks.remove(tr);
9282            tr.removedFromRecents();
9283        }
9284        ComponentName component = tr.getBaseIntent().getComponent();
9285        if (component == null) {
9286            Slog.w(TAG, "No component for base intent of task: " + tr);
9287            return;
9288        }
9289
9290        // Find any running services associated with this app and stop if needed.
9291        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9292
9293        if (!killProcess) {
9294            return;
9295        }
9296
9297        // Determine if the process(es) for this task should be killed.
9298        final String pkg = component.getPackageName();
9299        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9300        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9301        for (int i = 0; i < pmap.size(); i++) {
9302
9303            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9304            for (int j = 0; j < uids.size(); j++) {
9305                ProcessRecord proc = uids.valueAt(j);
9306                if (proc.userId != tr.userId) {
9307                    // Don't kill process for a different user.
9308                    continue;
9309                }
9310                if (proc == mHomeProcess) {
9311                    // Don't kill the home process along with tasks from the same package.
9312                    continue;
9313                }
9314                if (!proc.pkgList.containsKey(pkg)) {
9315                    // Don't kill process that is not associated with this task.
9316                    continue;
9317                }
9318
9319                for (int k = 0; k < proc.activities.size(); k++) {
9320                    TaskRecord otherTask = proc.activities.get(k).task;
9321                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9322                        // Don't kill process(es) that has an activity in a different task that is
9323                        // also in recents.
9324                        return;
9325                    }
9326                }
9327
9328                if (proc.foregroundServices) {
9329                    // Don't kill process(es) with foreground service.
9330                    return;
9331                }
9332
9333                // Add process to kill list.
9334                procsToKill.add(proc);
9335            }
9336        }
9337
9338        // Kill the running processes.
9339        for (int i = 0; i < procsToKill.size(); i++) {
9340            ProcessRecord pr = procsToKill.get(i);
9341            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9342                    && pr.curReceiver == null) {
9343                pr.kill("remove task", true);
9344            } else {
9345                // We delay killing processes that are not in the background or running a receiver.
9346                pr.waitingToKill = "remove task";
9347            }
9348        }
9349    }
9350
9351    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9352        // Remove all tasks with activities in the specified package from the list of recent tasks
9353        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9354            TaskRecord tr = mRecentTasks.get(i);
9355            if (tr.userId != userId) continue;
9356
9357            ComponentName cn = tr.intent.getComponent();
9358            if (cn != null && cn.getPackageName().equals(packageName)) {
9359                // If the package name matches, remove the task.
9360                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9361            }
9362        }
9363    }
9364
9365    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9366            int userId) {
9367
9368        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9369            TaskRecord tr = mRecentTasks.get(i);
9370            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9371                continue;
9372            }
9373
9374            ComponentName cn = tr.intent.getComponent();
9375            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9376                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9377            if (sameComponent) {
9378                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9379            }
9380        }
9381    }
9382
9383    /**
9384     * Removes the task with the specified task id.
9385     *
9386     * @param taskId Identifier of the task to be removed.
9387     * @param killProcess Kill any process associated with the task if possible.
9388     * @param removeFromRecents Whether to also remove the task from recents.
9389     * @return Returns true if the given task was found and removed.
9390     */
9391    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9392            boolean removeFromRecents) {
9393        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9394                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9395        if (tr != null) {
9396            tr.removeTaskActivitiesLocked();
9397            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9398            if (tr.isPersistable) {
9399                notifyTaskPersisterLocked(null, true);
9400            }
9401            return true;
9402        }
9403        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9404        return false;
9405    }
9406
9407    @Override
9408    public void removeStack(int stackId) {
9409        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9410        if (stackId == HOME_STACK_ID) {
9411            throw new IllegalArgumentException("Removing home stack is not allowed.");
9412        }
9413
9414        synchronized (this) {
9415            final long ident = Binder.clearCallingIdentity();
9416            try {
9417                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9418                if (stack == null) {
9419                    return;
9420                }
9421                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9422                for (int i = tasks.size() - 1; i >= 0; i--) {
9423                    removeTaskByIdLocked(
9424                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9425                }
9426            } finally {
9427                Binder.restoreCallingIdentity(ident);
9428            }
9429        }
9430    }
9431
9432    @Override
9433    public boolean removeTask(int taskId) {
9434        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9435        synchronized (this) {
9436            final long ident = Binder.clearCallingIdentity();
9437            try {
9438                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9439            } finally {
9440                Binder.restoreCallingIdentity(ident);
9441            }
9442        }
9443    }
9444
9445    /**
9446     * TODO: Add mController hook
9447     */
9448    @Override
9449    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9450        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9451
9452        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9453        synchronized(this) {
9454            moveTaskToFrontLocked(taskId, flags, bOptions);
9455        }
9456    }
9457
9458    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9459        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9460
9461        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9462                Binder.getCallingUid(), -1, -1, "Task to front")) {
9463            ActivityOptions.abort(options);
9464            return;
9465        }
9466        final long origId = Binder.clearCallingIdentity();
9467        try {
9468            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9469            if (task == null) {
9470                Slog.d(TAG, "Could not find task for id: "+ taskId);
9471                return;
9472            }
9473            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9474                mStackSupervisor.showLockTaskToast();
9475                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9476                return;
9477            }
9478            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9479            if (prev != null && prev.isRecentsActivity()) {
9480                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9481            }
9482            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9483                    false /* forceNonResizable */);
9484        } finally {
9485            Binder.restoreCallingIdentity(origId);
9486        }
9487        ActivityOptions.abort(options);
9488    }
9489
9490    /**
9491     * Moves an activity, and all of the other activities within the same task, to the bottom
9492     * of the history stack.  The activity's order within the task is unchanged.
9493     *
9494     * @param token A reference to the activity we wish to move
9495     * @param nonRoot If false then this only works if the activity is the root
9496     *                of a task; if true it will work for any activity in a task.
9497     * @return Returns true if the move completed, false if not.
9498     */
9499    @Override
9500    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9501        enforceNotIsolatedCaller("moveActivityTaskToBack");
9502        synchronized(this) {
9503            final long origId = Binder.clearCallingIdentity();
9504            try {
9505                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9506                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9507                if (task != null) {
9508                    if (mStackSupervisor.isLockedTask(task)) {
9509                        mStackSupervisor.showLockTaskToast();
9510                        return false;
9511                    }
9512                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9513                }
9514            } finally {
9515                Binder.restoreCallingIdentity(origId);
9516            }
9517        }
9518        return false;
9519    }
9520
9521    @Override
9522    public void moveTaskBackwards(int task) {
9523        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9524                "moveTaskBackwards()");
9525
9526        synchronized(this) {
9527            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9528                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9529                return;
9530            }
9531            final long origId = Binder.clearCallingIdentity();
9532            moveTaskBackwardsLocked(task);
9533            Binder.restoreCallingIdentity(origId);
9534        }
9535    }
9536
9537    private final void moveTaskBackwardsLocked(int task) {
9538        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9539    }
9540
9541    @Override
9542    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9543            IActivityContainerCallback callback) throws RemoteException {
9544        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9545        synchronized (this) {
9546            if (parentActivityToken == null) {
9547                throw new IllegalArgumentException("parent token must not be null");
9548            }
9549            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9550            if (r == null) {
9551                return null;
9552            }
9553            if (callback == null) {
9554                throw new IllegalArgumentException("callback must not be null");
9555            }
9556            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9557        }
9558    }
9559
9560    @Override
9561    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9562        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9563        synchronized (this) {
9564            mStackSupervisor.deleteActivityContainer(container);
9565        }
9566    }
9567
9568    @Override
9569    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9570        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9571        synchronized (this) {
9572            final int stackId = mStackSupervisor.getNextStackId();
9573            final ActivityStack stack =
9574                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9575            if (stack == null) {
9576                return null;
9577            }
9578            return stack.mActivityContainer;
9579        }
9580    }
9581
9582    @Override
9583    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9584        synchronized (this) {
9585            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9586            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9587                return stack.mActivityContainer.getDisplayId();
9588            }
9589            return Display.DEFAULT_DISPLAY;
9590        }
9591    }
9592
9593    @Override
9594    public int getActivityStackId(IBinder token) throws RemoteException {
9595        synchronized (this) {
9596            ActivityStack stack = ActivityRecord.getStackLocked(token);
9597            if (stack == null) {
9598                return INVALID_STACK_ID;
9599            }
9600            return stack.mStackId;
9601        }
9602    }
9603
9604    @Override
9605    public void exitFreeformMode(IBinder token) throws RemoteException {
9606        synchronized (this) {
9607            long ident = Binder.clearCallingIdentity();
9608            try {
9609                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9610                if (r == null) {
9611                    throw new IllegalArgumentException(
9612                            "exitFreeformMode: No activity record matching token=" + token);
9613                }
9614                final ActivityStack stack = r.getStackLocked(token);
9615                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9616                    throw new IllegalStateException(
9617                            "exitFreeformMode: You can only go fullscreen from freeform.");
9618                }
9619                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9620                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9621                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9622            } finally {
9623                Binder.restoreCallingIdentity(ident);
9624            }
9625        }
9626    }
9627
9628    @Override
9629    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9630        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9631        if (stackId == HOME_STACK_ID) {
9632            throw new IllegalArgumentException(
9633                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9634        }
9635        synchronized (this) {
9636            long ident = Binder.clearCallingIdentity();
9637            try {
9638                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9639                        + " to stackId=" + stackId + " toTop=" + toTop);
9640                if (stackId == DOCKED_STACK_ID) {
9641                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9642                            null /* initialBounds */);
9643                }
9644                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9645                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9646                if (result && stackId == DOCKED_STACK_ID) {
9647                    // If task moved to docked stack - show recents if needed.
9648                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9649                            "moveTaskToDockedStack");
9650                }
9651            } finally {
9652                Binder.restoreCallingIdentity(ident);
9653            }
9654        }
9655    }
9656
9657    @Override
9658    public void swapDockedAndFullscreenStack() throws RemoteException {
9659        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9660        synchronized (this) {
9661            long ident = Binder.clearCallingIdentity();
9662            try {
9663                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9664                        FULLSCREEN_WORKSPACE_STACK_ID);
9665                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9666                        : null;
9667                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9668                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9669                        : null;
9670                if (topTask == null || tasks == null || tasks.size() == 0) {
9671                    Slog.w(TAG,
9672                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9673                    return;
9674                }
9675
9676                // TODO: App transition
9677                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9678
9679                // Defer the resume so resume/pausing while moving stacks is dangerous.
9680                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9681                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9682                        ANIMATE, true /* deferResume */);
9683                final int size = tasks.size();
9684                for (int i = 0; i < size; i++) {
9685                    final int id = tasks.get(i).taskId;
9686                    if (id == topTask.taskId) {
9687                        continue;
9688                    }
9689                    mStackSupervisor.moveTaskToStackLocked(id,
9690                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9691                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9692                }
9693
9694                // Because we deferred the resume, to avoid conflicts with stack switches while
9695                // resuming, we need to do it after all the tasks are moved.
9696                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9697                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9698
9699                mWindowManager.executeAppTransition();
9700            } finally {
9701                Binder.restoreCallingIdentity(ident);
9702            }
9703        }
9704    }
9705
9706    /**
9707     * Moves the input task to the docked stack.
9708     *
9709     * @param taskId Id of task to move.
9710     * @param createMode The mode the docked stack should be created in if it doesn't exist
9711     *                   already. See
9712     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9713     *                   and
9714     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9715     * @param toTop If the task and stack should be moved to the top.
9716     * @param animate Whether we should play an animation for the moving the task
9717     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9718     *                      docked stack. Pass {@code null} to use default bounds.
9719     */
9720    @Override
9721    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9722            Rect initialBounds, boolean moveHomeStackFront) {
9723        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9724        synchronized (this) {
9725            long ident = Binder.clearCallingIdentity();
9726            try {
9727                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9728                        + " to createMode=" + createMode + " toTop=" + toTop);
9729                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9730                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9731                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9732                        animate, DEFER_RESUME);
9733                if (moved) {
9734                    if (moveHomeStackFront) {
9735                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9736                    }
9737                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9738                }
9739                return moved;
9740            } finally {
9741                Binder.restoreCallingIdentity(ident);
9742            }
9743        }
9744    }
9745
9746    /**
9747     * Moves the top activity in the input stackId to the pinned stack.
9748     *
9749     * @param stackId Id of stack to move the top activity to pinned stack.
9750     * @param bounds Bounds to use for pinned stack.
9751     *
9752     * @return True if the top activity of the input stack was successfully moved to the pinned
9753     *          stack.
9754     */
9755    @Override
9756    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9757        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9758        synchronized (this) {
9759            if (!mSupportsPictureInPicture) {
9760                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9761                        + "Device doesn't support picture-in-pciture mode");
9762            }
9763
9764            long ident = Binder.clearCallingIdentity();
9765            try {
9766                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9767            } finally {
9768                Binder.restoreCallingIdentity(ident);
9769            }
9770        }
9771    }
9772
9773    @Override
9774    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9775            boolean preserveWindows, boolean animate, int animationDuration) {
9776        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9777        long ident = Binder.clearCallingIdentity();
9778        try {
9779            synchronized (this) {
9780                if (animate) {
9781                    if (stackId == PINNED_STACK_ID) {
9782                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9783                    } else {
9784                        throw new IllegalArgumentException("Stack: " + stackId
9785                                + " doesn't support animated resize.");
9786                    }
9787                } else {
9788                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9789                            null /* tempTaskInsetBounds */, preserveWindows,
9790                            allowResizeInDockedMode, !DEFER_RESUME);
9791                }
9792            }
9793        } finally {
9794            Binder.restoreCallingIdentity(ident);
9795        }
9796    }
9797
9798    @Override
9799    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9800            Rect tempDockedTaskInsetBounds,
9801            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9802        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9803                "resizeDockedStack()");
9804        long ident = Binder.clearCallingIdentity();
9805        try {
9806            synchronized (this) {
9807                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9808                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9809                        PRESERVE_WINDOWS);
9810            }
9811        } finally {
9812            Binder.restoreCallingIdentity(ident);
9813        }
9814    }
9815
9816    @Override
9817    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9818        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9819                "resizePinnedStack()");
9820        final long ident = Binder.clearCallingIdentity();
9821        try {
9822            synchronized (this) {
9823                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9824            }
9825        } finally {
9826            Binder.restoreCallingIdentity(ident);
9827        }
9828    }
9829
9830    @Override
9831    public void positionTaskInStack(int taskId, int stackId, int position) {
9832        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9833        if (stackId == HOME_STACK_ID) {
9834            throw new IllegalArgumentException(
9835                    "positionTaskInStack: Attempt to change the position of task "
9836                    + taskId + " in/to home stack");
9837        }
9838        synchronized (this) {
9839            long ident = Binder.clearCallingIdentity();
9840            try {
9841                if (DEBUG_STACK) Slog.d(TAG_STACK,
9842                        "positionTaskInStack: positioning task=" + taskId
9843                        + " in stackId=" + stackId + " at position=" + position);
9844                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9845            } finally {
9846                Binder.restoreCallingIdentity(ident);
9847            }
9848        }
9849    }
9850
9851    @Override
9852    public List<StackInfo> getAllStackInfos() {
9853        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9854        long ident = Binder.clearCallingIdentity();
9855        try {
9856            synchronized (this) {
9857                return mStackSupervisor.getAllStackInfosLocked();
9858            }
9859        } finally {
9860            Binder.restoreCallingIdentity(ident);
9861        }
9862    }
9863
9864    @Override
9865    public StackInfo getStackInfo(int stackId) {
9866        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9867        long ident = Binder.clearCallingIdentity();
9868        try {
9869            synchronized (this) {
9870                return mStackSupervisor.getStackInfoLocked(stackId);
9871            }
9872        } finally {
9873            Binder.restoreCallingIdentity(ident);
9874        }
9875    }
9876
9877    @Override
9878    public boolean isInHomeStack(int taskId) {
9879        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9880        long ident = Binder.clearCallingIdentity();
9881        try {
9882            synchronized (this) {
9883                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9884                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9885                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9886            }
9887        } finally {
9888            Binder.restoreCallingIdentity(ident);
9889        }
9890    }
9891
9892    @Override
9893    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9894        synchronized(this) {
9895            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9896        }
9897    }
9898
9899    @Override
9900    public void updateDeviceOwner(String packageName) {
9901        final int callingUid = Binder.getCallingUid();
9902        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9903            throw new SecurityException("updateDeviceOwner called from non-system process");
9904        }
9905        synchronized (this) {
9906            mDeviceOwnerName = packageName;
9907        }
9908    }
9909
9910    @Override
9911    public void updateLockTaskPackages(int userId, String[] packages) {
9912        final int callingUid = Binder.getCallingUid();
9913        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9914            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9915                    "updateLockTaskPackages()");
9916        }
9917        synchronized (this) {
9918            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9919                    Arrays.toString(packages));
9920            mLockTaskPackages.put(userId, packages);
9921            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9922        }
9923    }
9924
9925
9926    void startLockTaskModeLocked(TaskRecord task) {
9927        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9928        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9929            return;
9930        }
9931
9932        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9933        // is initiated by system after the pinning request was shown and locked mode is initiated
9934        // by an authorized app directly
9935        final int callingUid = Binder.getCallingUid();
9936        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9937        long ident = Binder.clearCallingIdentity();
9938        try {
9939            if (!isSystemInitiated) {
9940                task.mLockTaskUid = callingUid;
9941                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9942                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9943                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9944                    StatusBarManagerInternal statusBarManager =
9945                            LocalServices.getService(StatusBarManagerInternal.class);
9946                    if (statusBarManager != null) {
9947                        statusBarManager.showScreenPinningRequest(task.taskId);
9948                    }
9949                    return;
9950                }
9951
9952                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9953                if (stack == null || task != stack.topTask()) {
9954                    throw new IllegalArgumentException("Invalid task, not in foreground");
9955                }
9956            }
9957            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9958                    "Locking fully");
9959            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9960                    ActivityManager.LOCK_TASK_MODE_PINNED :
9961                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9962                    "startLockTask", true);
9963        } finally {
9964            Binder.restoreCallingIdentity(ident);
9965        }
9966    }
9967
9968    @Override
9969    public void startLockTaskMode(int taskId) {
9970        synchronized (this) {
9971            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9972            if (task != null) {
9973                startLockTaskModeLocked(task);
9974            }
9975        }
9976    }
9977
9978    @Override
9979    public void startLockTaskMode(IBinder token) {
9980        synchronized (this) {
9981            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9982            if (r == null) {
9983                return;
9984            }
9985            final TaskRecord task = r.task;
9986            if (task != null) {
9987                startLockTaskModeLocked(task);
9988            }
9989        }
9990    }
9991
9992    @Override
9993    public void startSystemLockTaskMode(int taskId) throws RemoteException {
9994        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
9995        // This makes inner call to look as if it was initiated by system.
9996        long ident = Binder.clearCallingIdentity();
9997        try {
9998            synchronized (this) {
9999                startLockTaskMode(taskId);
10000            }
10001        } finally {
10002            Binder.restoreCallingIdentity(ident);
10003        }
10004    }
10005
10006    @Override
10007    public void stopLockTaskMode() {
10008        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10009        if (lockTask == null) {
10010            // Our work here is done.
10011            return;
10012        }
10013
10014        final int callingUid = Binder.getCallingUid();
10015        final int lockTaskUid = lockTask.mLockTaskUid;
10016        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10017        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10018            // Done.
10019            return;
10020        } else {
10021            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10022            // It is possible lockTaskMode was started by the system process because
10023            // android:lockTaskMode is set to a locking value in the application manifest
10024            // instead of the app calling startLockTaskMode. In this case
10025            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10026            // {@link TaskRecord.effectiveUid} instead. Also caller with
10027            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10028            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10029                    && callingUid != lockTaskUid
10030                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10031                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10032                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10033            }
10034        }
10035        long ident = Binder.clearCallingIdentity();
10036        try {
10037            Log.d(TAG, "stopLockTaskMode");
10038            // Stop lock task
10039            synchronized (this) {
10040                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10041                        "stopLockTask", true);
10042            }
10043        } finally {
10044            Binder.restoreCallingIdentity(ident);
10045        }
10046    }
10047
10048    /**
10049     * This API should be called by SystemUI only when user perform certain action to dismiss
10050     * lock task mode. We should only dismiss pinned lock task mode in this case.
10051     */
10052    @Override
10053    public void stopSystemLockTaskMode() throws RemoteException {
10054        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10055            stopLockTaskMode();
10056        } else {
10057            mStackSupervisor.showLockTaskToast();
10058        }
10059    }
10060
10061    @Override
10062    public boolean isInLockTaskMode() {
10063        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10064    }
10065
10066    @Override
10067    public int getLockTaskModeState() {
10068        synchronized (this) {
10069            return mStackSupervisor.getLockTaskModeState();
10070        }
10071    }
10072
10073    @Override
10074    public void showLockTaskEscapeMessage(IBinder token) {
10075        synchronized (this) {
10076            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10077            if (r == null) {
10078                return;
10079            }
10080            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10081        }
10082    }
10083
10084    // =========================================================
10085    // CONTENT PROVIDERS
10086    // =========================================================
10087
10088    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10089        List<ProviderInfo> providers = null;
10090        try {
10091            providers = AppGlobals.getPackageManager()
10092                    .queryContentProviders(app.processName, app.uid,
10093                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10094                                    | MATCH_DEBUG_TRIAGED_MISSING)
10095                    .getList();
10096        } catch (RemoteException ex) {
10097        }
10098        if (DEBUG_MU) Slog.v(TAG_MU,
10099                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10100        int userId = app.userId;
10101        if (providers != null) {
10102            int N = providers.size();
10103            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10104            for (int i=0; i<N; i++) {
10105                ProviderInfo cpi =
10106                    (ProviderInfo)providers.get(i);
10107                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10108                        cpi.name, cpi.flags);
10109                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10110                    // This is a singleton provider, but a user besides the
10111                    // default user is asking to initialize a process it runs
10112                    // in...  well, no, it doesn't actually run in this process,
10113                    // it runs in the process of the default user.  Get rid of it.
10114                    providers.remove(i);
10115                    N--;
10116                    i--;
10117                    continue;
10118                }
10119
10120                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10121                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10122                if (cpr == null) {
10123                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10124                    mProviderMap.putProviderByClass(comp, cpr);
10125                }
10126                if (DEBUG_MU) Slog.v(TAG_MU,
10127                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10128                app.pubProviders.put(cpi.name, cpr);
10129                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10130                    // Don't add this if it is a platform component that is marked
10131                    // to run in multiple processes, because this is actually
10132                    // part of the framework so doesn't make sense to track as a
10133                    // separate apk in the process.
10134                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10135                            mProcessStats);
10136                }
10137                notifyPackageUse(cpi.applicationInfo.packageName,
10138                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10139            }
10140        }
10141        return providers;
10142    }
10143
10144    /**
10145     * Check if {@link ProcessRecord} has a possible chance at accessing the
10146     * given {@link ProviderInfo}. Final permission checking is always done
10147     * in {@link ContentProvider}.
10148     */
10149    private final String checkContentProviderPermissionLocked(
10150            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10151        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10152        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10153        boolean checkedGrants = false;
10154        if (checkUser) {
10155            // Looking for cross-user grants before enforcing the typical cross-users permissions
10156            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10157            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10158                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10159                    return null;
10160                }
10161                checkedGrants = true;
10162            }
10163            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10164                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10165            if (userId != tmpTargetUserId) {
10166                // When we actually went to determine the final targer user ID, this ended
10167                // up different than our initial check for the authority.  This is because
10168                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10169                // SELF.  So we need to re-check the grants again.
10170                checkedGrants = false;
10171            }
10172        }
10173        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10174                cpi.applicationInfo.uid, cpi.exported)
10175                == PackageManager.PERMISSION_GRANTED) {
10176            return null;
10177        }
10178        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10179                cpi.applicationInfo.uid, cpi.exported)
10180                == PackageManager.PERMISSION_GRANTED) {
10181            return null;
10182        }
10183
10184        PathPermission[] pps = cpi.pathPermissions;
10185        if (pps != null) {
10186            int i = pps.length;
10187            while (i > 0) {
10188                i--;
10189                PathPermission pp = pps[i];
10190                String pprperm = pp.getReadPermission();
10191                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10192                        cpi.applicationInfo.uid, cpi.exported)
10193                        == PackageManager.PERMISSION_GRANTED) {
10194                    return null;
10195                }
10196                String ppwperm = pp.getWritePermission();
10197                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10198                        cpi.applicationInfo.uid, cpi.exported)
10199                        == PackageManager.PERMISSION_GRANTED) {
10200                    return null;
10201                }
10202            }
10203        }
10204        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10205            return null;
10206        }
10207
10208        String msg;
10209        if (!cpi.exported) {
10210            msg = "Permission Denial: opening provider " + cpi.name
10211                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10212                    + ", uid=" + callingUid + ") that is not exported from uid "
10213                    + cpi.applicationInfo.uid;
10214        } else {
10215            msg = "Permission Denial: opening provider " + cpi.name
10216                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10217                    + ", uid=" + callingUid + ") requires "
10218                    + cpi.readPermission + " or " + cpi.writePermission;
10219        }
10220        Slog.w(TAG, msg);
10221        return msg;
10222    }
10223
10224    /**
10225     * Returns if the ContentProvider has granted a uri to callingUid
10226     */
10227    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10228        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10229        if (perms != null) {
10230            for (int i=perms.size()-1; i>=0; i--) {
10231                GrantUri grantUri = perms.keyAt(i);
10232                if (grantUri.sourceUserId == userId || !checkUser) {
10233                    if (matchesProvider(grantUri.uri, cpi)) {
10234                        return true;
10235                    }
10236                }
10237            }
10238        }
10239        return false;
10240    }
10241
10242    /**
10243     * Returns true if the uri authority is one of the authorities specified in the provider.
10244     */
10245    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10246        String uriAuth = uri.getAuthority();
10247        String cpiAuth = cpi.authority;
10248        if (cpiAuth.indexOf(';') == -1) {
10249            return cpiAuth.equals(uriAuth);
10250        }
10251        String[] cpiAuths = cpiAuth.split(";");
10252        int length = cpiAuths.length;
10253        for (int i = 0; i < length; i++) {
10254            if (cpiAuths[i].equals(uriAuth)) return true;
10255        }
10256        return false;
10257    }
10258
10259    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10260            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10261        if (r != null) {
10262            for (int i=0; i<r.conProviders.size(); i++) {
10263                ContentProviderConnection conn = r.conProviders.get(i);
10264                if (conn.provider == cpr) {
10265                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10266                            "Adding provider requested by "
10267                            + r.processName + " from process "
10268                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10269                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10270                    if (stable) {
10271                        conn.stableCount++;
10272                        conn.numStableIncs++;
10273                    } else {
10274                        conn.unstableCount++;
10275                        conn.numUnstableIncs++;
10276                    }
10277                    return conn;
10278                }
10279            }
10280            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10281            if (stable) {
10282                conn.stableCount = 1;
10283                conn.numStableIncs = 1;
10284            } else {
10285                conn.unstableCount = 1;
10286                conn.numUnstableIncs = 1;
10287            }
10288            cpr.connections.add(conn);
10289            r.conProviders.add(conn);
10290            startAssociationLocked(r.uid, r.processName, r.curProcState,
10291                    cpr.uid, cpr.name, cpr.info.processName);
10292            return conn;
10293        }
10294        cpr.addExternalProcessHandleLocked(externalProcessToken);
10295        return null;
10296    }
10297
10298    boolean decProviderCountLocked(ContentProviderConnection conn,
10299            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10300        if (conn != null) {
10301            cpr = conn.provider;
10302            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10303                    "Removing provider requested by "
10304                    + conn.client.processName + " from process "
10305                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10306                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10307            if (stable) {
10308                conn.stableCount--;
10309            } else {
10310                conn.unstableCount--;
10311            }
10312            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10313                cpr.connections.remove(conn);
10314                conn.client.conProviders.remove(conn);
10315                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10316                    // The client is more important than last activity -- note the time this
10317                    // is happening, so we keep the old provider process around a bit as last
10318                    // activity to avoid thrashing it.
10319                    if (cpr.proc != null) {
10320                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10321                    }
10322                }
10323                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10324                return true;
10325            }
10326            return false;
10327        }
10328        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10329        return false;
10330    }
10331
10332    private void checkTime(long startTime, String where) {
10333        long now = SystemClock.uptimeMillis();
10334        if ((now-startTime) > 50) {
10335            // If we are taking more than 50ms, log about it.
10336            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10337        }
10338    }
10339
10340    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10341            String name, IBinder token, boolean stable, int userId) {
10342        ContentProviderRecord cpr;
10343        ContentProviderConnection conn = null;
10344        ProviderInfo cpi = null;
10345
10346        synchronized(this) {
10347            long startTime = SystemClock.uptimeMillis();
10348
10349            ProcessRecord r = null;
10350            if (caller != null) {
10351                r = getRecordForAppLocked(caller);
10352                if (r == null) {
10353                    throw new SecurityException(
10354                            "Unable to find app for caller " + caller
10355                          + " (pid=" + Binder.getCallingPid()
10356                          + ") when getting content provider " + name);
10357                }
10358            }
10359
10360            boolean checkCrossUser = true;
10361
10362            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10363
10364            // First check if this content provider has been published...
10365            cpr = mProviderMap.getProviderByName(name, userId);
10366            // If that didn't work, check if it exists for user 0 and then
10367            // verify that it's a singleton provider before using it.
10368            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10369                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10370                if (cpr != null) {
10371                    cpi = cpr.info;
10372                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10373                            cpi.name, cpi.flags)
10374                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10375                        userId = UserHandle.USER_SYSTEM;
10376                        checkCrossUser = false;
10377                    } else {
10378                        cpr = null;
10379                        cpi = null;
10380                    }
10381                }
10382            }
10383
10384            boolean providerRunning = cpr != null;
10385            if (providerRunning) {
10386                cpi = cpr.info;
10387                String msg;
10388                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10389                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10390                        != null) {
10391                    throw new SecurityException(msg);
10392                }
10393                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10394
10395                if (r != null && cpr.canRunHere(r)) {
10396                    // This provider has been published or is in the process
10397                    // of being published...  but it is also allowed to run
10398                    // in the caller's process, so don't make a connection
10399                    // and just let the caller instantiate its own instance.
10400                    ContentProviderHolder holder = cpr.newHolder(null);
10401                    // don't give caller the provider object, it needs
10402                    // to make its own.
10403                    holder.provider = null;
10404                    return holder;
10405                }
10406
10407                final long origId = Binder.clearCallingIdentity();
10408
10409                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10410
10411                // In this case the provider instance already exists, so we can
10412                // return it right away.
10413                conn = incProviderCountLocked(r, cpr, token, stable);
10414                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10415                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10416                        // If this is a perceptible app accessing the provider,
10417                        // make sure to count it as being accessed and thus
10418                        // back up on the LRU list.  This is good because
10419                        // content providers are often expensive to start.
10420                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10421                        updateLruProcessLocked(cpr.proc, false, null);
10422                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10423                    }
10424                }
10425
10426                if (cpr.proc != null) {
10427                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10428                    boolean success = updateOomAdjLocked(cpr.proc);
10429                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10430                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10431                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10432                    // NOTE: there is still a race here where a signal could be
10433                    // pending on the process even though we managed to update its
10434                    // adj level.  Not sure what to do about this, but at least
10435                    // the race is now smaller.
10436                    if (!success) {
10437                        // Uh oh...  it looks like the provider's process
10438                        // has been killed on us.  We need to wait for a new
10439                        // process to be started, and make sure its death
10440                        // doesn't kill our process.
10441                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10442                                + " is crashing; detaching " + r);
10443                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10444                        checkTime(startTime, "getContentProviderImpl: before appDied");
10445                        appDiedLocked(cpr.proc);
10446                        checkTime(startTime, "getContentProviderImpl: after appDied");
10447                        if (!lastRef) {
10448                            // This wasn't the last ref our process had on
10449                            // the provider...  we have now been killed, bail.
10450                            return null;
10451                        }
10452                        providerRunning = false;
10453                        conn = null;
10454                    }
10455                }
10456
10457                Binder.restoreCallingIdentity(origId);
10458            }
10459
10460            if (!providerRunning) {
10461                try {
10462                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10463                    cpi = AppGlobals.getPackageManager().
10464                        resolveContentProvider(name,
10465                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10466                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10467                } catch (RemoteException ex) {
10468                }
10469                if (cpi == null) {
10470                    return null;
10471                }
10472                // If the provider is a singleton AND
10473                // (it's a call within the same user || the provider is a
10474                // privileged app)
10475                // Then allow connecting to the singleton provider
10476                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10477                        cpi.name, cpi.flags)
10478                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10479                if (singleton) {
10480                    userId = UserHandle.USER_SYSTEM;
10481                }
10482                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10483                checkTime(startTime, "getContentProviderImpl: got app info for user");
10484
10485                String msg;
10486                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10487                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10488                        != null) {
10489                    throw new SecurityException(msg);
10490                }
10491                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10492
10493                if (!mProcessesReady
10494                        && !cpi.processName.equals("system")) {
10495                    // If this content provider does not run in the system
10496                    // process, and the system is not yet ready to run other
10497                    // processes, then fail fast instead of hanging.
10498                    throw new IllegalArgumentException(
10499                            "Attempt to launch content provider before system ready");
10500                }
10501
10502                // Make sure that the user who owns this provider is running.  If not,
10503                // we don't want to allow it to run.
10504                if (!mUserController.isUserRunningLocked(userId, 0)) {
10505                    Slog.w(TAG, "Unable to launch app "
10506                            + cpi.applicationInfo.packageName + "/"
10507                            + cpi.applicationInfo.uid + " for provider "
10508                            + name + ": user " + userId + " is stopped");
10509                    return null;
10510                }
10511
10512                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10513                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10514                cpr = mProviderMap.getProviderByClass(comp, userId);
10515                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10516                final boolean firstClass = cpr == null;
10517                if (firstClass) {
10518                    final long ident = Binder.clearCallingIdentity();
10519
10520                    // If permissions need a review before any of the app components can run,
10521                    // we return no provider and launch a review activity if the calling app
10522                    // is in the foreground.
10523                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10524                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10525                            return null;
10526                        }
10527                    }
10528
10529                    try {
10530                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10531                        ApplicationInfo ai =
10532                            AppGlobals.getPackageManager().
10533                                getApplicationInfo(
10534                                        cpi.applicationInfo.packageName,
10535                                        STOCK_PM_FLAGS, userId);
10536                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10537                        if (ai == null) {
10538                            Slog.w(TAG, "No package info for content provider "
10539                                    + cpi.name);
10540                            return null;
10541                        }
10542                        ai = getAppInfoForUser(ai, userId);
10543                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10544                    } catch (RemoteException ex) {
10545                        // pm is in same process, this will never happen.
10546                    } finally {
10547                        Binder.restoreCallingIdentity(ident);
10548                    }
10549                }
10550
10551                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10552
10553                if (r != null && cpr.canRunHere(r)) {
10554                    // If this is a multiprocess provider, then just return its
10555                    // info and allow the caller to instantiate it.  Only do
10556                    // this if the provider is the same user as the caller's
10557                    // process, or can run as root (so can be in any process).
10558                    return cpr.newHolder(null);
10559                }
10560
10561                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10562                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10563                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10564
10565                // This is single process, and our app is now connecting to it.
10566                // See if we are already in the process of launching this
10567                // provider.
10568                final int N = mLaunchingProviders.size();
10569                int i;
10570                for (i = 0; i < N; i++) {
10571                    if (mLaunchingProviders.get(i) == cpr) {
10572                        break;
10573                    }
10574                }
10575
10576                // If the provider is not already being launched, then get it
10577                // started.
10578                if (i >= N) {
10579                    final long origId = Binder.clearCallingIdentity();
10580
10581                    try {
10582                        // Content provider is now in use, its package can't be stopped.
10583                        try {
10584                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10585                            AppGlobals.getPackageManager().setPackageStoppedState(
10586                                    cpr.appInfo.packageName, false, userId);
10587                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10588                        } catch (RemoteException e) {
10589                        } catch (IllegalArgumentException e) {
10590                            Slog.w(TAG, "Failed trying to unstop package "
10591                                    + cpr.appInfo.packageName + ": " + e);
10592                        }
10593
10594                        // Use existing process if already started
10595                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10596                        ProcessRecord proc = getProcessRecordLocked(
10597                                cpi.processName, cpr.appInfo.uid, false);
10598                        if (proc != null && proc.thread != null) {
10599                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10600                                    "Installing in existing process " + proc);
10601                            if (!proc.pubProviders.containsKey(cpi.name)) {
10602                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10603                                proc.pubProviders.put(cpi.name, cpr);
10604                                try {
10605                                    proc.thread.scheduleInstallProvider(cpi);
10606                                } catch (RemoteException e) {
10607                                }
10608                            }
10609                        } else {
10610                            checkTime(startTime, "getContentProviderImpl: before start process");
10611                            proc = startProcessLocked(cpi.processName,
10612                                    cpr.appInfo, false, 0, "content provider",
10613                                    new ComponentName(cpi.applicationInfo.packageName,
10614                                            cpi.name), false, false, false);
10615                            checkTime(startTime, "getContentProviderImpl: after start process");
10616                            if (proc == null) {
10617                                Slog.w(TAG, "Unable to launch app "
10618                                        + cpi.applicationInfo.packageName + "/"
10619                                        + cpi.applicationInfo.uid + " for provider "
10620                                        + name + ": process is bad");
10621                                return null;
10622                            }
10623                        }
10624                        cpr.launchingApp = proc;
10625                        mLaunchingProviders.add(cpr);
10626                    } finally {
10627                        Binder.restoreCallingIdentity(origId);
10628                    }
10629                }
10630
10631                checkTime(startTime, "getContentProviderImpl: updating data structures");
10632
10633                // Make sure the provider is published (the same provider class
10634                // may be published under multiple names).
10635                if (firstClass) {
10636                    mProviderMap.putProviderByClass(comp, cpr);
10637                }
10638
10639                mProviderMap.putProviderByName(name, cpr);
10640                conn = incProviderCountLocked(r, cpr, token, stable);
10641                if (conn != null) {
10642                    conn.waiting = true;
10643                }
10644            }
10645            checkTime(startTime, "getContentProviderImpl: done!");
10646        }
10647
10648        // Wait for the provider to be published...
10649        synchronized (cpr) {
10650            while (cpr.provider == null) {
10651                if (cpr.launchingApp == null) {
10652                    Slog.w(TAG, "Unable to launch app "
10653                            + cpi.applicationInfo.packageName + "/"
10654                            + cpi.applicationInfo.uid + " for provider "
10655                            + name + ": launching app became null");
10656                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10657                            UserHandle.getUserId(cpi.applicationInfo.uid),
10658                            cpi.applicationInfo.packageName,
10659                            cpi.applicationInfo.uid, name);
10660                    return null;
10661                }
10662                try {
10663                    if (DEBUG_MU) Slog.v(TAG_MU,
10664                            "Waiting to start provider " + cpr
10665                            + " launchingApp=" + cpr.launchingApp);
10666                    if (conn != null) {
10667                        conn.waiting = true;
10668                    }
10669                    cpr.wait();
10670                } catch (InterruptedException ex) {
10671                } finally {
10672                    if (conn != null) {
10673                        conn.waiting = false;
10674                    }
10675                }
10676            }
10677        }
10678        return cpr != null ? cpr.newHolder(conn) : null;
10679    }
10680
10681    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10682            ProcessRecord r, final int userId) {
10683        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10684                cpi.packageName, userId)) {
10685
10686            final boolean callerForeground = r == null || r.setSchedGroup
10687                    != ProcessList.SCHED_GROUP_BACKGROUND;
10688
10689            // Show a permission review UI only for starting from a foreground app
10690            if (!callerForeground) {
10691                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10692                        + cpi.packageName + " requires a permissions review");
10693                return false;
10694            }
10695
10696            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10697            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10698                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10699            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10700
10701            if (DEBUG_PERMISSIONS_REVIEW) {
10702                Slog.i(TAG, "u" + userId + " Launching permission review "
10703                        + "for package " + cpi.packageName);
10704            }
10705
10706            final UserHandle userHandle = new UserHandle(userId);
10707            mHandler.post(new Runnable() {
10708                @Override
10709                public void run() {
10710                    mContext.startActivityAsUser(intent, userHandle);
10711                }
10712            });
10713
10714            return false;
10715        }
10716
10717        return true;
10718    }
10719
10720    PackageManagerInternal getPackageManagerInternalLocked() {
10721        if (mPackageManagerInt == null) {
10722            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10723        }
10724        return mPackageManagerInt;
10725    }
10726
10727    @Override
10728    public final ContentProviderHolder getContentProvider(
10729            IApplicationThread caller, String name, int userId, boolean stable) {
10730        enforceNotIsolatedCaller("getContentProvider");
10731        if (caller == null) {
10732            String msg = "null IApplicationThread when getting content provider "
10733                    + name;
10734            Slog.w(TAG, msg);
10735            throw new SecurityException(msg);
10736        }
10737        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10738        // with cross-user grant.
10739        return getContentProviderImpl(caller, name, null, stable, userId);
10740    }
10741
10742    public ContentProviderHolder getContentProviderExternal(
10743            String name, int userId, IBinder token) {
10744        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10745            "Do not have permission in call getContentProviderExternal()");
10746        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10747                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10748        return getContentProviderExternalUnchecked(name, token, userId);
10749    }
10750
10751    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10752            IBinder token, int userId) {
10753        return getContentProviderImpl(null, name, token, true, userId);
10754    }
10755
10756    /**
10757     * Drop a content provider from a ProcessRecord's bookkeeping
10758     */
10759    public void removeContentProvider(IBinder connection, boolean stable) {
10760        enforceNotIsolatedCaller("removeContentProvider");
10761        long ident = Binder.clearCallingIdentity();
10762        try {
10763            synchronized (this) {
10764                ContentProviderConnection conn;
10765                try {
10766                    conn = (ContentProviderConnection)connection;
10767                } catch (ClassCastException e) {
10768                    String msg ="removeContentProvider: " + connection
10769                            + " not a ContentProviderConnection";
10770                    Slog.w(TAG, msg);
10771                    throw new IllegalArgumentException(msg);
10772                }
10773                if (conn == null) {
10774                    throw new NullPointerException("connection is null");
10775                }
10776                if (decProviderCountLocked(conn, null, null, stable)) {
10777                    updateOomAdjLocked();
10778                }
10779            }
10780        } finally {
10781            Binder.restoreCallingIdentity(ident);
10782        }
10783    }
10784
10785    public void removeContentProviderExternal(String name, IBinder token) {
10786        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10787            "Do not have permission in call removeContentProviderExternal()");
10788        int userId = UserHandle.getCallingUserId();
10789        long ident = Binder.clearCallingIdentity();
10790        try {
10791            removeContentProviderExternalUnchecked(name, token, userId);
10792        } finally {
10793            Binder.restoreCallingIdentity(ident);
10794        }
10795    }
10796
10797    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10798        synchronized (this) {
10799            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10800            if(cpr == null) {
10801                //remove from mProvidersByClass
10802                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10803                return;
10804            }
10805
10806            //update content provider record entry info
10807            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10808            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10809            if (localCpr.hasExternalProcessHandles()) {
10810                if (localCpr.removeExternalProcessHandleLocked(token)) {
10811                    updateOomAdjLocked();
10812                } else {
10813                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10814                            + " with no external reference for token: "
10815                            + token + ".");
10816                }
10817            } else {
10818                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10819                        + " with no external references.");
10820            }
10821        }
10822    }
10823
10824    public final void publishContentProviders(IApplicationThread caller,
10825            List<ContentProviderHolder> providers) {
10826        if (providers == null) {
10827            return;
10828        }
10829
10830        enforceNotIsolatedCaller("publishContentProviders");
10831        synchronized (this) {
10832            final ProcessRecord r = getRecordForAppLocked(caller);
10833            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10834            if (r == null) {
10835                throw new SecurityException(
10836                        "Unable to find app for caller " + caller
10837                      + " (pid=" + Binder.getCallingPid()
10838                      + ") when publishing content providers");
10839            }
10840
10841            final long origId = Binder.clearCallingIdentity();
10842
10843            final int N = providers.size();
10844            for (int i = 0; i < N; i++) {
10845                ContentProviderHolder src = providers.get(i);
10846                if (src == null || src.info == null || src.provider == null) {
10847                    continue;
10848                }
10849                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10850                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10851                if (dst != null) {
10852                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10853                    mProviderMap.putProviderByClass(comp, dst);
10854                    String names[] = dst.info.authority.split(";");
10855                    for (int j = 0; j < names.length; j++) {
10856                        mProviderMap.putProviderByName(names[j], dst);
10857                    }
10858
10859                    int launchingCount = mLaunchingProviders.size();
10860                    int j;
10861                    boolean wasInLaunchingProviders = false;
10862                    for (j = 0; j < launchingCount; j++) {
10863                        if (mLaunchingProviders.get(j) == dst) {
10864                            mLaunchingProviders.remove(j);
10865                            wasInLaunchingProviders = true;
10866                            j--;
10867                            launchingCount--;
10868                        }
10869                    }
10870                    if (wasInLaunchingProviders) {
10871                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10872                    }
10873                    synchronized (dst) {
10874                        dst.provider = src.provider;
10875                        dst.proc = r;
10876                        dst.notifyAll();
10877                    }
10878                    updateOomAdjLocked(r);
10879                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10880                            src.info.authority);
10881                }
10882            }
10883
10884            Binder.restoreCallingIdentity(origId);
10885        }
10886    }
10887
10888    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10889        ContentProviderConnection conn;
10890        try {
10891            conn = (ContentProviderConnection)connection;
10892        } catch (ClassCastException e) {
10893            String msg ="refContentProvider: " + connection
10894                    + " not a ContentProviderConnection";
10895            Slog.w(TAG, msg);
10896            throw new IllegalArgumentException(msg);
10897        }
10898        if (conn == null) {
10899            throw new NullPointerException("connection is null");
10900        }
10901
10902        synchronized (this) {
10903            if (stable > 0) {
10904                conn.numStableIncs += stable;
10905            }
10906            stable = conn.stableCount + stable;
10907            if (stable < 0) {
10908                throw new IllegalStateException("stableCount < 0: " + stable);
10909            }
10910
10911            if (unstable > 0) {
10912                conn.numUnstableIncs += unstable;
10913            }
10914            unstable = conn.unstableCount + unstable;
10915            if (unstable < 0) {
10916                throw new IllegalStateException("unstableCount < 0: " + unstable);
10917            }
10918
10919            if ((stable+unstable) <= 0) {
10920                throw new IllegalStateException("ref counts can't go to zero here: stable="
10921                        + stable + " unstable=" + unstable);
10922            }
10923            conn.stableCount = stable;
10924            conn.unstableCount = unstable;
10925            return !conn.dead;
10926        }
10927    }
10928
10929    public void unstableProviderDied(IBinder connection) {
10930        ContentProviderConnection conn;
10931        try {
10932            conn = (ContentProviderConnection)connection;
10933        } catch (ClassCastException e) {
10934            String msg ="refContentProvider: " + connection
10935                    + " not a ContentProviderConnection";
10936            Slog.w(TAG, msg);
10937            throw new IllegalArgumentException(msg);
10938        }
10939        if (conn == null) {
10940            throw new NullPointerException("connection is null");
10941        }
10942
10943        // Safely retrieve the content provider associated with the connection.
10944        IContentProvider provider;
10945        synchronized (this) {
10946            provider = conn.provider.provider;
10947        }
10948
10949        if (provider == null) {
10950            // Um, yeah, we're way ahead of you.
10951            return;
10952        }
10953
10954        // Make sure the caller is being honest with us.
10955        if (provider.asBinder().pingBinder()) {
10956            // Er, no, still looks good to us.
10957            synchronized (this) {
10958                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10959                        + " says " + conn + " died, but we don't agree");
10960                return;
10961            }
10962        }
10963
10964        // Well look at that!  It's dead!
10965        synchronized (this) {
10966            if (conn.provider.provider != provider) {
10967                // But something changed...  good enough.
10968                return;
10969            }
10970
10971            ProcessRecord proc = conn.provider.proc;
10972            if (proc == null || proc.thread == null) {
10973                // Seems like the process is already cleaned up.
10974                return;
10975            }
10976
10977            // As far as we're concerned, this is just like receiving a
10978            // death notification...  just a bit prematurely.
10979            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10980                    + ") early provider death");
10981            final long ident = Binder.clearCallingIdentity();
10982            try {
10983                appDiedLocked(proc);
10984            } finally {
10985                Binder.restoreCallingIdentity(ident);
10986            }
10987        }
10988    }
10989
10990    @Override
10991    public void appNotRespondingViaProvider(IBinder connection) {
10992        enforceCallingPermission(
10993                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10994
10995        final ContentProviderConnection conn = (ContentProviderConnection) connection;
10996        if (conn == null) {
10997            Slog.w(TAG, "ContentProviderConnection is null");
10998            return;
10999        }
11000
11001        final ProcessRecord host = conn.provider.proc;
11002        if (host == null) {
11003            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11004            return;
11005        }
11006
11007        mHandler.post(new Runnable() {
11008            @Override
11009            public void run() {
11010                mAppErrors.appNotResponding(host, null, null, false,
11011                        "ContentProvider not responding");
11012            }
11013        });
11014    }
11015
11016    public final void installSystemProviders() {
11017        List<ProviderInfo> providers;
11018        synchronized (this) {
11019            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11020            providers = generateApplicationProvidersLocked(app);
11021            if (providers != null) {
11022                for (int i=providers.size()-1; i>=0; i--) {
11023                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11024                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11025                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11026                                + ": not system .apk");
11027                        providers.remove(i);
11028                    }
11029                }
11030            }
11031        }
11032        if (providers != null) {
11033            mSystemThread.installSystemProviders(providers);
11034        }
11035
11036        mCoreSettingsObserver = new CoreSettingsObserver(this);
11037        mFontScaleSettingObserver = new FontScaleSettingObserver();
11038
11039        //mUsageStatsService.monitorPackages();
11040    }
11041
11042    private void startPersistentApps(int matchFlags) {
11043        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11044
11045        synchronized (this) {
11046            try {
11047                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11048                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11049                for (ApplicationInfo app : apps) {
11050                    if (!"android".equals(app.packageName)) {
11051                        addAppLocked(app, false, null /* ABI override */);
11052                    }
11053                }
11054            } catch (RemoteException ex) {
11055            }
11056        }
11057    }
11058
11059    /**
11060     * When a user is unlocked, we need to install encryption-unaware providers
11061     * belonging to any running apps.
11062     */
11063    private void installEncryptionUnawareProviders(int userId) {
11064        // We're only interested in providers that are encryption unaware, and
11065        // we don't care about uninstalled apps, since there's no way they're
11066        // running at this point.
11067        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11068
11069        synchronized (this) {
11070            final int NP = mProcessNames.getMap().size();
11071            for (int ip = 0; ip < NP; ip++) {
11072                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11073                final int NA = apps.size();
11074                for (int ia = 0; ia < NA; ia++) {
11075                    final ProcessRecord app = apps.valueAt(ia);
11076                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11077
11078                    final int NG = app.pkgList.size();
11079                    for (int ig = 0; ig < NG; ig++) {
11080                        try {
11081                            final String pkgName = app.pkgList.keyAt(ig);
11082                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11083                                    .getPackageInfo(pkgName, matchFlags, userId);
11084                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11085                                for (ProviderInfo provInfo : pkgInfo.providers) {
11086                                    Log.v(TAG, "Installing " + provInfo);
11087                                    app.thread.scheduleInstallProvider(provInfo);
11088                                }
11089                            }
11090                        } catch (RemoteException ignored) {
11091                        }
11092                    }
11093                }
11094            }
11095        }
11096    }
11097
11098    /**
11099     * Allows apps to retrieve the MIME type of a URI.
11100     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11101     * users, then it does not need permission to access the ContentProvider.
11102     * Either, it needs cross-user uri grants.
11103     *
11104     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11105     *
11106     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11107     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11108     */
11109    public String getProviderMimeType(Uri uri, int userId) {
11110        enforceNotIsolatedCaller("getProviderMimeType");
11111        final String name = uri.getAuthority();
11112        int callingUid = Binder.getCallingUid();
11113        int callingPid = Binder.getCallingPid();
11114        long ident = 0;
11115        boolean clearedIdentity = false;
11116        synchronized (this) {
11117            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11118        }
11119        if (canClearIdentity(callingPid, callingUid, userId)) {
11120            clearedIdentity = true;
11121            ident = Binder.clearCallingIdentity();
11122        }
11123        ContentProviderHolder holder = null;
11124        try {
11125            holder = getContentProviderExternalUnchecked(name, null, userId);
11126            if (holder != null) {
11127                return holder.provider.getType(uri);
11128            }
11129        } catch (RemoteException e) {
11130            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11131            return null;
11132        } finally {
11133            // We need to clear the identity to call removeContentProviderExternalUnchecked
11134            if (!clearedIdentity) {
11135                ident = Binder.clearCallingIdentity();
11136            }
11137            try {
11138                if (holder != null) {
11139                    removeContentProviderExternalUnchecked(name, null, userId);
11140                }
11141            } finally {
11142                Binder.restoreCallingIdentity(ident);
11143            }
11144        }
11145
11146        return null;
11147    }
11148
11149    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11150        if (UserHandle.getUserId(callingUid) == userId) {
11151            return true;
11152        }
11153        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11154                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11155                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11156                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11157                return true;
11158        }
11159        return false;
11160    }
11161
11162    // =========================================================
11163    // GLOBAL MANAGEMENT
11164    // =========================================================
11165
11166    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11167            boolean isolated, int isolatedUid) {
11168        String proc = customProcess != null ? customProcess : info.processName;
11169        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11170        final int userId = UserHandle.getUserId(info.uid);
11171        int uid = info.uid;
11172        if (isolated) {
11173            if (isolatedUid == 0) {
11174                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11175                while (true) {
11176                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11177                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11178                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11179                    }
11180                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11181                    mNextIsolatedProcessUid++;
11182                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11183                        // No process for this uid, use it.
11184                        break;
11185                    }
11186                    stepsLeft--;
11187                    if (stepsLeft <= 0) {
11188                        return null;
11189                    }
11190                }
11191            } else {
11192                // Special case for startIsolatedProcess (internal only), where
11193                // the uid of the isolated process is specified by the caller.
11194                uid = isolatedUid;
11195            }
11196        }
11197        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11198        if (!mBooted && !mBooting
11199                && userId == UserHandle.USER_SYSTEM
11200                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11201            r.persistent = true;
11202        }
11203        addProcessNameLocked(r);
11204        return r;
11205    }
11206
11207    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11208            String abiOverride) {
11209        ProcessRecord app;
11210        if (!isolated) {
11211            app = getProcessRecordLocked(info.processName, info.uid, true);
11212        } else {
11213            app = null;
11214        }
11215
11216        if (app == null) {
11217            app = newProcessRecordLocked(info, null, isolated, 0);
11218            updateLruProcessLocked(app, false, null);
11219            updateOomAdjLocked();
11220        }
11221
11222        // This package really, really can not be stopped.
11223        try {
11224            AppGlobals.getPackageManager().setPackageStoppedState(
11225                    info.packageName, false, UserHandle.getUserId(app.uid));
11226        } catch (RemoteException e) {
11227        } catch (IllegalArgumentException e) {
11228            Slog.w(TAG, "Failed trying to unstop package "
11229                    + info.packageName + ": " + e);
11230        }
11231
11232        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11233            app.persistent = true;
11234            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11235        }
11236        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11237            mPersistentStartingProcesses.add(app);
11238            startProcessLocked(app, "added application", app.processName, abiOverride,
11239                    null /* entryPoint */, null /* entryPointArgs */);
11240        }
11241
11242        return app;
11243    }
11244
11245    public void unhandledBack() {
11246        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11247                "unhandledBack()");
11248
11249        synchronized(this) {
11250            final long origId = Binder.clearCallingIdentity();
11251            try {
11252                getFocusedStack().unhandledBackLocked();
11253            } finally {
11254                Binder.restoreCallingIdentity(origId);
11255            }
11256        }
11257    }
11258
11259    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11260        enforceNotIsolatedCaller("openContentUri");
11261        final int userId = UserHandle.getCallingUserId();
11262        String name = uri.getAuthority();
11263        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11264        ParcelFileDescriptor pfd = null;
11265        if (cph != null) {
11266            // We record the binder invoker's uid in thread-local storage before
11267            // going to the content provider to open the file.  Later, in the code
11268            // that handles all permissions checks, we look for this uid and use
11269            // that rather than the Activity Manager's own uid.  The effect is that
11270            // we do the check against the caller's permissions even though it looks
11271            // to the content provider like the Activity Manager itself is making
11272            // the request.
11273            Binder token = new Binder();
11274            sCallerIdentity.set(new Identity(
11275                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11276            try {
11277                pfd = cph.provider.openFile(null, uri, "r", null, token);
11278            } catch (FileNotFoundException e) {
11279                // do nothing; pfd will be returned null
11280            } finally {
11281                // Ensure that whatever happens, we clean up the identity state
11282                sCallerIdentity.remove();
11283                // Ensure we're done with the provider.
11284                removeContentProviderExternalUnchecked(name, null, userId);
11285            }
11286        } else {
11287            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11288        }
11289        return pfd;
11290    }
11291
11292    // Actually is sleeping or shutting down or whatever else in the future
11293    // is an inactive state.
11294    public boolean isSleepingOrShuttingDown() {
11295        return isSleeping() || mShuttingDown;
11296    }
11297
11298    public boolean isSleeping() {
11299        return mSleeping;
11300    }
11301
11302    void onWakefulnessChanged(int wakefulness) {
11303        synchronized(this) {
11304            mWakefulness = wakefulness;
11305            updateSleepIfNeededLocked();
11306        }
11307    }
11308
11309    void finishRunningVoiceLocked() {
11310        if (mRunningVoice != null) {
11311            mRunningVoice = null;
11312            mVoiceWakeLock.release();
11313            updateSleepIfNeededLocked();
11314        }
11315    }
11316
11317    void startTimeTrackingFocusedActivityLocked() {
11318        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11319            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11320        }
11321    }
11322
11323    void updateSleepIfNeededLocked() {
11324        if (mSleeping && !shouldSleepLocked()) {
11325            mSleeping = false;
11326            startTimeTrackingFocusedActivityLocked();
11327            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11328            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11329            updateOomAdjLocked();
11330        } else if (!mSleeping && shouldSleepLocked()) {
11331            mSleeping = true;
11332            if (mCurAppTimeTracker != null) {
11333                mCurAppTimeTracker.stop();
11334            }
11335            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11336            mStackSupervisor.goingToSleepLocked();
11337            updateOomAdjLocked();
11338
11339            // Initialize the wake times of all processes.
11340            checkExcessivePowerUsageLocked(false);
11341            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11342            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11343            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11344        }
11345    }
11346
11347    private boolean shouldSleepLocked() {
11348        // Resume applications while running a voice interactor.
11349        if (mRunningVoice != null) {
11350            return false;
11351        }
11352
11353        // TODO: Transform the lock screen state into a sleep token instead.
11354        switch (mWakefulness) {
11355            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11356            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11357            case PowerManagerInternal.WAKEFULNESS_DOZING:
11358                // Pause applications whenever the lock screen is shown or any sleep
11359                // tokens have been acquired.
11360                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11361            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11362            default:
11363                // If we're asleep then pause applications unconditionally.
11364                return true;
11365        }
11366    }
11367
11368    /** Pokes the task persister. */
11369    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11370        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11371    }
11372
11373    /** Notifies all listeners when the task stack has changed. */
11374    void notifyTaskStackChangedLocked() {
11375        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11376        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11377        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11378        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11379    }
11380
11381    /** Notifies all listeners when an Activity is pinned. */
11382    void notifyActivityPinnedLocked() {
11383        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11384        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11385    }
11386
11387    /**
11388     * Notifies all listeners when an attempt was made to start an an activity that is already
11389     * running in the pinned stack and the activity was not actually started, but the task is
11390     * either brought to the front or a new Intent is delivered to it.
11391     */
11392    void notifyPinnedActivityRestartAttemptLocked() {
11393        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11394        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11395    }
11396
11397    /** Notifies all listeners when the pinned stack animation ends. */
11398    @Override
11399    public void notifyPinnedStackAnimationEnded() {
11400        synchronized (this) {
11401            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11402            mHandler.obtainMessage(
11403                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11404        }
11405    }
11406
11407    @Override
11408    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11409        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11410    }
11411
11412    @Override
11413    public boolean shutdown(int timeout) {
11414        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11415                != PackageManager.PERMISSION_GRANTED) {
11416            throw new SecurityException("Requires permission "
11417                    + android.Manifest.permission.SHUTDOWN);
11418        }
11419
11420        boolean timedout = false;
11421
11422        synchronized(this) {
11423            mShuttingDown = true;
11424            updateEventDispatchingLocked();
11425            timedout = mStackSupervisor.shutdownLocked(timeout);
11426        }
11427
11428        mAppOpsService.shutdown();
11429        if (mUsageStatsService != null) {
11430            mUsageStatsService.prepareShutdown();
11431        }
11432        mBatteryStatsService.shutdown();
11433        synchronized (this) {
11434            mProcessStats.shutdownLocked();
11435            notifyTaskPersisterLocked(null, true);
11436        }
11437
11438        return timedout;
11439    }
11440
11441    public final void activitySlept(IBinder token) {
11442        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11443
11444        final long origId = Binder.clearCallingIdentity();
11445
11446        synchronized (this) {
11447            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11448            if (r != null) {
11449                mStackSupervisor.activitySleptLocked(r);
11450            }
11451        }
11452
11453        Binder.restoreCallingIdentity(origId);
11454    }
11455
11456    private String lockScreenShownToString() {
11457        switch (mLockScreenShown) {
11458            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11459            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11460            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11461            default: return "Unknown=" + mLockScreenShown;
11462        }
11463    }
11464
11465    void logLockScreen(String msg) {
11466        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11467                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11468                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11469                + " mSleeping=" + mSleeping);
11470    }
11471
11472    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11473        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11474        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11475        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11476            boolean wasRunningVoice = mRunningVoice != null;
11477            mRunningVoice = session;
11478            if (!wasRunningVoice) {
11479                mVoiceWakeLock.acquire();
11480                updateSleepIfNeededLocked();
11481            }
11482        }
11483    }
11484
11485    private void updateEventDispatchingLocked() {
11486        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11487    }
11488
11489    public void setLockScreenShown(boolean showing, boolean occluded) {
11490        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11491                != PackageManager.PERMISSION_GRANTED) {
11492            throw new SecurityException("Requires permission "
11493                    + android.Manifest.permission.DEVICE_POWER);
11494        }
11495
11496        synchronized(this) {
11497            long ident = Binder.clearCallingIdentity();
11498            try {
11499                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11500                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11501                if (showing && occluded) {
11502                    // The lock screen is currently showing, but is occluded by a window that can
11503                    // show on top of the lock screen. In this can we want to dismiss the docked
11504                    // stack since it will be complicated/risky to try to put the activity on top
11505                    // of the lock screen in the right fullscreen configuration.
11506                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11507                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11508                }
11509
11510                updateSleepIfNeededLocked();
11511            } finally {
11512                Binder.restoreCallingIdentity(ident);
11513            }
11514        }
11515    }
11516
11517    @Override
11518    public void notifyLockedProfile(@UserIdInt int userId) {
11519        try {
11520            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11521                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11522            }
11523        } catch (RemoteException ex) {
11524            throw new SecurityException("Fail to check is caller a privileged app", ex);
11525        }
11526
11527        synchronized (this) {
11528            if (mStackSupervisor.isUserLockedProfile(userId)) {
11529                final long ident = Binder.clearCallingIdentity();
11530                try {
11531                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11532                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11533                        // If there is no device lock, we will show the profile's credential page.
11534                        mActivityStarter.showConfirmDeviceCredential(userId);
11535                    } else {
11536                        // Showing launcher to avoid user entering credential twice.
11537                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11538                    }
11539                } finally {
11540                    Binder.restoreCallingIdentity(ident);
11541                }
11542            }
11543        }
11544    }
11545
11546    @Override
11547    public void startConfirmDeviceCredentialIntent(Intent intent) {
11548        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11549        synchronized (this) {
11550            final long ident = Binder.clearCallingIdentity();
11551            try {
11552                mActivityStarter.startConfirmCredentialIntent(intent);
11553            } finally {
11554                Binder.restoreCallingIdentity(ident);
11555            }
11556        }
11557    }
11558
11559    @Override
11560    public void stopAppSwitches() {
11561        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11562                != PackageManager.PERMISSION_GRANTED) {
11563            throw new SecurityException("viewquires permission "
11564                    + android.Manifest.permission.STOP_APP_SWITCHES);
11565        }
11566
11567        synchronized(this) {
11568            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11569                    + APP_SWITCH_DELAY_TIME;
11570            mDidAppSwitch = false;
11571            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11572            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11573            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11574        }
11575    }
11576
11577    public void resumeAppSwitches() {
11578        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11579                != PackageManager.PERMISSION_GRANTED) {
11580            throw new SecurityException("Requires permission "
11581                    + android.Manifest.permission.STOP_APP_SWITCHES);
11582        }
11583
11584        synchronized(this) {
11585            // Note that we don't execute any pending app switches... we will
11586            // let those wait until either the timeout, or the next start
11587            // activity request.
11588            mAppSwitchesAllowedTime = 0;
11589        }
11590    }
11591
11592    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11593            int callingPid, int callingUid, String name) {
11594        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11595            return true;
11596        }
11597
11598        int perm = checkComponentPermission(
11599                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11600                sourceUid, -1, true);
11601        if (perm == PackageManager.PERMISSION_GRANTED) {
11602            return true;
11603        }
11604
11605        // If the actual IPC caller is different from the logical source, then
11606        // also see if they are allowed to control app switches.
11607        if (callingUid != -1 && callingUid != sourceUid) {
11608            perm = checkComponentPermission(
11609                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11610                    callingUid, -1, true);
11611            if (perm == PackageManager.PERMISSION_GRANTED) {
11612                return true;
11613            }
11614        }
11615
11616        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11617        return false;
11618    }
11619
11620    public void setDebugApp(String packageName, boolean waitForDebugger,
11621            boolean persistent) {
11622        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11623                "setDebugApp()");
11624
11625        long ident = Binder.clearCallingIdentity();
11626        try {
11627            // Note that this is not really thread safe if there are multiple
11628            // callers into it at the same time, but that's not a situation we
11629            // care about.
11630            if (persistent) {
11631                final ContentResolver resolver = mContext.getContentResolver();
11632                Settings.Global.putString(
11633                    resolver, Settings.Global.DEBUG_APP,
11634                    packageName);
11635                Settings.Global.putInt(
11636                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11637                    waitForDebugger ? 1 : 0);
11638            }
11639
11640            synchronized (this) {
11641                if (!persistent) {
11642                    mOrigDebugApp = mDebugApp;
11643                    mOrigWaitForDebugger = mWaitForDebugger;
11644                }
11645                mDebugApp = packageName;
11646                mWaitForDebugger = waitForDebugger;
11647                mDebugTransient = !persistent;
11648                if (packageName != null) {
11649                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11650                            false, UserHandle.USER_ALL, "set debug app");
11651                }
11652            }
11653        } finally {
11654            Binder.restoreCallingIdentity(ident);
11655        }
11656    }
11657
11658    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11659        synchronized (this) {
11660            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11661            if (!isDebuggable) {
11662                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11663                    throw new SecurityException("Process not debuggable: " + app.packageName);
11664                }
11665            }
11666
11667            mTrackAllocationApp = processName;
11668        }
11669    }
11670
11671    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11672        synchronized (this) {
11673            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11674            if (!isDebuggable) {
11675                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11676                    throw new SecurityException("Process not debuggable: " + app.packageName);
11677                }
11678            }
11679            mProfileApp = processName;
11680            mProfileFile = profilerInfo.profileFile;
11681            if (mProfileFd != null) {
11682                try {
11683                    mProfileFd.close();
11684                } catch (IOException e) {
11685                }
11686                mProfileFd = null;
11687            }
11688            mProfileFd = profilerInfo.profileFd;
11689            mSamplingInterval = profilerInfo.samplingInterval;
11690            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11691            mProfileType = 0;
11692        }
11693    }
11694
11695    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11696        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11697        if (!isDebuggable) {
11698            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11699                throw new SecurityException("Process not debuggable: " + app.packageName);
11700            }
11701        }
11702        mNativeDebuggingApp = processName;
11703    }
11704
11705    @Override
11706    public void setAlwaysFinish(boolean enabled) {
11707        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11708                "setAlwaysFinish()");
11709
11710        long ident = Binder.clearCallingIdentity();
11711        try {
11712            Settings.Global.putInt(
11713                    mContext.getContentResolver(),
11714                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11715
11716            synchronized (this) {
11717                mAlwaysFinishActivities = enabled;
11718            }
11719        } finally {
11720            Binder.restoreCallingIdentity(ident);
11721        }
11722    }
11723
11724    @Override
11725    public void setLenientBackgroundCheck(boolean enabled) {
11726        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11727                "setLenientBackgroundCheck()");
11728
11729        long ident = Binder.clearCallingIdentity();
11730        try {
11731            Settings.Global.putInt(
11732                    mContext.getContentResolver(),
11733                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11734
11735            synchronized (this) {
11736                mLenientBackgroundCheck = enabled;
11737            }
11738        } finally {
11739            Binder.restoreCallingIdentity(ident);
11740        }
11741    }
11742
11743    @Override
11744    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11745        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11746                "setActivityController()");
11747        synchronized (this) {
11748            mController = controller;
11749            mControllerIsAMonkey = imAMonkey;
11750            Watchdog.getInstance().setActivityController(controller);
11751        }
11752    }
11753
11754    @Override
11755    public void setUserIsMonkey(boolean userIsMonkey) {
11756        synchronized (this) {
11757            synchronized (mPidsSelfLocked) {
11758                final int callingPid = Binder.getCallingPid();
11759                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11760                if (precessRecord == null) {
11761                    throw new SecurityException("Unknown process: " + callingPid);
11762                }
11763                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11764                    throw new SecurityException("Only an instrumentation process "
11765                            + "with a UiAutomation can call setUserIsMonkey");
11766                }
11767            }
11768            mUserIsMonkey = userIsMonkey;
11769        }
11770    }
11771
11772    @Override
11773    public boolean isUserAMonkey() {
11774        synchronized (this) {
11775            // If there is a controller also implies the user is a monkey.
11776            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11777        }
11778    }
11779
11780    public void requestBugReport(int bugreportType) {
11781        String service = null;
11782        switch (bugreportType) {
11783            case ActivityManager.BUGREPORT_OPTION_FULL:
11784                service = "bugreport";
11785                break;
11786            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11787                service = "bugreportplus";
11788                break;
11789            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11790                service = "bugreportremote";
11791                break;
11792        }
11793        if (service == null) {
11794            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11795                    + bugreportType);
11796        }
11797        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11798        SystemProperties.set("ctl.start", service);
11799    }
11800
11801    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11802        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11803    }
11804
11805    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11806        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11807            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11808        }
11809        return KEY_DISPATCHING_TIMEOUT;
11810    }
11811
11812    @Override
11813    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11814        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11815                != PackageManager.PERMISSION_GRANTED) {
11816            throw new SecurityException("Requires permission "
11817                    + android.Manifest.permission.FILTER_EVENTS);
11818        }
11819        ProcessRecord proc;
11820        long timeout;
11821        synchronized (this) {
11822            synchronized (mPidsSelfLocked) {
11823                proc = mPidsSelfLocked.get(pid);
11824            }
11825            timeout = getInputDispatchingTimeoutLocked(proc);
11826        }
11827
11828        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11829            return -1;
11830        }
11831
11832        return timeout;
11833    }
11834
11835    /**
11836     * Handle input dispatching timeouts.
11837     * Returns whether input dispatching should be aborted or not.
11838     */
11839    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11840            final ActivityRecord activity, final ActivityRecord parent,
11841            final boolean aboveSystem, String reason) {
11842        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11843                != PackageManager.PERMISSION_GRANTED) {
11844            throw new SecurityException("Requires permission "
11845                    + android.Manifest.permission.FILTER_EVENTS);
11846        }
11847
11848        final String annotation;
11849        if (reason == null) {
11850            annotation = "Input dispatching timed out";
11851        } else {
11852            annotation = "Input dispatching timed out (" + reason + ")";
11853        }
11854
11855        if (proc != null) {
11856            synchronized (this) {
11857                if (proc.debugging) {
11858                    return false;
11859                }
11860
11861                if (mDidDexOpt) {
11862                    // Give more time since we were dexopting.
11863                    mDidDexOpt = false;
11864                    return false;
11865                }
11866
11867                if (proc.instrumentationClass != null) {
11868                    Bundle info = new Bundle();
11869                    info.putString("shortMsg", "keyDispatchingTimedOut");
11870                    info.putString("longMsg", annotation);
11871                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11872                    return true;
11873                }
11874            }
11875            mHandler.post(new Runnable() {
11876                @Override
11877                public void run() {
11878                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11879                }
11880            });
11881        }
11882
11883        return true;
11884    }
11885
11886    @Override
11887    public Bundle getAssistContextExtras(int requestType) {
11888        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11889                null, null, true /* focused */, true /* newSessionId */,
11890                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11891        if (pae == null) {
11892            return null;
11893        }
11894        synchronized (pae) {
11895            while (!pae.haveResult) {
11896                try {
11897                    pae.wait();
11898                } catch (InterruptedException e) {
11899                }
11900            }
11901        }
11902        synchronized (this) {
11903            buildAssistBundleLocked(pae, pae.result);
11904            mPendingAssistExtras.remove(pae);
11905            mUiHandler.removeCallbacks(pae);
11906        }
11907        return pae.extras;
11908    }
11909
11910    @Override
11911    public boolean isAssistDataAllowedOnCurrentActivity() {
11912        int userId;
11913        synchronized (this) {
11914            userId = mUserController.getCurrentUserIdLocked();
11915            ActivityRecord activity = getFocusedStack().topActivity();
11916            if (activity == null) {
11917                return false;
11918            }
11919            userId = activity.userId;
11920        }
11921        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11922                Context.DEVICE_POLICY_SERVICE);
11923        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11924    }
11925
11926    @Override
11927    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11928        long ident = Binder.clearCallingIdentity();
11929        try {
11930            synchronized (this) {
11931                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11932                ActivityRecord top = getFocusedStack().topActivity();
11933                if (top != caller) {
11934                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11935                            + " is not current top " + top);
11936                    return false;
11937                }
11938                if (!top.nowVisible) {
11939                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11940                            + " is not visible");
11941                    return false;
11942                }
11943            }
11944            AssistUtils utils = new AssistUtils(mContext);
11945            return utils.showSessionForActiveService(args,
11946                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11947        } finally {
11948            Binder.restoreCallingIdentity(ident);
11949        }
11950    }
11951
11952    @Override
11953    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11954            Bundle receiverExtras,
11955            IBinder activityToken, boolean focused, boolean newSessionId) {
11956        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11957                activityToken, focused, newSessionId,
11958                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11959                != null;
11960    }
11961
11962    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11963            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
11964            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
11965        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11966                "enqueueAssistContext()");
11967        synchronized (this) {
11968            ActivityRecord activity = getFocusedStack().topActivity();
11969            if (activity == null) {
11970                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11971                return null;
11972            }
11973            if (activity.app == null || activity.app.thread == null) {
11974                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11975                return null;
11976            }
11977            if (focused) {
11978                if (activityToken != null) {
11979                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11980                    if (activity != caller) {
11981                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11982                                + " is not current top " + activity);
11983                        return null;
11984                    }
11985                }
11986            } else {
11987                activity = ActivityRecord.forTokenLocked(activityToken);
11988                if (activity == null) {
11989                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
11990                            + " couldn't be found");
11991                    return null;
11992                }
11993            }
11994
11995            PendingAssistExtras pae;
11996            Bundle extras = new Bundle();
11997            if (args != null) {
11998                extras.putAll(args);
11999            }
12000            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12001            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12002            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12003                    userHandle);
12004            // Increment the sessionId if necessary
12005            if (newSessionId) {
12006                mViSessionId++;
12007            }
12008            try {
12009                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12010                        requestType, mViSessionId);
12011                mPendingAssistExtras.add(pae);
12012                mUiHandler.postDelayed(pae, timeout);
12013            } catch (RemoteException e) {
12014                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12015                return null;
12016            }
12017            return pae;
12018        }
12019    }
12020
12021    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12022        IResultReceiver receiver;
12023        synchronized (this) {
12024            mPendingAssistExtras.remove(pae);
12025            receiver = pae.receiver;
12026        }
12027        if (receiver != null) {
12028            // Caller wants result sent back to them.
12029            Bundle sendBundle = new Bundle();
12030            // At least return the receiver extras
12031            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12032                    pae.receiverExtras);
12033            try {
12034                pae.receiver.send(0, sendBundle);
12035            } catch (RemoteException e) {
12036            }
12037        }
12038    }
12039
12040    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12041        if (result != null) {
12042            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12043        }
12044        if (pae.hint != null) {
12045            pae.extras.putBoolean(pae.hint, true);
12046        }
12047    }
12048
12049    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12050            AssistContent content, Uri referrer) {
12051        PendingAssistExtras pae = (PendingAssistExtras)token;
12052        synchronized (pae) {
12053            pae.result = extras;
12054            pae.structure = structure;
12055            pae.content = content;
12056            if (referrer != null) {
12057                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12058            }
12059            pae.haveResult = true;
12060            pae.notifyAll();
12061            if (pae.intent == null && pae.receiver == null) {
12062                // Caller is just waiting for the result.
12063                return;
12064            }
12065        }
12066
12067        // We are now ready to launch the assist activity.
12068        IResultReceiver sendReceiver = null;
12069        Bundle sendBundle = null;
12070        synchronized (this) {
12071            buildAssistBundleLocked(pae, extras);
12072            boolean exists = mPendingAssistExtras.remove(pae);
12073            mUiHandler.removeCallbacks(pae);
12074            if (!exists) {
12075                // Timed out.
12076                return;
12077            }
12078            if ((sendReceiver=pae.receiver) != null) {
12079                // Caller wants result sent back to them.
12080                sendBundle = new Bundle();
12081                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12082                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12083                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12084                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12085                        pae.receiverExtras);
12086            }
12087        }
12088        if (sendReceiver != null) {
12089            try {
12090                sendReceiver.send(0, sendBundle);
12091            } catch (RemoteException e) {
12092            }
12093            return;
12094        }
12095
12096        long ident = Binder.clearCallingIdentity();
12097        try {
12098            pae.intent.replaceExtras(pae.extras);
12099            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12100                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12101                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12102            closeSystemDialogs("assist");
12103            try {
12104                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12105            } catch (ActivityNotFoundException e) {
12106                Slog.w(TAG, "No activity to handle assist action.", e);
12107            }
12108        } finally {
12109            Binder.restoreCallingIdentity(ident);
12110        }
12111    }
12112
12113    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12114            Bundle args) {
12115        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12116                true /* focused */, true /* newSessionId */,
12117                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12118    }
12119
12120    public void registerProcessObserver(IProcessObserver observer) {
12121        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12122                "registerProcessObserver()");
12123        synchronized (this) {
12124            mProcessObservers.register(observer);
12125        }
12126    }
12127
12128    @Override
12129    public void unregisterProcessObserver(IProcessObserver observer) {
12130        synchronized (this) {
12131            mProcessObservers.unregister(observer);
12132        }
12133    }
12134
12135    @Override
12136    public void registerUidObserver(IUidObserver observer, int which) {
12137        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12138                "registerUidObserver()");
12139        synchronized (this) {
12140            mUidObservers.register(observer, which);
12141        }
12142    }
12143
12144    @Override
12145    public void unregisterUidObserver(IUidObserver observer) {
12146        synchronized (this) {
12147            mUidObservers.unregister(observer);
12148        }
12149    }
12150
12151    @Override
12152    public boolean convertFromTranslucent(IBinder token) {
12153        final long origId = Binder.clearCallingIdentity();
12154        try {
12155            synchronized (this) {
12156                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12157                if (r == null) {
12158                    return false;
12159                }
12160                final boolean translucentChanged = r.changeWindowTranslucency(true);
12161                if (translucentChanged) {
12162                    r.task.stack.releaseBackgroundResources(r);
12163                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12164                }
12165                mWindowManager.setAppFullscreen(token, true);
12166                return translucentChanged;
12167            }
12168        } finally {
12169            Binder.restoreCallingIdentity(origId);
12170        }
12171    }
12172
12173    @Override
12174    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12175        final long origId = Binder.clearCallingIdentity();
12176        try {
12177            synchronized (this) {
12178                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12179                if (r == null) {
12180                    return false;
12181                }
12182                int index = r.task.mActivities.lastIndexOf(r);
12183                if (index > 0) {
12184                    ActivityRecord under = r.task.mActivities.get(index - 1);
12185                    under.returningOptions = options;
12186                }
12187                final boolean translucentChanged = r.changeWindowTranslucency(false);
12188                if (translucentChanged) {
12189                    r.task.stack.convertActivityToTranslucent(r);
12190                }
12191                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12192                mWindowManager.setAppFullscreen(token, false);
12193                return translucentChanged;
12194            }
12195        } finally {
12196            Binder.restoreCallingIdentity(origId);
12197        }
12198    }
12199
12200    @Override
12201    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12202        final long origId = Binder.clearCallingIdentity();
12203        try {
12204            synchronized (this) {
12205                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12206                if (r != null) {
12207                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12208                }
12209            }
12210            return false;
12211        } finally {
12212            Binder.restoreCallingIdentity(origId);
12213        }
12214    }
12215
12216    @Override
12217    public boolean isBackgroundVisibleBehind(IBinder token) {
12218        final long origId = Binder.clearCallingIdentity();
12219        try {
12220            synchronized (this) {
12221                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12222                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12223                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12224                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12225                return visible;
12226            }
12227        } finally {
12228            Binder.restoreCallingIdentity(origId);
12229        }
12230    }
12231
12232    @Override
12233    public ActivityOptions getActivityOptions(IBinder token) {
12234        final long origId = Binder.clearCallingIdentity();
12235        try {
12236            synchronized (this) {
12237                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12238                if (r != null) {
12239                    final ActivityOptions activityOptions = r.pendingOptions;
12240                    r.pendingOptions = null;
12241                    return activityOptions;
12242                }
12243                return null;
12244            }
12245        } finally {
12246            Binder.restoreCallingIdentity(origId);
12247        }
12248    }
12249
12250    @Override
12251    public void setImmersive(IBinder token, boolean immersive) {
12252        synchronized(this) {
12253            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12254            if (r == null) {
12255                throw new IllegalArgumentException();
12256            }
12257            r.immersive = immersive;
12258
12259            // update associated state if we're frontmost
12260            if (r == mFocusedActivity) {
12261                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12262                applyUpdateLockStateLocked(r);
12263            }
12264        }
12265    }
12266
12267    @Override
12268    public boolean isImmersive(IBinder token) {
12269        synchronized (this) {
12270            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12271            if (r == null) {
12272                throw new IllegalArgumentException();
12273            }
12274            return r.immersive;
12275        }
12276    }
12277
12278    @Override
12279    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12280        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12281            throw new UnsupportedOperationException("VR mode not supported on this device!");
12282        }
12283
12284        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12285
12286        ActivityRecord r;
12287        synchronized (this) {
12288            r = ActivityRecord.isInStackLocked(token);
12289        }
12290
12291        if (r == null) {
12292            throw new IllegalArgumentException();
12293        }
12294
12295        int err;
12296        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12297                VrManagerInternal.NO_ERROR) {
12298            return err;
12299        }
12300
12301        synchronized(this) {
12302            r.requestedVrComponent = (enabled) ? packageName : null;
12303
12304            // Update associated state if this activity is currently focused
12305            if (r == mFocusedActivity) {
12306                applyUpdateVrModeLocked(r);
12307            }
12308            return 0;
12309        }
12310    }
12311
12312    @Override
12313    public boolean isVrModePackageEnabled(ComponentName packageName) {
12314        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12315            throw new UnsupportedOperationException("VR mode not supported on this device!");
12316        }
12317
12318        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12319
12320        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12321                VrManagerInternal.NO_ERROR;
12322    }
12323
12324    public boolean isTopActivityImmersive() {
12325        enforceNotIsolatedCaller("startActivity");
12326        synchronized (this) {
12327            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12328            return (r != null) ? r.immersive : false;
12329        }
12330    }
12331
12332    @Override
12333    public boolean isTopOfTask(IBinder token) {
12334        synchronized (this) {
12335            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12336            if (r == null) {
12337                throw new IllegalArgumentException();
12338            }
12339            return r.task.getTopActivity() == r;
12340        }
12341    }
12342
12343    public final void enterSafeMode() {
12344        synchronized(this) {
12345            // It only makes sense to do this before the system is ready
12346            // and started launching other packages.
12347            if (!mSystemReady) {
12348                try {
12349                    AppGlobals.getPackageManager().enterSafeMode();
12350                } catch (RemoteException e) {
12351                }
12352            }
12353
12354            mSafeMode = true;
12355        }
12356    }
12357
12358    public final void showSafeModeOverlay() {
12359        View v = LayoutInflater.from(mContext).inflate(
12360                com.android.internal.R.layout.safe_mode, null);
12361        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12362        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12363        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12364        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12365        lp.gravity = Gravity.BOTTOM | Gravity.START;
12366        lp.format = v.getBackground().getOpacity();
12367        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12368                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12369        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12370        ((WindowManager)mContext.getSystemService(
12371                Context.WINDOW_SERVICE)).addView(v, lp);
12372    }
12373
12374    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12375        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12376            return;
12377        }
12378        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12379        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12380        synchronized (stats) {
12381            if (mBatteryStatsService.isOnBattery()) {
12382                mBatteryStatsService.enforceCallingPermission();
12383                int MY_UID = Binder.getCallingUid();
12384                final int uid;
12385                if (sender == null) {
12386                    uid = sourceUid;
12387                } else {
12388                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12389                }
12390                BatteryStatsImpl.Uid.Pkg pkg =
12391                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12392                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12393                pkg.noteWakeupAlarmLocked(tag);
12394            }
12395        }
12396    }
12397
12398    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12399        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12400            return;
12401        }
12402        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12403        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12404        synchronized (stats) {
12405            mBatteryStatsService.enforceCallingPermission();
12406            int MY_UID = Binder.getCallingUid();
12407            final int uid;
12408            if (sender == null) {
12409                uid = sourceUid;
12410            } else {
12411                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12412            }
12413            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12414        }
12415    }
12416
12417    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12418        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12419            return;
12420        }
12421        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12422        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12423        synchronized (stats) {
12424            mBatteryStatsService.enforceCallingPermission();
12425            int MY_UID = Binder.getCallingUid();
12426            final int uid;
12427            if (sender == null) {
12428                uid = sourceUid;
12429            } else {
12430                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12431            }
12432            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12433        }
12434    }
12435
12436    public boolean killPids(int[] pids, String pReason, boolean secure) {
12437        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12438            throw new SecurityException("killPids only available to the system");
12439        }
12440        String reason = (pReason == null) ? "Unknown" : pReason;
12441        // XXX Note: don't acquire main activity lock here, because the window
12442        // manager calls in with its locks held.
12443
12444        boolean killed = false;
12445        synchronized (mPidsSelfLocked) {
12446            int worstType = 0;
12447            for (int i=0; i<pids.length; i++) {
12448                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12449                if (proc != null) {
12450                    int type = proc.setAdj;
12451                    if (type > worstType) {
12452                        worstType = type;
12453                    }
12454                }
12455            }
12456
12457            // If the worst oom_adj is somewhere in the cached proc LRU range,
12458            // then constrain it so we will kill all cached procs.
12459            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12460                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12461                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12462            }
12463
12464            // If this is not a secure call, don't let it kill processes that
12465            // are important.
12466            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12467                worstType = ProcessList.SERVICE_ADJ;
12468            }
12469
12470            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12471            for (int i=0; i<pids.length; i++) {
12472                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12473                if (proc == null) {
12474                    continue;
12475                }
12476                int adj = proc.setAdj;
12477                if (adj >= worstType && !proc.killedByAm) {
12478                    proc.kill(reason, true);
12479                    killed = true;
12480                }
12481            }
12482        }
12483        return killed;
12484    }
12485
12486    @Override
12487    public void killUid(int appId, int userId, String reason) {
12488        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12489        synchronized (this) {
12490            final long identity = Binder.clearCallingIdentity();
12491            try {
12492                killPackageProcessesLocked(null, appId, userId,
12493                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12494                        reason != null ? reason : "kill uid");
12495            } finally {
12496                Binder.restoreCallingIdentity(identity);
12497            }
12498        }
12499    }
12500
12501    @Override
12502    public boolean killProcessesBelowForeground(String reason) {
12503        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12504            throw new SecurityException("killProcessesBelowForeground() only available to system");
12505        }
12506
12507        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12508    }
12509
12510    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12511        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12512            throw new SecurityException("killProcessesBelowAdj() only available to system");
12513        }
12514
12515        boolean killed = false;
12516        synchronized (mPidsSelfLocked) {
12517            final int size = mPidsSelfLocked.size();
12518            for (int i = 0; i < size; i++) {
12519                final int pid = mPidsSelfLocked.keyAt(i);
12520                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12521                if (proc == null) continue;
12522
12523                final int adj = proc.setAdj;
12524                if (adj > belowAdj && !proc.killedByAm) {
12525                    proc.kill(reason, true);
12526                    killed = true;
12527                }
12528            }
12529        }
12530        return killed;
12531    }
12532
12533    @Override
12534    public void hang(final IBinder who, boolean allowRestart) {
12535        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12536                != PackageManager.PERMISSION_GRANTED) {
12537            throw new SecurityException("Requires permission "
12538                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12539        }
12540
12541        final IBinder.DeathRecipient death = new DeathRecipient() {
12542            @Override
12543            public void binderDied() {
12544                synchronized (this) {
12545                    notifyAll();
12546                }
12547            }
12548        };
12549
12550        try {
12551            who.linkToDeath(death, 0);
12552        } catch (RemoteException e) {
12553            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12554            return;
12555        }
12556
12557        synchronized (this) {
12558            Watchdog.getInstance().setAllowRestart(allowRestart);
12559            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12560            synchronized (death) {
12561                while (who.isBinderAlive()) {
12562                    try {
12563                        death.wait();
12564                    } catch (InterruptedException e) {
12565                    }
12566                }
12567            }
12568            Watchdog.getInstance().setAllowRestart(true);
12569        }
12570    }
12571
12572    @Override
12573    public void restart() {
12574        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12575                != PackageManager.PERMISSION_GRANTED) {
12576            throw new SecurityException("Requires permission "
12577                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12578        }
12579
12580        Log.i(TAG, "Sending shutdown broadcast...");
12581
12582        BroadcastReceiver br = new BroadcastReceiver() {
12583            @Override public void onReceive(Context context, Intent intent) {
12584                // Now the broadcast is done, finish up the low-level shutdown.
12585                Log.i(TAG, "Shutting down activity manager...");
12586                shutdown(10000);
12587                Log.i(TAG, "Shutdown complete, restarting!");
12588                Process.killProcess(Process.myPid());
12589                System.exit(10);
12590            }
12591        };
12592
12593        // First send the high-level shut down broadcast.
12594        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12595        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12596        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12597        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12598        mContext.sendOrderedBroadcastAsUser(intent,
12599                UserHandle.ALL, null, br, mHandler, 0, null, null);
12600        */
12601        br.onReceive(mContext, intent);
12602    }
12603
12604    private long getLowRamTimeSinceIdle(long now) {
12605        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12606    }
12607
12608    @Override
12609    public void performIdleMaintenance() {
12610        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12611                != PackageManager.PERMISSION_GRANTED) {
12612            throw new SecurityException("Requires permission "
12613                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12614        }
12615
12616        synchronized (this) {
12617            final long now = SystemClock.uptimeMillis();
12618            final long timeSinceLastIdle = now - mLastIdleTime;
12619            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12620            mLastIdleTime = now;
12621            mLowRamTimeSinceLastIdle = 0;
12622            if (mLowRamStartTime != 0) {
12623                mLowRamStartTime = now;
12624            }
12625
12626            StringBuilder sb = new StringBuilder(128);
12627            sb.append("Idle maintenance over ");
12628            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12629            sb.append(" low RAM for ");
12630            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12631            Slog.i(TAG, sb.toString());
12632
12633            // If at least 1/3 of our time since the last idle period has been spent
12634            // with RAM low, then we want to kill processes.
12635            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12636
12637            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12638                ProcessRecord proc = mLruProcesses.get(i);
12639                if (proc.notCachedSinceIdle) {
12640                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12641                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12642                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12643                        if (doKilling && proc.initialIdlePss != 0
12644                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12645                            sb = new StringBuilder(128);
12646                            sb.append("Kill");
12647                            sb.append(proc.processName);
12648                            sb.append(" in idle maint: pss=");
12649                            sb.append(proc.lastPss);
12650                            sb.append(", swapPss=");
12651                            sb.append(proc.lastSwapPss);
12652                            sb.append(", initialPss=");
12653                            sb.append(proc.initialIdlePss);
12654                            sb.append(", period=");
12655                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12656                            sb.append(", lowRamPeriod=");
12657                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12658                            Slog.wtfQuiet(TAG, sb.toString());
12659                            proc.kill("idle maint (pss " + proc.lastPss
12660                                    + " from " + proc.initialIdlePss + ")", true);
12661                        }
12662                    }
12663                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12664                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12665                    proc.notCachedSinceIdle = true;
12666                    proc.initialIdlePss = 0;
12667                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12668                            mTestPssMode, isSleeping(), now);
12669                }
12670            }
12671
12672            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12673            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12674        }
12675    }
12676
12677    @Override
12678    public void sendIdleJobTrigger() {
12679        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12680                != PackageManager.PERMISSION_GRANTED) {
12681            throw new SecurityException("Requires permission "
12682                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12683        }
12684
12685        final long ident = Binder.clearCallingIdentity();
12686        try {
12687            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12688                    .setPackage("android")
12689                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12690            broadcastIntent(null, intent, null, null, 0, null, null, null,
12691                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12692        } finally {
12693            Binder.restoreCallingIdentity(ident);
12694        }
12695    }
12696
12697    private void retrieveSettings() {
12698        final ContentResolver resolver = mContext.getContentResolver();
12699        final boolean freeformWindowManagement =
12700                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12701                        || Settings.Global.getInt(
12702                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12703        final boolean supportsPictureInPicture =
12704                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12705
12706        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12707        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12708        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12709        final boolean alwaysFinishActivities =
12710                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12711        final boolean lenientBackgroundCheck =
12712                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12713        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12714        final boolean forceResizable = Settings.Global.getInt(
12715                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12716        // Transfer any global setting for forcing RTL layout, into a System Property
12717        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12718
12719        final Configuration configuration = new Configuration();
12720        Settings.System.getConfiguration(resolver, configuration);
12721        if (forceRtl) {
12722            // This will take care of setting the correct layout direction flags
12723            configuration.setLayoutDirection(configuration.locale);
12724        }
12725
12726        synchronized (this) {
12727            mDebugApp = mOrigDebugApp = debugApp;
12728            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12729            mAlwaysFinishActivities = alwaysFinishActivities;
12730            mLenientBackgroundCheck = lenientBackgroundCheck;
12731            mForceResizableActivities = forceResizable;
12732            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12733            if (supportsMultiWindow || forceResizable) {
12734                mSupportsMultiWindow = true;
12735                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12736                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12737            } else {
12738                mSupportsMultiWindow = false;
12739                mSupportsFreeformWindowManagement = false;
12740                mSupportsPictureInPicture = false;
12741            }
12742            // This happens before any activities are started, so we can
12743            // change mConfiguration in-place.
12744            updateConfigurationLocked(configuration, null, true);
12745            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12746                    "Initial config: " + mConfiguration);
12747
12748            // Load resources only after the current configuration has been set.
12749            final Resources res = mContext.getResources();
12750            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12751            mThumbnailWidth = res.getDimensionPixelSize(
12752                    com.android.internal.R.dimen.thumbnail_width);
12753            mThumbnailHeight = res.getDimensionPixelSize(
12754                    com.android.internal.R.dimen.thumbnail_height);
12755            mFullscreenThumbnailScale = res.getFraction(
12756                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12757            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12758                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12759            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12760                    com.android.internal.R.string.config_appsNotReportingCrashes));
12761        }
12762    }
12763
12764    public boolean testIsSystemReady() {
12765        // no need to synchronize(this) just to read & return the value
12766        return mSystemReady;
12767    }
12768
12769    public void systemReady(final Runnable goingCallback) {
12770        synchronized(this) {
12771            if (mSystemReady) {
12772                // If we're done calling all the receivers, run the next "boot phase" passed in
12773                // by the SystemServer
12774                if (goingCallback != null) {
12775                    goingCallback.run();
12776                }
12777                return;
12778            }
12779
12780            mLocalDeviceIdleController
12781                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12782
12783            // Make sure we have the current profile info, since it is needed for security checks.
12784            mUserController.onSystemReady();
12785            mRecentTasks.onSystemReadyLocked();
12786            mAppOpsService.systemReady();
12787            mSystemReady = true;
12788        }
12789
12790        ArrayList<ProcessRecord> procsToKill = null;
12791        synchronized(mPidsSelfLocked) {
12792            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12793                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12794                if (!isAllowedWhileBooting(proc.info)){
12795                    if (procsToKill == null) {
12796                        procsToKill = new ArrayList<ProcessRecord>();
12797                    }
12798                    procsToKill.add(proc);
12799                }
12800            }
12801        }
12802
12803        synchronized(this) {
12804            if (procsToKill != null) {
12805                for (int i=procsToKill.size()-1; i>=0; i--) {
12806                    ProcessRecord proc = procsToKill.get(i);
12807                    Slog.i(TAG, "Removing system update proc: " + proc);
12808                    removeProcessLocked(proc, true, false, "system update done");
12809                }
12810            }
12811
12812            // Now that we have cleaned up any update processes, we
12813            // are ready to start launching real processes and know that
12814            // we won't trample on them any more.
12815            mProcessesReady = true;
12816        }
12817
12818        Slog.i(TAG, "System now ready");
12819        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12820            SystemClock.uptimeMillis());
12821
12822        synchronized(this) {
12823            // Make sure we have no pre-ready processes sitting around.
12824
12825            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12826                ResolveInfo ri = mContext.getPackageManager()
12827                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12828                                STOCK_PM_FLAGS);
12829                CharSequence errorMsg = null;
12830                if (ri != null) {
12831                    ActivityInfo ai = ri.activityInfo;
12832                    ApplicationInfo app = ai.applicationInfo;
12833                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12834                        mTopAction = Intent.ACTION_FACTORY_TEST;
12835                        mTopData = null;
12836                        mTopComponent = new ComponentName(app.packageName,
12837                                ai.name);
12838                    } else {
12839                        errorMsg = mContext.getResources().getText(
12840                                com.android.internal.R.string.factorytest_not_system);
12841                    }
12842                } else {
12843                    errorMsg = mContext.getResources().getText(
12844                            com.android.internal.R.string.factorytest_no_action);
12845                }
12846                if (errorMsg != null) {
12847                    mTopAction = null;
12848                    mTopData = null;
12849                    mTopComponent = null;
12850                    Message msg = Message.obtain();
12851                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12852                    msg.getData().putCharSequence("msg", errorMsg);
12853                    mUiHandler.sendMessage(msg);
12854                }
12855            }
12856        }
12857
12858        retrieveSettings();
12859        final int currentUserId;
12860        synchronized (this) {
12861            currentUserId = mUserController.getCurrentUserIdLocked();
12862            readGrantedUriPermissionsLocked();
12863        }
12864
12865        if (goingCallback != null) goingCallback.run();
12866
12867        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12868                Integer.toString(currentUserId), currentUserId);
12869        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12870                Integer.toString(currentUserId), currentUserId);
12871        mSystemServiceManager.startUser(currentUserId);
12872
12873        synchronized (this) {
12874            // Only start up encryption-aware persistent apps; once user is
12875            // unlocked we'll come back around and start unaware apps
12876            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12877
12878            // Start up initial activity.
12879            mBooting = true;
12880            // Enable home activity for system user, so that the system can always boot
12881            if (UserManager.isSplitSystemUser()) {
12882                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12883                try {
12884                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12885                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12886                            UserHandle.USER_SYSTEM);
12887                } catch (RemoteException e) {
12888                    throw e.rethrowAsRuntimeException();
12889                }
12890            }
12891            startHomeActivityLocked(currentUserId, "systemReady");
12892
12893            try {
12894                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12895                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12896                            + " data partition or your device will be unstable.");
12897                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12898                }
12899            } catch (RemoteException e) {
12900            }
12901
12902            if (!Build.isBuildConsistent()) {
12903                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12904                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12905            }
12906
12907            long ident = Binder.clearCallingIdentity();
12908            try {
12909                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12910                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12911                        | Intent.FLAG_RECEIVER_FOREGROUND);
12912                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12913                broadcastIntentLocked(null, null, intent,
12914                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12915                        null, false, false, MY_PID, Process.SYSTEM_UID,
12916                        currentUserId);
12917                intent = new Intent(Intent.ACTION_USER_STARTING);
12918                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12919                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12920                broadcastIntentLocked(null, null, intent,
12921                        null, new IIntentReceiver.Stub() {
12922                            @Override
12923                            public void performReceive(Intent intent, int resultCode, String data,
12924                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12925                                    throws RemoteException {
12926                            }
12927                        }, 0, null, null,
12928                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12929                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12930            } catch (Throwable t) {
12931                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12932            } finally {
12933                Binder.restoreCallingIdentity(ident);
12934            }
12935            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12936            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12937        }
12938    }
12939
12940    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12941        synchronized (this) {
12942            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12943        }
12944    }
12945
12946    void skipCurrentReceiverLocked(ProcessRecord app) {
12947        for (BroadcastQueue queue : mBroadcastQueues) {
12948            queue.skipCurrentReceiverLocked(app);
12949        }
12950    }
12951
12952    /**
12953     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12954     * The application process will exit immediately after this call returns.
12955     * @param app object of the crashing app, null for the system server
12956     * @param crashInfo describing the exception
12957     */
12958    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12959        ProcessRecord r = findAppProcess(app, "Crash");
12960        final String processName = app == null ? "system_server"
12961                : (r == null ? "unknown" : r.processName);
12962
12963        handleApplicationCrashInner("crash", r, processName, crashInfo);
12964    }
12965
12966    /* Native crash reporting uses this inner version because it needs to be somewhat
12967     * decoupled from the AM-managed cleanup lifecycle
12968     */
12969    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12970            ApplicationErrorReport.CrashInfo crashInfo) {
12971        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12972                UserHandle.getUserId(Binder.getCallingUid()), processName,
12973                r == null ? -1 : r.info.flags,
12974                crashInfo.exceptionClassName,
12975                crashInfo.exceptionMessage,
12976                crashInfo.throwFileName,
12977                crashInfo.throwLineNumber);
12978
12979        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12980
12981        mAppErrors.crashApplication(r, crashInfo);
12982    }
12983
12984    public void handleApplicationStrictModeViolation(
12985            IBinder app,
12986            int violationMask,
12987            StrictMode.ViolationInfo info) {
12988        ProcessRecord r = findAppProcess(app, "StrictMode");
12989        if (r == null) {
12990            return;
12991        }
12992
12993        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12994            Integer stackFingerprint = info.hashCode();
12995            boolean logIt = true;
12996            synchronized (mAlreadyLoggedViolatedStacks) {
12997                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12998                    logIt = false;
12999                    // TODO: sub-sample into EventLog for these, with
13000                    // the info.durationMillis?  Then we'd get
13001                    // the relative pain numbers, without logging all
13002                    // the stack traces repeatedly.  We'd want to do
13003                    // likewise in the client code, which also does
13004                    // dup suppression, before the Binder call.
13005                } else {
13006                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13007                        mAlreadyLoggedViolatedStacks.clear();
13008                    }
13009                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13010                }
13011            }
13012            if (logIt) {
13013                logStrictModeViolationToDropBox(r, info);
13014            }
13015        }
13016
13017        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13018            AppErrorResult result = new AppErrorResult();
13019            synchronized (this) {
13020                final long origId = Binder.clearCallingIdentity();
13021
13022                Message msg = Message.obtain();
13023                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13024                HashMap<String, Object> data = new HashMap<String, Object>();
13025                data.put("result", result);
13026                data.put("app", r);
13027                data.put("violationMask", violationMask);
13028                data.put("info", info);
13029                msg.obj = data;
13030                mUiHandler.sendMessage(msg);
13031
13032                Binder.restoreCallingIdentity(origId);
13033            }
13034            int res = result.get();
13035            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13036        }
13037    }
13038
13039    // Depending on the policy in effect, there could be a bunch of
13040    // these in quick succession so we try to batch these together to
13041    // minimize disk writes, number of dropbox entries, and maximize
13042    // compression, by having more fewer, larger records.
13043    private void logStrictModeViolationToDropBox(
13044            ProcessRecord process,
13045            StrictMode.ViolationInfo info) {
13046        if (info == null) {
13047            return;
13048        }
13049        final boolean isSystemApp = process == null ||
13050                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13051                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13052        final String processName = process == null ? "unknown" : process.processName;
13053        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13054        final DropBoxManager dbox = (DropBoxManager)
13055                mContext.getSystemService(Context.DROPBOX_SERVICE);
13056
13057        // Exit early if the dropbox isn't configured to accept this report type.
13058        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13059
13060        boolean bufferWasEmpty;
13061        boolean needsFlush;
13062        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13063        synchronized (sb) {
13064            bufferWasEmpty = sb.length() == 0;
13065            appendDropBoxProcessHeaders(process, processName, sb);
13066            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13067            sb.append("System-App: ").append(isSystemApp).append("\n");
13068            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13069            if (info.violationNumThisLoop != 0) {
13070                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13071            }
13072            if (info.numAnimationsRunning != 0) {
13073                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13074            }
13075            if (info.broadcastIntentAction != null) {
13076                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13077            }
13078            if (info.durationMillis != -1) {
13079                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13080            }
13081            if (info.numInstances != -1) {
13082                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13083            }
13084            if (info.tags != null) {
13085                for (String tag : info.tags) {
13086                    sb.append("Span-Tag: ").append(tag).append("\n");
13087                }
13088            }
13089            sb.append("\n");
13090            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13091                sb.append(info.crashInfo.stackTrace);
13092                sb.append("\n");
13093            }
13094            if (info.message != null) {
13095                sb.append(info.message);
13096                sb.append("\n");
13097            }
13098
13099            // Only buffer up to ~64k.  Various logging bits truncate
13100            // things at 128k.
13101            needsFlush = (sb.length() > 64 * 1024);
13102        }
13103
13104        // Flush immediately if the buffer's grown too large, or this
13105        // is a non-system app.  Non-system apps are isolated with a
13106        // different tag & policy and not batched.
13107        //
13108        // Batching is useful during internal testing with
13109        // StrictMode settings turned up high.  Without batching,
13110        // thousands of separate files could be created on boot.
13111        if (!isSystemApp || needsFlush) {
13112            new Thread("Error dump: " + dropboxTag) {
13113                @Override
13114                public void run() {
13115                    String report;
13116                    synchronized (sb) {
13117                        report = sb.toString();
13118                        sb.delete(0, sb.length());
13119                        sb.trimToSize();
13120                    }
13121                    if (report.length() != 0) {
13122                        dbox.addText(dropboxTag, report);
13123                    }
13124                }
13125            }.start();
13126            return;
13127        }
13128
13129        // System app batching:
13130        if (!bufferWasEmpty) {
13131            // An existing dropbox-writing thread is outstanding, so
13132            // we don't need to start it up.  The existing thread will
13133            // catch the buffer appends we just did.
13134            return;
13135        }
13136
13137        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13138        // (After this point, we shouldn't access AMS internal data structures.)
13139        new Thread("Error dump: " + dropboxTag) {
13140            @Override
13141            public void run() {
13142                // 5 second sleep to let stacks arrive and be batched together
13143                try {
13144                    Thread.sleep(5000);  // 5 seconds
13145                } catch (InterruptedException e) {}
13146
13147                String errorReport;
13148                synchronized (mStrictModeBuffer) {
13149                    errorReport = mStrictModeBuffer.toString();
13150                    if (errorReport.length() == 0) {
13151                        return;
13152                    }
13153                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13154                    mStrictModeBuffer.trimToSize();
13155                }
13156                dbox.addText(dropboxTag, errorReport);
13157            }
13158        }.start();
13159    }
13160
13161    /**
13162     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13163     * @param app object of the crashing app, null for the system server
13164     * @param tag reported by the caller
13165     * @param system whether this wtf is coming from the system
13166     * @param crashInfo describing the context of the error
13167     * @return true if the process should exit immediately (WTF is fatal)
13168     */
13169    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13170            final ApplicationErrorReport.CrashInfo crashInfo) {
13171        final int callingUid = Binder.getCallingUid();
13172        final int callingPid = Binder.getCallingPid();
13173
13174        if (system) {
13175            // If this is coming from the system, we could very well have low-level
13176            // system locks held, so we want to do this all asynchronously.  And we
13177            // never want this to become fatal, so there is that too.
13178            mHandler.post(new Runnable() {
13179                @Override public void run() {
13180                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13181                }
13182            });
13183            return false;
13184        }
13185
13186        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13187                crashInfo);
13188
13189        if (r != null && r.pid != Process.myPid() &&
13190                Settings.Global.getInt(mContext.getContentResolver(),
13191                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13192            mAppErrors.crashApplication(r, crashInfo);
13193            return true;
13194        } else {
13195            return false;
13196        }
13197    }
13198
13199    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13200            final ApplicationErrorReport.CrashInfo crashInfo) {
13201        final ProcessRecord r = findAppProcess(app, "WTF");
13202        final String processName = app == null ? "system_server"
13203                : (r == null ? "unknown" : r.processName);
13204
13205        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13206                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13207
13208        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13209
13210        return r;
13211    }
13212
13213    /**
13214     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13215     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13216     */
13217    private ProcessRecord findAppProcess(IBinder app, String reason) {
13218        if (app == null) {
13219            return null;
13220        }
13221
13222        synchronized (this) {
13223            final int NP = mProcessNames.getMap().size();
13224            for (int ip=0; ip<NP; ip++) {
13225                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13226                final int NA = apps.size();
13227                for (int ia=0; ia<NA; ia++) {
13228                    ProcessRecord p = apps.valueAt(ia);
13229                    if (p.thread != null && p.thread.asBinder() == app) {
13230                        return p;
13231                    }
13232                }
13233            }
13234
13235            Slog.w(TAG, "Can't find mystery application for " + reason
13236                    + " from pid=" + Binder.getCallingPid()
13237                    + " uid=" + Binder.getCallingUid() + ": " + app);
13238            return null;
13239        }
13240    }
13241
13242    /**
13243     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13244     * to append various headers to the dropbox log text.
13245     */
13246    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13247            StringBuilder sb) {
13248        // Watchdog thread ends up invoking this function (with
13249        // a null ProcessRecord) to add the stack file to dropbox.
13250        // Do not acquire a lock on this (am) in such cases, as it
13251        // could cause a potential deadlock, if and when watchdog
13252        // is invoked due to unavailability of lock on am and it
13253        // would prevent watchdog from killing system_server.
13254        if (process == null) {
13255            sb.append("Process: ").append(processName).append("\n");
13256            return;
13257        }
13258        // Note: ProcessRecord 'process' is guarded by the service
13259        // instance.  (notably process.pkgList, which could otherwise change
13260        // concurrently during execution of this method)
13261        synchronized (this) {
13262            sb.append("Process: ").append(processName).append("\n");
13263            int flags = process.info.flags;
13264            IPackageManager pm = AppGlobals.getPackageManager();
13265            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13266            for (int ip=0; ip<process.pkgList.size(); ip++) {
13267                String pkg = process.pkgList.keyAt(ip);
13268                sb.append("Package: ").append(pkg);
13269                try {
13270                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13271                    if (pi != null) {
13272                        sb.append(" v").append(pi.versionCode);
13273                        if (pi.versionName != null) {
13274                            sb.append(" (").append(pi.versionName).append(")");
13275                        }
13276                    }
13277                } catch (RemoteException e) {
13278                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13279                }
13280                sb.append("\n");
13281            }
13282        }
13283    }
13284
13285    private static String processClass(ProcessRecord process) {
13286        if (process == null || process.pid == MY_PID) {
13287            return "system_server";
13288        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13289            return "system_app";
13290        } else {
13291            return "data_app";
13292        }
13293    }
13294
13295    private volatile long mWtfClusterStart;
13296    private volatile int mWtfClusterCount;
13297
13298    /**
13299     * Write a description of an error (crash, WTF, ANR) to the drop box.
13300     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13301     * @param process which caused the error, null means the system server
13302     * @param activity which triggered the error, null if unknown
13303     * @param parent activity related to the error, null if unknown
13304     * @param subject line related to the error, null if absent
13305     * @param report in long form describing the error, null if absent
13306     * @param logFile to include in the report, null if none
13307     * @param crashInfo giving an application stack trace, null if absent
13308     */
13309    public void addErrorToDropBox(String eventType,
13310            ProcessRecord process, String processName, ActivityRecord activity,
13311            ActivityRecord parent, String subject,
13312            final String report, final File logFile,
13313            final ApplicationErrorReport.CrashInfo crashInfo) {
13314        // NOTE -- this must never acquire the ActivityManagerService lock,
13315        // otherwise the watchdog may be prevented from resetting the system.
13316
13317        final String dropboxTag = processClass(process) + "_" + eventType;
13318        final DropBoxManager dbox = (DropBoxManager)
13319                mContext.getSystemService(Context.DROPBOX_SERVICE);
13320
13321        // Exit early if the dropbox isn't configured to accept this report type.
13322        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13323
13324        // Rate-limit how often we're willing to do the heavy lifting below to
13325        // collect and record logs; currently 5 logs per 10 second period.
13326        final long now = SystemClock.elapsedRealtime();
13327        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13328            mWtfClusterStart = now;
13329            mWtfClusterCount = 1;
13330        } else {
13331            if (mWtfClusterCount++ >= 5) return;
13332        }
13333
13334        final StringBuilder sb = new StringBuilder(1024);
13335        appendDropBoxProcessHeaders(process, processName, sb);
13336        if (process != null) {
13337            sb.append("Foreground: ")
13338                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13339                    .append("\n");
13340        }
13341        if (activity != null) {
13342            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13343        }
13344        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13345            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13346        }
13347        if (parent != null && parent != activity) {
13348            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13349        }
13350        if (subject != null) {
13351            sb.append("Subject: ").append(subject).append("\n");
13352        }
13353        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13354        if (Debug.isDebuggerConnected()) {
13355            sb.append("Debugger: Connected\n");
13356        }
13357        sb.append("\n");
13358
13359        // Do the rest in a worker thread to avoid blocking the caller on I/O
13360        // (After this point, we shouldn't access AMS internal data structures.)
13361        Thread worker = new Thread("Error dump: " + dropboxTag) {
13362            @Override
13363            public void run() {
13364                if (report != null) {
13365                    sb.append(report);
13366                }
13367                if (logFile != null) {
13368                    try {
13369                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13370                                    "\n\n[[TRUNCATED]]"));
13371                    } catch (IOException e) {
13372                        Slog.e(TAG, "Error reading " + logFile, e);
13373                    }
13374                }
13375                if (crashInfo != null && crashInfo.stackTrace != null) {
13376                    sb.append(crashInfo.stackTrace);
13377                }
13378
13379                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13380                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13381                if (lines > 0) {
13382                    sb.append("\n");
13383
13384                    // Merge several logcat streams, and take the last N lines
13385                    InputStreamReader input = null;
13386                    try {
13387                        java.lang.Process logcat = new ProcessBuilder(
13388                                "/system/bin/timeout", "-k", "15s", "10s",
13389                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13390                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13391                                        .redirectErrorStream(true).start();
13392
13393                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13394                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13395                        input = new InputStreamReader(logcat.getInputStream());
13396
13397                        int num;
13398                        char[] buf = new char[8192];
13399                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13400                    } catch (IOException e) {
13401                        Slog.e(TAG, "Error running logcat", e);
13402                    } finally {
13403                        if (input != null) try { input.close(); } catch (IOException e) {}
13404                    }
13405                }
13406
13407                dbox.addText(dropboxTag, sb.toString());
13408            }
13409        };
13410
13411        if (process == null) {
13412            // If process is null, we are being called from some internal code
13413            // and may be about to die -- run this synchronously.
13414            worker.run();
13415        } else {
13416            worker.start();
13417        }
13418    }
13419
13420    @Override
13421    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13422        enforceNotIsolatedCaller("getProcessesInErrorState");
13423        // assume our apps are happy - lazy create the list
13424        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13425
13426        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13427                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13428        int userId = UserHandle.getUserId(Binder.getCallingUid());
13429
13430        synchronized (this) {
13431
13432            // iterate across all processes
13433            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13434                ProcessRecord app = mLruProcesses.get(i);
13435                if (!allUsers && app.userId != userId) {
13436                    continue;
13437                }
13438                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13439                    // This one's in trouble, so we'll generate a report for it
13440                    // crashes are higher priority (in case there's a crash *and* an anr)
13441                    ActivityManager.ProcessErrorStateInfo report = null;
13442                    if (app.crashing) {
13443                        report = app.crashingReport;
13444                    } else if (app.notResponding) {
13445                        report = app.notRespondingReport;
13446                    }
13447
13448                    if (report != null) {
13449                        if (errList == null) {
13450                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13451                        }
13452                        errList.add(report);
13453                    } else {
13454                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13455                                " crashing = " + app.crashing +
13456                                " notResponding = " + app.notResponding);
13457                    }
13458                }
13459            }
13460        }
13461
13462        return errList;
13463    }
13464
13465    static int procStateToImportance(int procState, int memAdj,
13466            ActivityManager.RunningAppProcessInfo currApp) {
13467        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13468        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13469            currApp.lru = memAdj;
13470        } else {
13471            currApp.lru = 0;
13472        }
13473        return imp;
13474    }
13475
13476    private void fillInProcMemInfo(ProcessRecord app,
13477            ActivityManager.RunningAppProcessInfo outInfo) {
13478        outInfo.pid = app.pid;
13479        outInfo.uid = app.info.uid;
13480        if (mHeavyWeightProcess == app) {
13481            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13482        }
13483        if (app.persistent) {
13484            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13485        }
13486        if (app.activities.size() > 0) {
13487            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13488        }
13489        outInfo.lastTrimLevel = app.trimMemoryLevel;
13490        int adj = app.curAdj;
13491        int procState = app.curProcState;
13492        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13493        outInfo.importanceReasonCode = app.adjTypeCode;
13494        outInfo.processState = app.curProcState;
13495    }
13496
13497    @Override
13498    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13499        enforceNotIsolatedCaller("getRunningAppProcesses");
13500
13501        final int callingUid = Binder.getCallingUid();
13502
13503        // Lazy instantiation of list
13504        List<ActivityManager.RunningAppProcessInfo> runList = null;
13505        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13506                callingUid) == PackageManager.PERMISSION_GRANTED;
13507        final int userId = UserHandle.getUserId(callingUid);
13508        final boolean allUids = isGetTasksAllowed(
13509                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13510
13511        synchronized (this) {
13512            // Iterate across all processes
13513            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13514                ProcessRecord app = mLruProcesses.get(i);
13515                if ((!allUsers && app.userId != userId)
13516                        || (!allUids && app.uid != callingUid)) {
13517                    continue;
13518                }
13519                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13520                    // Generate process state info for running application
13521                    ActivityManager.RunningAppProcessInfo currApp =
13522                        new ActivityManager.RunningAppProcessInfo(app.processName,
13523                                app.pid, app.getPackageList());
13524                    fillInProcMemInfo(app, currApp);
13525                    if (app.adjSource instanceof ProcessRecord) {
13526                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13527                        currApp.importanceReasonImportance =
13528                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13529                                        app.adjSourceProcState);
13530                    } else if (app.adjSource instanceof ActivityRecord) {
13531                        ActivityRecord r = (ActivityRecord)app.adjSource;
13532                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13533                    }
13534                    if (app.adjTarget instanceof ComponentName) {
13535                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13536                    }
13537                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13538                    //        + " lru=" + currApp.lru);
13539                    if (runList == null) {
13540                        runList = new ArrayList<>();
13541                    }
13542                    runList.add(currApp);
13543                }
13544            }
13545        }
13546        return runList;
13547    }
13548
13549    @Override
13550    public List<ApplicationInfo> getRunningExternalApplications() {
13551        enforceNotIsolatedCaller("getRunningExternalApplications");
13552        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13553        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13554        if (runningApps != null && runningApps.size() > 0) {
13555            Set<String> extList = new HashSet<String>();
13556            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13557                if (app.pkgList != null) {
13558                    for (String pkg : app.pkgList) {
13559                        extList.add(pkg);
13560                    }
13561                }
13562            }
13563            IPackageManager pm = AppGlobals.getPackageManager();
13564            for (String pkg : extList) {
13565                try {
13566                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13567                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13568                        retList.add(info);
13569                    }
13570                } catch (RemoteException e) {
13571                }
13572            }
13573        }
13574        return retList;
13575    }
13576
13577    @Override
13578    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13579        enforceNotIsolatedCaller("getMyMemoryState");
13580        synchronized (this) {
13581            ProcessRecord proc;
13582            synchronized (mPidsSelfLocked) {
13583                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13584            }
13585            fillInProcMemInfo(proc, outInfo);
13586        }
13587    }
13588
13589    @Override
13590    public int getMemoryTrimLevel() {
13591        enforceNotIsolatedCaller("getMyMemoryState");
13592        synchronized (this) {
13593            return mLastMemoryLevel;
13594        }
13595    }
13596
13597    @Override
13598    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13599            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13600        (new ActivityManagerShellCommand(this, false)).exec(
13601                this, in, out, err, args, resultReceiver);
13602    }
13603
13604    @Override
13605    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13606        if (checkCallingPermission(android.Manifest.permission.DUMP)
13607                != PackageManager.PERMISSION_GRANTED) {
13608            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13609                    + Binder.getCallingPid()
13610                    + ", uid=" + Binder.getCallingUid()
13611                    + " without permission "
13612                    + android.Manifest.permission.DUMP);
13613            return;
13614        }
13615
13616        boolean dumpAll = false;
13617        boolean dumpClient = false;
13618        String dumpPackage = null;
13619
13620        int opti = 0;
13621        while (opti < args.length) {
13622            String opt = args[opti];
13623            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13624                break;
13625            }
13626            opti++;
13627            if ("-a".equals(opt)) {
13628                dumpAll = true;
13629            } else if ("-c".equals(opt)) {
13630                dumpClient = true;
13631            } else if ("-p".equals(opt)) {
13632                if (opti < args.length) {
13633                    dumpPackage = args[opti];
13634                    opti++;
13635                } else {
13636                    pw.println("Error: -p option requires package argument");
13637                    return;
13638                }
13639                dumpClient = true;
13640            } else if ("-h".equals(opt)) {
13641                ActivityManagerShellCommand.dumpHelp(pw, true);
13642                return;
13643            } else {
13644                pw.println("Unknown argument: " + opt + "; use -h for help");
13645            }
13646        }
13647
13648        long origId = Binder.clearCallingIdentity();
13649        boolean more = false;
13650        // Is the caller requesting to dump a particular piece of data?
13651        if (opti < args.length) {
13652            String cmd = args[opti];
13653            opti++;
13654            if ("activities".equals(cmd) || "a".equals(cmd)) {
13655                synchronized (this) {
13656                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13657                }
13658            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13659                synchronized (this) {
13660                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13661                }
13662            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13663                String[] newArgs;
13664                String name;
13665                if (opti >= args.length) {
13666                    name = null;
13667                    newArgs = EMPTY_STRING_ARRAY;
13668                } else {
13669                    dumpPackage = args[opti];
13670                    opti++;
13671                    newArgs = new String[args.length - opti];
13672                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13673                            args.length - opti);
13674                }
13675                synchronized (this) {
13676                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13677                }
13678            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13679                String[] newArgs;
13680                String name;
13681                if (opti >= args.length) {
13682                    name = null;
13683                    newArgs = EMPTY_STRING_ARRAY;
13684                } else {
13685                    dumpPackage = args[opti];
13686                    opti++;
13687                    newArgs = new String[args.length - opti];
13688                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13689                            args.length - opti);
13690                }
13691                synchronized (this) {
13692                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13693                }
13694            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13695                String[] newArgs;
13696                String name;
13697                if (opti >= args.length) {
13698                    name = null;
13699                    newArgs = EMPTY_STRING_ARRAY;
13700                } else {
13701                    dumpPackage = args[opti];
13702                    opti++;
13703                    newArgs = new String[args.length - opti];
13704                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13705                            args.length - opti);
13706                }
13707                synchronized (this) {
13708                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13709                }
13710            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13711                synchronized (this) {
13712                    dumpOomLocked(fd, pw, args, opti, true);
13713                }
13714            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13715                synchronized (this) {
13716                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13717                }
13718            } else if ("provider".equals(cmd)) {
13719                String[] newArgs;
13720                String name;
13721                if (opti >= args.length) {
13722                    name = null;
13723                    newArgs = EMPTY_STRING_ARRAY;
13724                } else {
13725                    name = args[opti];
13726                    opti++;
13727                    newArgs = new String[args.length - opti];
13728                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13729                }
13730                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13731                    pw.println("No providers match: " + name);
13732                    pw.println("Use -h for help.");
13733                }
13734            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13735                synchronized (this) {
13736                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13737                }
13738            } else if ("service".equals(cmd)) {
13739                String[] newArgs;
13740                String name;
13741                if (opti >= args.length) {
13742                    name = null;
13743                    newArgs = EMPTY_STRING_ARRAY;
13744                } else {
13745                    name = args[opti];
13746                    opti++;
13747                    newArgs = new String[args.length - opti];
13748                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13749                            args.length - opti);
13750                }
13751                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13752                    pw.println("No services match: " + name);
13753                    pw.println("Use -h for help.");
13754                }
13755            } else if ("package".equals(cmd)) {
13756                String[] newArgs;
13757                if (opti >= args.length) {
13758                    pw.println("package: no package name specified");
13759                    pw.println("Use -h for help.");
13760                } else {
13761                    dumpPackage = args[opti];
13762                    opti++;
13763                    newArgs = new String[args.length - opti];
13764                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13765                            args.length - opti);
13766                    args = newArgs;
13767                    opti = 0;
13768                    more = true;
13769                }
13770            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13771                synchronized (this) {
13772                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13773                }
13774            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13775                synchronized (this) {
13776                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13777                }
13778            } else if ("locks".equals(cmd)) {
13779                LockGuard.dump(fd, pw, args);
13780            } else {
13781                // Dumping a single activity?
13782                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13783                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13784                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13785                    if (res < 0) {
13786                        pw.println("Bad activity command, or no activities match: " + cmd);
13787                        pw.println("Use -h for help.");
13788                    }
13789                }
13790            }
13791            if (!more) {
13792                Binder.restoreCallingIdentity(origId);
13793                return;
13794            }
13795        }
13796
13797        // No piece of data specified, dump everything.
13798        synchronized (this) {
13799            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13800            pw.println();
13801            if (dumpAll) {
13802                pw.println("-------------------------------------------------------------------------------");
13803            }
13804            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13805            pw.println();
13806            if (dumpAll) {
13807                pw.println("-------------------------------------------------------------------------------");
13808            }
13809            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13810            pw.println();
13811            if (dumpAll) {
13812                pw.println("-------------------------------------------------------------------------------");
13813            }
13814            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13815            pw.println();
13816            if (dumpAll) {
13817                pw.println("-------------------------------------------------------------------------------");
13818            }
13819            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13820            pw.println();
13821            if (dumpAll) {
13822                pw.println("-------------------------------------------------------------------------------");
13823            }
13824            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13825            pw.println();
13826            if (dumpAll) {
13827                pw.println("-------------------------------------------------------------------------------");
13828            }
13829            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13830            if (mAssociations.size() > 0) {
13831                pw.println();
13832                if (dumpAll) {
13833                    pw.println("-------------------------------------------------------------------------------");
13834                }
13835                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13836            }
13837            pw.println();
13838            if (dumpAll) {
13839                pw.println("-------------------------------------------------------------------------------");
13840            }
13841            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13842        }
13843        Binder.restoreCallingIdentity(origId);
13844    }
13845
13846    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13847            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13848        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13849
13850        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13851                dumpPackage);
13852        boolean needSep = printedAnything;
13853
13854        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13855                dumpPackage, needSep, "  mFocusedActivity: ");
13856        if (printed) {
13857            printedAnything = true;
13858            needSep = false;
13859        }
13860
13861        if (dumpPackage == null) {
13862            if (needSep) {
13863                pw.println();
13864            }
13865            needSep = true;
13866            printedAnything = true;
13867            mStackSupervisor.dump(pw, "  ");
13868        }
13869
13870        if (!printedAnything) {
13871            pw.println("  (nothing)");
13872        }
13873    }
13874
13875    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13876            int opti, boolean dumpAll, String dumpPackage) {
13877        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13878
13879        boolean printedAnything = false;
13880
13881        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13882            boolean printedHeader = false;
13883
13884            final int N = mRecentTasks.size();
13885            for (int i=0; i<N; i++) {
13886                TaskRecord tr = mRecentTasks.get(i);
13887                if (dumpPackage != null) {
13888                    if (tr.realActivity == null ||
13889                            !dumpPackage.equals(tr.realActivity)) {
13890                        continue;
13891                    }
13892                }
13893                if (!printedHeader) {
13894                    pw.println("  Recent tasks:");
13895                    printedHeader = true;
13896                    printedAnything = true;
13897                }
13898                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13899                        pw.println(tr);
13900                if (dumpAll) {
13901                    mRecentTasks.get(i).dump(pw, "    ");
13902                }
13903            }
13904        }
13905
13906        if (!printedAnything) {
13907            pw.println("  (nothing)");
13908        }
13909    }
13910
13911    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13912            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13913        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13914
13915        int dumpUid = 0;
13916        if (dumpPackage != null) {
13917            IPackageManager pm = AppGlobals.getPackageManager();
13918            try {
13919                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13920            } catch (RemoteException e) {
13921            }
13922        }
13923
13924        boolean printedAnything = false;
13925
13926        final long now = SystemClock.uptimeMillis();
13927
13928        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13929            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13930                    = mAssociations.valueAt(i1);
13931            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13932                SparseArray<ArrayMap<String, Association>> sourceUids
13933                        = targetComponents.valueAt(i2);
13934                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13935                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13936                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13937                        Association ass = sourceProcesses.valueAt(i4);
13938                        if (dumpPackage != null) {
13939                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13940                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13941                                continue;
13942                            }
13943                        }
13944                        printedAnything = true;
13945                        pw.print("  ");
13946                        pw.print(ass.mTargetProcess);
13947                        pw.print("/");
13948                        UserHandle.formatUid(pw, ass.mTargetUid);
13949                        pw.print(" <- ");
13950                        pw.print(ass.mSourceProcess);
13951                        pw.print("/");
13952                        UserHandle.formatUid(pw, ass.mSourceUid);
13953                        pw.println();
13954                        pw.print("    via ");
13955                        pw.print(ass.mTargetComponent.flattenToShortString());
13956                        pw.println();
13957                        pw.print("    ");
13958                        long dur = ass.mTime;
13959                        if (ass.mNesting > 0) {
13960                            dur += now - ass.mStartTime;
13961                        }
13962                        TimeUtils.formatDuration(dur, pw);
13963                        pw.print(" (");
13964                        pw.print(ass.mCount);
13965                        pw.print(" times)");
13966                        pw.print("  ");
13967                        for (int i=0; i<ass.mStateTimes.length; i++) {
13968                            long amt = ass.mStateTimes[i];
13969                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13970                                amt += now - ass.mLastStateUptime;
13971                            }
13972                            if (amt != 0) {
13973                                pw.print(" ");
13974                                pw.print(ProcessList.makeProcStateString(
13975                                            i + ActivityManager.MIN_PROCESS_STATE));
13976                                pw.print("=");
13977                                TimeUtils.formatDuration(amt, pw);
13978                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13979                                    pw.print("*");
13980                                }
13981                            }
13982                        }
13983                        pw.println();
13984                        if (ass.mNesting > 0) {
13985                            pw.print("    Currently active: ");
13986                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13987                            pw.println();
13988                        }
13989                    }
13990                }
13991            }
13992
13993        }
13994
13995        if (!printedAnything) {
13996            pw.println("  (nothing)");
13997        }
13998    }
13999
14000    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14001            String header, boolean needSep) {
14002        boolean printed = false;
14003        int whichAppId = -1;
14004        if (dumpPackage != null) {
14005            try {
14006                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14007                        dumpPackage, 0);
14008                whichAppId = UserHandle.getAppId(info.uid);
14009            } catch (NameNotFoundException e) {
14010                e.printStackTrace();
14011            }
14012        }
14013        for (int i=0; i<uids.size(); i++) {
14014            UidRecord uidRec = uids.valueAt(i);
14015            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14016                continue;
14017            }
14018            if (!printed) {
14019                printed = true;
14020                if (needSep) {
14021                    pw.println();
14022                }
14023                pw.print("  ");
14024                pw.println(header);
14025                needSep = true;
14026            }
14027            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14028            pw.print(": "); pw.println(uidRec);
14029        }
14030        return printed;
14031    }
14032
14033    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14034            int opti, boolean dumpAll, String dumpPackage) {
14035        boolean needSep = false;
14036        boolean printedAnything = false;
14037        int numPers = 0;
14038
14039        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14040
14041        if (dumpAll) {
14042            final int NP = mProcessNames.getMap().size();
14043            for (int ip=0; ip<NP; ip++) {
14044                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14045                final int NA = procs.size();
14046                for (int ia=0; ia<NA; ia++) {
14047                    ProcessRecord r = procs.valueAt(ia);
14048                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14049                        continue;
14050                    }
14051                    if (!needSep) {
14052                        pw.println("  All known processes:");
14053                        needSep = true;
14054                        printedAnything = true;
14055                    }
14056                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14057                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14058                        pw.print(" "); pw.println(r);
14059                    r.dump(pw, "    ");
14060                    if (r.persistent) {
14061                        numPers++;
14062                    }
14063                }
14064            }
14065        }
14066
14067        if (mIsolatedProcesses.size() > 0) {
14068            boolean printed = false;
14069            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14070                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14071                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14072                    continue;
14073                }
14074                if (!printed) {
14075                    if (needSep) {
14076                        pw.println();
14077                    }
14078                    pw.println("  Isolated process list (sorted by uid):");
14079                    printedAnything = true;
14080                    printed = true;
14081                    needSep = true;
14082                }
14083                pw.println(String.format("%sIsolated #%2d: %s",
14084                        "    ", i, r.toString()));
14085            }
14086        }
14087
14088        if (mActiveUids.size() > 0) {
14089            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14090                printedAnything = needSep = true;
14091            }
14092        }
14093        if (mValidateUids.size() > 0) {
14094            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14095                printedAnything = needSep = true;
14096            }
14097        }
14098
14099        if (mLruProcesses.size() > 0) {
14100            if (needSep) {
14101                pw.println();
14102            }
14103            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14104                    pw.print(" total, non-act at ");
14105                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14106                    pw.print(", non-svc at ");
14107                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14108                    pw.println("):");
14109            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14110            needSep = true;
14111            printedAnything = true;
14112        }
14113
14114        if (dumpAll || dumpPackage != null) {
14115            synchronized (mPidsSelfLocked) {
14116                boolean printed = false;
14117                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14118                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14119                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14120                        continue;
14121                    }
14122                    if (!printed) {
14123                        if (needSep) pw.println();
14124                        needSep = true;
14125                        pw.println("  PID mappings:");
14126                        printed = true;
14127                        printedAnything = true;
14128                    }
14129                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14130                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14131                }
14132            }
14133        }
14134
14135        if (mForegroundProcesses.size() > 0) {
14136            synchronized (mPidsSelfLocked) {
14137                boolean printed = false;
14138                for (int i=0; i<mForegroundProcesses.size(); i++) {
14139                    ProcessRecord r = mPidsSelfLocked.get(
14140                            mForegroundProcesses.valueAt(i).pid);
14141                    if (dumpPackage != null && (r == null
14142                            || !r.pkgList.containsKey(dumpPackage))) {
14143                        continue;
14144                    }
14145                    if (!printed) {
14146                        if (needSep) pw.println();
14147                        needSep = true;
14148                        pw.println("  Foreground Processes:");
14149                        printed = true;
14150                        printedAnything = true;
14151                    }
14152                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14153                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14154                }
14155            }
14156        }
14157
14158        if (mPersistentStartingProcesses.size() > 0) {
14159            if (needSep) pw.println();
14160            needSep = true;
14161            printedAnything = true;
14162            pw.println("  Persisent processes that are starting:");
14163            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14164                    "Starting Norm", "Restarting PERS", dumpPackage);
14165        }
14166
14167        if (mRemovedProcesses.size() > 0) {
14168            if (needSep) pw.println();
14169            needSep = true;
14170            printedAnything = true;
14171            pw.println("  Processes that are being removed:");
14172            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14173                    "Removed Norm", "Removed PERS", dumpPackage);
14174        }
14175
14176        if (mProcessesOnHold.size() > 0) {
14177            if (needSep) pw.println();
14178            needSep = true;
14179            printedAnything = true;
14180            pw.println("  Processes that are on old until the system is ready:");
14181            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14182                    "OnHold Norm", "OnHold PERS", dumpPackage);
14183        }
14184
14185        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14186
14187        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14188        if (needSep) {
14189            printedAnything = true;
14190        }
14191
14192        if (dumpPackage == null) {
14193            pw.println();
14194            needSep = false;
14195            mUserController.dump(pw, dumpAll);
14196        }
14197        if (mHomeProcess != null && (dumpPackage == null
14198                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14199            if (needSep) {
14200                pw.println();
14201                needSep = false;
14202            }
14203            pw.println("  mHomeProcess: " + mHomeProcess);
14204        }
14205        if (mPreviousProcess != null && (dumpPackage == null
14206                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14207            if (needSep) {
14208                pw.println();
14209                needSep = false;
14210            }
14211            pw.println("  mPreviousProcess: " + mPreviousProcess);
14212        }
14213        if (dumpAll) {
14214            StringBuilder sb = new StringBuilder(128);
14215            sb.append("  mPreviousProcessVisibleTime: ");
14216            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14217            pw.println(sb);
14218        }
14219        if (mHeavyWeightProcess != null && (dumpPackage == null
14220                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14221            if (needSep) {
14222                pw.println();
14223                needSep = false;
14224            }
14225            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14226        }
14227        if (dumpPackage == null) {
14228            pw.println("  mConfiguration: " + mConfiguration);
14229        }
14230        if (dumpAll) {
14231            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14232            if (mCompatModePackages.getPackages().size() > 0) {
14233                boolean printed = false;
14234                for (Map.Entry<String, Integer> entry
14235                        : mCompatModePackages.getPackages().entrySet()) {
14236                    String pkg = entry.getKey();
14237                    int mode = entry.getValue();
14238                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14239                        continue;
14240                    }
14241                    if (!printed) {
14242                        pw.println("  mScreenCompatPackages:");
14243                        printed = true;
14244                    }
14245                    pw.print("    "); pw.print(pkg); pw.print(": ");
14246                            pw.print(mode); pw.println();
14247                }
14248            }
14249        }
14250        if (dumpPackage == null) {
14251            pw.println("  mWakefulness="
14252                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14253            pw.println("  mSleepTokens=" + mSleepTokens);
14254            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14255                    + lockScreenShownToString());
14256            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14257            if (mRunningVoice != null) {
14258                pw.println("  mRunningVoice=" + mRunningVoice);
14259                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14260            }
14261        }
14262        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14263                || mOrigWaitForDebugger) {
14264            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14265                    || dumpPackage.equals(mOrigDebugApp)) {
14266                if (needSep) {
14267                    pw.println();
14268                    needSep = false;
14269                }
14270                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14271                        + " mDebugTransient=" + mDebugTransient
14272                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14273            }
14274        }
14275        if (mCurAppTimeTracker != null) {
14276            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14277        }
14278        if (mMemWatchProcesses.getMap().size() > 0) {
14279            pw.println("  Mem watch processes:");
14280            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14281                    = mMemWatchProcesses.getMap();
14282            for (int i=0; i<procs.size(); i++) {
14283                final String proc = procs.keyAt(i);
14284                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14285                for (int j=0; j<uids.size(); j++) {
14286                    if (needSep) {
14287                        pw.println();
14288                        needSep = false;
14289                    }
14290                    StringBuilder sb = new StringBuilder();
14291                    sb.append("    ").append(proc).append('/');
14292                    UserHandle.formatUid(sb, uids.keyAt(j));
14293                    Pair<Long, String> val = uids.valueAt(j);
14294                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14295                    if (val.second != null) {
14296                        sb.append(", report to ").append(val.second);
14297                    }
14298                    pw.println(sb.toString());
14299                }
14300            }
14301            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14302            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14303            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14304                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14305        }
14306        if (mTrackAllocationApp != null) {
14307            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14308                if (needSep) {
14309                    pw.println();
14310                    needSep = false;
14311                }
14312                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14313            }
14314        }
14315        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14316                || mProfileFd != null) {
14317            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14318                if (needSep) {
14319                    pw.println();
14320                    needSep = false;
14321                }
14322                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14323                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14324                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14325                        + mAutoStopProfiler);
14326                pw.println("  mProfileType=" + mProfileType);
14327            }
14328        }
14329        if (mNativeDebuggingApp != null) {
14330            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14331                if (needSep) {
14332                    pw.println();
14333                    needSep = false;
14334                }
14335                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14336            }
14337        }
14338        if (dumpPackage == null) {
14339            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14340                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14341                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14342            }
14343            if (mController != null) {
14344                pw.println("  mController=" + mController
14345                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14346            }
14347            if (dumpAll) {
14348                pw.println("  Total persistent processes: " + numPers);
14349                pw.println("  mProcessesReady=" + mProcessesReady
14350                        + " mSystemReady=" + mSystemReady
14351                        + " mBooted=" + mBooted
14352                        + " mFactoryTest=" + mFactoryTest);
14353                pw.println("  mBooting=" + mBooting
14354                        + " mCallFinishBooting=" + mCallFinishBooting
14355                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14356                pw.print("  mLastPowerCheckRealtime=");
14357                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14358                        pw.println("");
14359                pw.print("  mLastPowerCheckUptime=");
14360                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14361                        pw.println("");
14362                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14363                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14364                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14365                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14366                        + " (" + mLruProcesses.size() + " total)"
14367                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14368                        + " mNumServiceProcs=" + mNumServiceProcs
14369                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14370                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14371                        + " mLastMemoryLevel=" + mLastMemoryLevel
14372                        + " mLastNumProcesses=" + mLastNumProcesses);
14373                long now = SystemClock.uptimeMillis();
14374                pw.print("  mLastIdleTime=");
14375                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14376                        pw.print(" mLowRamSinceLastIdle=");
14377                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14378                        pw.println();
14379            }
14380        }
14381
14382        if (!printedAnything) {
14383            pw.println("  (nothing)");
14384        }
14385    }
14386
14387    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14388            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14389        if (mProcessesToGc.size() > 0) {
14390            boolean printed = false;
14391            long now = SystemClock.uptimeMillis();
14392            for (int i=0; i<mProcessesToGc.size(); i++) {
14393                ProcessRecord proc = mProcessesToGc.get(i);
14394                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14395                    continue;
14396                }
14397                if (!printed) {
14398                    if (needSep) pw.println();
14399                    needSep = true;
14400                    pw.println("  Processes that are waiting to GC:");
14401                    printed = true;
14402                }
14403                pw.print("    Process "); pw.println(proc);
14404                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14405                        pw.print(", last gced=");
14406                        pw.print(now-proc.lastRequestedGc);
14407                        pw.print(" ms ago, last lowMem=");
14408                        pw.print(now-proc.lastLowMemory);
14409                        pw.println(" ms ago");
14410
14411            }
14412        }
14413        return needSep;
14414    }
14415
14416    void printOomLevel(PrintWriter pw, String name, int adj) {
14417        pw.print("    ");
14418        if (adj >= 0) {
14419            pw.print(' ');
14420            if (adj < 10) pw.print(' ');
14421        } else {
14422            if (adj > -10) pw.print(' ');
14423        }
14424        pw.print(adj);
14425        pw.print(": ");
14426        pw.print(name);
14427        pw.print(" (");
14428        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14429        pw.println(")");
14430    }
14431
14432    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14433            int opti, boolean dumpAll) {
14434        boolean needSep = false;
14435
14436        if (mLruProcesses.size() > 0) {
14437            if (needSep) pw.println();
14438            needSep = true;
14439            pw.println("  OOM levels:");
14440            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14441            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14442            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14443            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14444            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14445            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14446            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14447            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14448            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14449            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14450            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14451            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14452            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14453            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14454
14455            if (needSep) pw.println();
14456            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14457                    pw.print(" total, non-act at ");
14458                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14459                    pw.print(", non-svc at ");
14460                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14461                    pw.println("):");
14462            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14463            needSep = true;
14464        }
14465
14466        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14467
14468        pw.println();
14469        pw.println("  mHomeProcess: " + mHomeProcess);
14470        pw.println("  mPreviousProcess: " + mPreviousProcess);
14471        if (mHeavyWeightProcess != null) {
14472            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14473        }
14474
14475        return true;
14476    }
14477
14478    /**
14479     * There are three ways to call this:
14480     *  - no provider specified: dump all the providers
14481     *  - a flattened component name that matched an existing provider was specified as the
14482     *    first arg: dump that one provider
14483     *  - the first arg isn't the flattened component name of an existing provider:
14484     *    dump all providers whose component contains the first arg as a substring
14485     */
14486    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14487            int opti, boolean dumpAll) {
14488        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14489    }
14490
14491    static class ItemMatcher {
14492        ArrayList<ComponentName> components;
14493        ArrayList<String> strings;
14494        ArrayList<Integer> objects;
14495        boolean all;
14496
14497        ItemMatcher() {
14498            all = true;
14499        }
14500
14501        void build(String name) {
14502            ComponentName componentName = ComponentName.unflattenFromString(name);
14503            if (componentName != null) {
14504                if (components == null) {
14505                    components = new ArrayList<ComponentName>();
14506                }
14507                components.add(componentName);
14508                all = false;
14509            } else {
14510                int objectId = 0;
14511                // Not a '/' separated full component name; maybe an object ID?
14512                try {
14513                    objectId = Integer.parseInt(name, 16);
14514                    if (objects == null) {
14515                        objects = new ArrayList<Integer>();
14516                    }
14517                    objects.add(objectId);
14518                    all = false;
14519                } catch (RuntimeException e) {
14520                    // Not an integer; just do string match.
14521                    if (strings == null) {
14522                        strings = new ArrayList<String>();
14523                    }
14524                    strings.add(name);
14525                    all = false;
14526                }
14527            }
14528        }
14529
14530        int build(String[] args, int opti) {
14531            for (; opti<args.length; opti++) {
14532                String name = args[opti];
14533                if ("--".equals(name)) {
14534                    return opti+1;
14535                }
14536                build(name);
14537            }
14538            return opti;
14539        }
14540
14541        boolean match(Object object, ComponentName comp) {
14542            if (all) {
14543                return true;
14544            }
14545            if (components != null) {
14546                for (int i=0; i<components.size(); i++) {
14547                    if (components.get(i).equals(comp)) {
14548                        return true;
14549                    }
14550                }
14551            }
14552            if (objects != null) {
14553                for (int i=0; i<objects.size(); i++) {
14554                    if (System.identityHashCode(object) == objects.get(i)) {
14555                        return true;
14556                    }
14557                }
14558            }
14559            if (strings != null) {
14560                String flat = comp.flattenToString();
14561                for (int i=0; i<strings.size(); i++) {
14562                    if (flat.contains(strings.get(i))) {
14563                        return true;
14564                    }
14565                }
14566            }
14567            return false;
14568        }
14569    }
14570
14571    /**
14572     * There are three things that cmd can be:
14573     *  - a flattened component name that matches an existing activity
14574     *  - the cmd arg isn't the flattened component name of an existing activity:
14575     *    dump all activity whose component contains the cmd as a substring
14576     *  - A hex number of the ActivityRecord object instance.
14577     */
14578    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14579            int opti, boolean dumpAll) {
14580        ArrayList<ActivityRecord> activities;
14581
14582        synchronized (this) {
14583            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14584        }
14585
14586        if (activities.size() <= 0) {
14587            return false;
14588        }
14589
14590        String[] newArgs = new String[args.length - opti];
14591        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14592
14593        TaskRecord lastTask = null;
14594        boolean needSep = false;
14595        for (int i=activities.size()-1; i>=0; i--) {
14596            ActivityRecord r = activities.get(i);
14597            if (needSep) {
14598                pw.println();
14599            }
14600            needSep = true;
14601            synchronized (this) {
14602                if (lastTask != r.task) {
14603                    lastTask = r.task;
14604                    pw.print("TASK "); pw.print(lastTask.affinity);
14605                            pw.print(" id="); pw.println(lastTask.taskId);
14606                    if (dumpAll) {
14607                        lastTask.dump(pw, "  ");
14608                    }
14609                }
14610            }
14611            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14612        }
14613        return true;
14614    }
14615
14616    /**
14617     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14618     * there is a thread associated with the activity.
14619     */
14620    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14621            final ActivityRecord r, String[] args, boolean dumpAll) {
14622        String innerPrefix = prefix + "  ";
14623        synchronized (this) {
14624            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14625                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14626                    pw.print(" pid=");
14627                    if (r.app != null) pw.println(r.app.pid);
14628                    else pw.println("(not running)");
14629            if (dumpAll) {
14630                r.dump(pw, innerPrefix);
14631            }
14632        }
14633        if (r.app != null && r.app.thread != null) {
14634            // flush anything that is already in the PrintWriter since the thread is going
14635            // to write to the file descriptor directly
14636            pw.flush();
14637            try {
14638                TransferPipe tp = new TransferPipe();
14639                try {
14640                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14641                            r.appToken, innerPrefix, args);
14642                    tp.go(fd);
14643                } finally {
14644                    tp.kill();
14645                }
14646            } catch (IOException e) {
14647                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14648            } catch (RemoteException e) {
14649                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14650            }
14651        }
14652    }
14653
14654    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14655            int opti, boolean dumpAll, String dumpPackage) {
14656        boolean needSep = false;
14657        boolean onlyHistory = false;
14658        boolean printedAnything = false;
14659
14660        if ("history".equals(dumpPackage)) {
14661            if (opti < args.length && "-s".equals(args[opti])) {
14662                dumpAll = false;
14663            }
14664            onlyHistory = true;
14665            dumpPackage = null;
14666        }
14667
14668        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14669        if (!onlyHistory && dumpAll) {
14670            if (mRegisteredReceivers.size() > 0) {
14671                boolean printed = false;
14672                Iterator it = mRegisteredReceivers.values().iterator();
14673                while (it.hasNext()) {
14674                    ReceiverList r = (ReceiverList)it.next();
14675                    if (dumpPackage != null && (r.app == null ||
14676                            !dumpPackage.equals(r.app.info.packageName))) {
14677                        continue;
14678                    }
14679                    if (!printed) {
14680                        pw.println("  Registered Receivers:");
14681                        needSep = true;
14682                        printed = true;
14683                        printedAnything = true;
14684                    }
14685                    pw.print("  * "); pw.println(r);
14686                    r.dump(pw, "    ");
14687                }
14688            }
14689
14690            if (mReceiverResolver.dump(pw, needSep ?
14691                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14692                    "    ", dumpPackage, false, false)) {
14693                needSep = true;
14694                printedAnything = true;
14695            }
14696        }
14697
14698        for (BroadcastQueue q : mBroadcastQueues) {
14699            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14700            printedAnything |= needSep;
14701        }
14702
14703        needSep = true;
14704
14705        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14706            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14707                if (needSep) {
14708                    pw.println();
14709                }
14710                needSep = true;
14711                printedAnything = true;
14712                pw.print("  Sticky broadcasts for user ");
14713                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14714                StringBuilder sb = new StringBuilder(128);
14715                for (Map.Entry<String, ArrayList<Intent>> ent
14716                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14717                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14718                    if (dumpAll) {
14719                        pw.println(":");
14720                        ArrayList<Intent> intents = ent.getValue();
14721                        final int N = intents.size();
14722                        for (int i=0; i<N; i++) {
14723                            sb.setLength(0);
14724                            sb.append("    Intent: ");
14725                            intents.get(i).toShortString(sb, false, true, false, false);
14726                            pw.println(sb.toString());
14727                            Bundle bundle = intents.get(i).getExtras();
14728                            if (bundle != null) {
14729                                pw.print("      ");
14730                                pw.println(bundle.toString());
14731                            }
14732                        }
14733                    } else {
14734                        pw.println("");
14735                    }
14736                }
14737            }
14738        }
14739
14740        if (!onlyHistory && dumpAll) {
14741            pw.println();
14742            for (BroadcastQueue queue : mBroadcastQueues) {
14743                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14744                        + queue.mBroadcastsScheduled);
14745            }
14746            pw.println("  mHandler:");
14747            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14748            needSep = true;
14749            printedAnything = true;
14750        }
14751
14752        if (!printedAnything) {
14753            pw.println("  (nothing)");
14754        }
14755    }
14756
14757    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14758            int opti, boolean dumpAll, String dumpPackage) {
14759        boolean needSep;
14760        boolean printedAnything = false;
14761
14762        ItemMatcher matcher = new ItemMatcher();
14763        matcher.build(args, opti);
14764
14765        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14766
14767        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14768        printedAnything |= needSep;
14769
14770        if (mLaunchingProviders.size() > 0) {
14771            boolean printed = false;
14772            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14773                ContentProviderRecord r = mLaunchingProviders.get(i);
14774                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14775                    continue;
14776                }
14777                if (!printed) {
14778                    if (needSep) pw.println();
14779                    needSep = true;
14780                    pw.println("  Launching content providers:");
14781                    printed = true;
14782                    printedAnything = true;
14783                }
14784                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14785                        pw.println(r);
14786            }
14787        }
14788
14789        if (!printedAnything) {
14790            pw.println("  (nothing)");
14791        }
14792    }
14793
14794    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14795            int opti, boolean dumpAll, String dumpPackage) {
14796        boolean needSep = false;
14797        boolean printedAnything = false;
14798
14799        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14800
14801        if (mGrantedUriPermissions.size() > 0) {
14802            boolean printed = false;
14803            int dumpUid = -2;
14804            if (dumpPackage != null) {
14805                try {
14806                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14807                            MATCH_UNINSTALLED_PACKAGES, 0);
14808                } catch (NameNotFoundException e) {
14809                    dumpUid = -1;
14810                }
14811            }
14812            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14813                int uid = mGrantedUriPermissions.keyAt(i);
14814                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14815                    continue;
14816                }
14817                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14818                if (!printed) {
14819                    if (needSep) pw.println();
14820                    needSep = true;
14821                    pw.println("  Granted Uri Permissions:");
14822                    printed = true;
14823                    printedAnything = true;
14824                }
14825                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14826                for (UriPermission perm : perms.values()) {
14827                    pw.print("    "); pw.println(perm);
14828                    if (dumpAll) {
14829                        perm.dump(pw, "      ");
14830                    }
14831                }
14832            }
14833        }
14834
14835        if (!printedAnything) {
14836            pw.println("  (nothing)");
14837        }
14838    }
14839
14840    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14841            int opti, boolean dumpAll, String dumpPackage) {
14842        boolean printed = false;
14843
14844        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14845
14846        if (mIntentSenderRecords.size() > 0) {
14847            Iterator<WeakReference<PendingIntentRecord>> it
14848                    = mIntentSenderRecords.values().iterator();
14849            while (it.hasNext()) {
14850                WeakReference<PendingIntentRecord> ref = it.next();
14851                PendingIntentRecord rec = ref != null ? ref.get(): null;
14852                if (dumpPackage != null && (rec == null
14853                        || !dumpPackage.equals(rec.key.packageName))) {
14854                    continue;
14855                }
14856                printed = true;
14857                if (rec != null) {
14858                    pw.print("  * "); pw.println(rec);
14859                    if (dumpAll) {
14860                        rec.dump(pw, "    ");
14861                    }
14862                } else {
14863                    pw.print("  * "); pw.println(ref);
14864                }
14865            }
14866        }
14867
14868        if (!printed) {
14869            pw.println("  (nothing)");
14870        }
14871    }
14872
14873    private static final int dumpProcessList(PrintWriter pw,
14874            ActivityManagerService service, List list,
14875            String prefix, String normalLabel, String persistentLabel,
14876            String dumpPackage) {
14877        int numPers = 0;
14878        final int N = list.size()-1;
14879        for (int i=N; i>=0; i--) {
14880            ProcessRecord r = (ProcessRecord)list.get(i);
14881            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14882                continue;
14883            }
14884            pw.println(String.format("%s%s #%2d: %s",
14885                    prefix, (r.persistent ? persistentLabel : normalLabel),
14886                    i, r.toString()));
14887            if (r.persistent) {
14888                numPers++;
14889            }
14890        }
14891        return numPers;
14892    }
14893
14894    private static final boolean dumpProcessOomList(PrintWriter pw,
14895            ActivityManagerService service, List<ProcessRecord> origList,
14896            String prefix, String normalLabel, String persistentLabel,
14897            boolean inclDetails, String dumpPackage) {
14898
14899        ArrayList<Pair<ProcessRecord, Integer>> list
14900                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14901        for (int i=0; i<origList.size(); i++) {
14902            ProcessRecord r = origList.get(i);
14903            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14904                continue;
14905            }
14906            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14907        }
14908
14909        if (list.size() <= 0) {
14910            return false;
14911        }
14912
14913        Comparator<Pair<ProcessRecord, Integer>> comparator
14914                = new Comparator<Pair<ProcessRecord, Integer>>() {
14915            @Override
14916            public int compare(Pair<ProcessRecord, Integer> object1,
14917                    Pair<ProcessRecord, Integer> object2) {
14918                if (object1.first.setAdj != object2.first.setAdj) {
14919                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14920                }
14921                if (object1.first.setProcState != object2.first.setProcState) {
14922                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14923                }
14924                if (object1.second.intValue() != object2.second.intValue()) {
14925                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14926                }
14927                return 0;
14928            }
14929        };
14930
14931        Collections.sort(list, comparator);
14932
14933        final long curRealtime = SystemClock.elapsedRealtime();
14934        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14935        final long curUptime = SystemClock.uptimeMillis();
14936        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14937
14938        for (int i=list.size()-1; i>=0; i--) {
14939            ProcessRecord r = list.get(i).first;
14940            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14941            char schedGroup;
14942            switch (r.setSchedGroup) {
14943                case ProcessList.SCHED_GROUP_BACKGROUND:
14944                    schedGroup = 'B';
14945                    break;
14946                case ProcessList.SCHED_GROUP_DEFAULT:
14947                    schedGroup = 'F';
14948                    break;
14949                case ProcessList.SCHED_GROUP_TOP_APP:
14950                    schedGroup = 'T';
14951                    break;
14952                default:
14953                    schedGroup = '?';
14954                    break;
14955            }
14956            char foreground;
14957            if (r.foregroundActivities) {
14958                foreground = 'A';
14959            } else if (r.foregroundServices) {
14960                foreground = 'S';
14961            } else {
14962                foreground = ' ';
14963            }
14964            String procState = ProcessList.makeProcStateString(r.curProcState);
14965            pw.print(prefix);
14966            pw.print(r.persistent ? persistentLabel : normalLabel);
14967            pw.print(" #");
14968            int num = (origList.size()-1)-list.get(i).second;
14969            if (num < 10) pw.print(' ');
14970            pw.print(num);
14971            pw.print(": ");
14972            pw.print(oomAdj);
14973            pw.print(' ');
14974            pw.print(schedGroup);
14975            pw.print('/');
14976            pw.print(foreground);
14977            pw.print('/');
14978            pw.print(procState);
14979            pw.print(" trm:");
14980            if (r.trimMemoryLevel < 10) pw.print(' ');
14981            pw.print(r.trimMemoryLevel);
14982            pw.print(' ');
14983            pw.print(r.toShortString());
14984            pw.print(" (");
14985            pw.print(r.adjType);
14986            pw.println(')');
14987            if (r.adjSource != null || r.adjTarget != null) {
14988                pw.print(prefix);
14989                pw.print("    ");
14990                if (r.adjTarget instanceof ComponentName) {
14991                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14992                } else if (r.adjTarget != null) {
14993                    pw.print(r.adjTarget.toString());
14994                } else {
14995                    pw.print("{null}");
14996                }
14997                pw.print("<=");
14998                if (r.adjSource instanceof ProcessRecord) {
14999                    pw.print("Proc{");
15000                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15001                    pw.println("}");
15002                } else if (r.adjSource != null) {
15003                    pw.println(r.adjSource.toString());
15004                } else {
15005                    pw.println("{null}");
15006                }
15007            }
15008            if (inclDetails) {
15009                pw.print(prefix);
15010                pw.print("    ");
15011                pw.print("oom: max="); pw.print(r.maxAdj);
15012                pw.print(" curRaw="); pw.print(r.curRawAdj);
15013                pw.print(" setRaw="); pw.print(r.setRawAdj);
15014                pw.print(" cur="); pw.print(r.curAdj);
15015                pw.print(" set="); pw.println(r.setAdj);
15016                pw.print(prefix);
15017                pw.print("    ");
15018                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15019                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15020                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15021                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15022                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15023                pw.println();
15024                pw.print(prefix);
15025                pw.print("    ");
15026                pw.print("cached="); pw.print(r.cached);
15027                pw.print(" empty="); pw.print(r.empty);
15028                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15029
15030                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15031                    if (r.lastWakeTime != 0) {
15032                        long wtime;
15033                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15034                        synchronized (stats) {
15035                            wtime = stats.getProcessWakeTime(r.info.uid,
15036                                    r.pid, curRealtime);
15037                        }
15038                        long timeUsed = wtime - r.lastWakeTime;
15039                        pw.print(prefix);
15040                        pw.print("    ");
15041                        pw.print("keep awake over ");
15042                        TimeUtils.formatDuration(realtimeSince, pw);
15043                        pw.print(" used ");
15044                        TimeUtils.formatDuration(timeUsed, pw);
15045                        pw.print(" (");
15046                        pw.print((timeUsed*100)/realtimeSince);
15047                        pw.println("%)");
15048                    }
15049                    if (r.lastCpuTime != 0) {
15050                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15051                        pw.print(prefix);
15052                        pw.print("    ");
15053                        pw.print("run cpu over ");
15054                        TimeUtils.formatDuration(uptimeSince, pw);
15055                        pw.print(" used ");
15056                        TimeUtils.formatDuration(timeUsed, pw);
15057                        pw.print(" (");
15058                        pw.print((timeUsed*100)/uptimeSince);
15059                        pw.println("%)");
15060                    }
15061                }
15062            }
15063        }
15064        return true;
15065    }
15066
15067    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15068            String[] args) {
15069        ArrayList<ProcessRecord> procs;
15070        synchronized (this) {
15071            if (args != null && args.length > start
15072                    && args[start].charAt(0) != '-') {
15073                procs = new ArrayList<ProcessRecord>();
15074                int pid = -1;
15075                try {
15076                    pid = Integer.parseInt(args[start]);
15077                } catch (NumberFormatException e) {
15078                }
15079                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15080                    ProcessRecord proc = mLruProcesses.get(i);
15081                    if (proc.pid == pid) {
15082                        procs.add(proc);
15083                    } else if (allPkgs && proc.pkgList != null
15084                            && proc.pkgList.containsKey(args[start])) {
15085                        procs.add(proc);
15086                    } else if (proc.processName.equals(args[start])) {
15087                        procs.add(proc);
15088                    }
15089                }
15090                if (procs.size() <= 0) {
15091                    return null;
15092                }
15093            } else {
15094                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15095            }
15096        }
15097        return procs;
15098    }
15099
15100    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15101            PrintWriter pw, String[] args) {
15102        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15103        if (procs == null) {
15104            pw.println("No process found for: " + args[0]);
15105            return;
15106        }
15107
15108        long uptime = SystemClock.uptimeMillis();
15109        long realtime = SystemClock.elapsedRealtime();
15110        pw.println("Applications Graphics Acceleration Info:");
15111        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15112
15113        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15114            ProcessRecord r = procs.get(i);
15115            if (r.thread != null) {
15116                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15117                pw.flush();
15118                try {
15119                    TransferPipe tp = new TransferPipe();
15120                    try {
15121                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15122                        tp.go(fd);
15123                    } finally {
15124                        tp.kill();
15125                    }
15126                } catch (IOException e) {
15127                    pw.println("Failure while dumping the app: " + r);
15128                    pw.flush();
15129                } catch (RemoteException e) {
15130                    pw.println("Got a RemoteException while dumping the app " + r);
15131                    pw.flush();
15132                }
15133            }
15134        }
15135    }
15136
15137    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15138        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15139        if (procs == null) {
15140            pw.println("No process found for: " + args[0]);
15141            return;
15142        }
15143
15144        pw.println("Applications Database Info:");
15145
15146        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15147            ProcessRecord r = procs.get(i);
15148            if (r.thread != null) {
15149                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15150                pw.flush();
15151                try {
15152                    TransferPipe tp = new TransferPipe();
15153                    try {
15154                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15155                        tp.go(fd);
15156                    } finally {
15157                        tp.kill();
15158                    }
15159                } catch (IOException e) {
15160                    pw.println("Failure while dumping the app: " + r);
15161                    pw.flush();
15162                } catch (RemoteException e) {
15163                    pw.println("Got a RemoteException while dumping the app " + r);
15164                    pw.flush();
15165                }
15166            }
15167        }
15168    }
15169
15170    final static class MemItem {
15171        final boolean isProc;
15172        final String label;
15173        final String shortLabel;
15174        final long pss;
15175        final long swapPss;
15176        final int id;
15177        final boolean hasActivities;
15178        ArrayList<MemItem> subitems;
15179
15180        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15181                boolean _hasActivities) {
15182            isProc = true;
15183            label = _label;
15184            shortLabel = _shortLabel;
15185            pss = _pss;
15186            swapPss = _swapPss;
15187            id = _id;
15188            hasActivities = _hasActivities;
15189        }
15190
15191        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15192            isProc = false;
15193            label = _label;
15194            shortLabel = _shortLabel;
15195            pss = _pss;
15196            swapPss = _swapPss;
15197            id = _id;
15198            hasActivities = false;
15199        }
15200    }
15201
15202    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15203            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15204        if (sort && !isCompact) {
15205            Collections.sort(items, new Comparator<MemItem>() {
15206                @Override
15207                public int compare(MemItem lhs, MemItem rhs) {
15208                    if (lhs.pss < rhs.pss) {
15209                        return 1;
15210                    } else if (lhs.pss > rhs.pss) {
15211                        return -1;
15212                    }
15213                    return 0;
15214                }
15215            });
15216        }
15217
15218        for (int i=0; i<items.size(); i++) {
15219            MemItem mi = items.get(i);
15220            if (!isCompact) {
15221                if (dumpSwapPss) {
15222                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15223                            mi.label, stringifyKBSize(mi.swapPss));
15224                } else {
15225                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15226                }
15227            } else if (mi.isProc) {
15228                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15229                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15230                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15231                pw.println(mi.hasActivities ? ",a" : ",e");
15232            } else {
15233                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15234                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15235            }
15236            if (mi.subitems != null) {
15237                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15238                        true, isCompact, dumpSwapPss);
15239            }
15240        }
15241    }
15242
15243    // These are in KB.
15244    static final long[] DUMP_MEM_BUCKETS = new long[] {
15245        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15246        120*1024, 160*1024, 200*1024,
15247        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15248        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15249    };
15250
15251    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15252            boolean stackLike) {
15253        int start = label.lastIndexOf('.');
15254        if (start >= 0) start++;
15255        else start = 0;
15256        int end = label.length();
15257        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15258            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15259                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15260                out.append(bucket);
15261                out.append(stackLike ? "MB." : "MB ");
15262                out.append(label, start, end);
15263                return;
15264            }
15265        }
15266        out.append(memKB/1024);
15267        out.append(stackLike ? "MB." : "MB ");
15268        out.append(label, start, end);
15269    }
15270
15271    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15272            ProcessList.NATIVE_ADJ,
15273            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15274            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15275            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15276            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15277            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15278            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15279    };
15280    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15281            "Native",
15282            "System", "Persistent", "Persistent Service", "Foreground",
15283            "Visible", "Perceptible",
15284            "Heavy Weight", "Backup",
15285            "A Services", "Home",
15286            "Previous", "B Services", "Cached"
15287    };
15288    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15289            "native",
15290            "sys", "pers", "persvc", "fore",
15291            "vis", "percept",
15292            "heavy", "backup",
15293            "servicea", "home",
15294            "prev", "serviceb", "cached"
15295    };
15296
15297    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15298            long realtime, boolean isCheckinRequest, boolean isCompact) {
15299        if (isCompact) {
15300            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15301        }
15302        if (isCheckinRequest || isCompact) {
15303            // short checkin version
15304            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15305        } else {
15306            pw.println("Applications Memory Usage (in Kilobytes):");
15307            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15308        }
15309    }
15310
15311    private static final int KSM_SHARED = 0;
15312    private static final int KSM_SHARING = 1;
15313    private static final int KSM_UNSHARED = 2;
15314    private static final int KSM_VOLATILE = 3;
15315
15316    private final long[] getKsmInfo() {
15317        long[] longOut = new long[4];
15318        final int[] SINGLE_LONG_FORMAT = new int[] {
15319            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15320        };
15321        long[] longTmp = new long[1];
15322        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15323                SINGLE_LONG_FORMAT, null, longTmp, null);
15324        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15325        longTmp[0] = 0;
15326        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15327                SINGLE_LONG_FORMAT, null, longTmp, null);
15328        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15329        longTmp[0] = 0;
15330        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15331                SINGLE_LONG_FORMAT, null, longTmp, null);
15332        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15333        longTmp[0] = 0;
15334        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15335                SINGLE_LONG_FORMAT, null, longTmp, null);
15336        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15337        return longOut;
15338    }
15339
15340    private static String stringifySize(long size, int order) {
15341        Locale locale = Locale.US;
15342        switch (order) {
15343            case 1:
15344                return String.format(locale, "%,13d", size);
15345            case 1024:
15346                return String.format(locale, "%,9dK", size / 1024);
15347            case 1024 * 1024:
15348                return String.format(locale, "%,5dM", size / 1024 / 1024);
15349            case 1024 * 1024 * 1024:
15350                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15351            default:
15352                throw new IllegalArgumentException("Invalid size order");
15353        }
15354    }
15355
15356    private static String stringifyKBSize(long size) {
15357        return stringifySize(size * 1024, 1024);
15358    }
15359
15360    // Update this version number in case you change the 'compact' format
15361    private static final int MEMINFO_COMPACT_VERSION = 1;
15362
15363    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15364            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15365        boolean dumpDetails = false;
15366        boolean dumpFullDetails = false;
15367        boolean dumpDalvik = false;
15368        boolean dumpSummaryOnly = false;
15369        boolean dumpUnreachable = false;
15370        boolean oomOnly = false;
15371        boolean isCompact = false;
15372        boolean localOnly = false;
15373        boolean packages = false;
15374        boolean isCheckinRequest = false;
15375        boolean dumpSwapPss = false;
15376
15377        int opti = 0;
15378        while (opti < args.length) {
15379            String opt = args[opti];
15380            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15381                break;
15382            }
15383            opti++;
15384            if ("-a".equals(opt)) {
15385                dumpDetails = true;
15386                dumpFullDetails = true;
15387                dumpDalvik = true;
15388                dumpSwapPss = true;
15389            } else if ("-d".equals(opt)) {
15390                dumpDalvik = true;
15391            } else if ("-c".equals(opt)) {
15392                isCompact = true;
15393            } else if ("-s".equals(opt)) {
15394                dumpDetails = true;
15395                dumpSummaryOnly = true;
15396            } else if ("-S".equals(opt)) {
15397                dumpSwapPss = true;
15398            } else if ("--unreachable".equals(opt)) {
15399                dumpUnreachable = true;
15400            } else if ("--oom".equals(opt)) {
15401                oomOnly = true;
15402            } else if ("--local".equals(opt)) {
15403                localOnly = true;
15404            } else if ("--package".equals(opt)) {
15405                packages = true;
15406            } else if ("--checkin".equals(opt)) {
15407                isCheckinRequest = true;
15408
15409            } else if ("-h".equals(opt)) {
15410                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15411                pw.println("  -a: include all available information for each process.");
15412                pw.println("  -d: include dalvik details.");
15413                pw.println("  -c: dump in a compact machine-parseable representation.");
15414                pw.println("  -s: dump only summary of application memory usage.");
15415                pw.println("  -S: dump also SwapPss.");
15416                pw.println("  --oom: only show processes organized by oom adj.");
15417                pw.println("  --local: only collect details locally, don't call process.");
15418                pw.println("  --package: interpret process arg as package, dumping all");
15419                pw.println("             processes that have loaded that package.");
15420                pw.println("  --checkin: dump data for a checkin");
15421                pw.println("If [process] is specified it can be the name or ");
15422                pw.println("pid of a specific process to dump.");
15423                return;
15424            } else {
15425                pw.println("Unknown argument: " + opt + "; use -h for help");
15426            }
15427        }
15428
15429        long uptime = SystemClock.uptimeMillis();
15430        long realtime = SystemClock.elapsedRealtime();
15431        final long[] tmpLong = new long[1];
15432
15433        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15434        if (procs == null) {
15435            // No Java processes.  Maybe they want to print a native process.
15436            if (args != null && args.length > opti
15437                    && args[opti].charAt(0) != '-') {
15438                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15439                        = new ArrayList<ProcessCpuTracker.Stats>();
15440                updateCpuStatsNow();
15441                int findPid = -1;
15442                try {
15443                    findPid = Integer.parseInt(args[opti]);
15444                } catch (NumberFormatException e) {
15445                }
15446                synchronized (mProcessCpuTracker) {
15447                    final int N = mProcessCpuTracker.countStats();
15448                    for (int i=0; i<N; i++) {
15449                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15450                        if (st.pid == findPid || (st.baseName != null
15451                                && st.baseName.equals(args[opti]))) {
15452                            nativeProcs.add(st);
15453                        }
15454                    }
15455                }
15456                if (nativeProcs.size() > 0) {
15457                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15458                            isCompact);
15459                    Debug.MemoryInfo mi = null;
15460                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15461                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15462                        final int pid = r.pid;
15463                        if (!isCheckinRequest && dumpDetails) {
15464                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15465                        }
15466                        if (mi == null) {
15467                            mi = new Debug.MemoryInfo();
15468                        }
15469                        if (dumpDetails || (!brief && !oomOnly)) {
15470                            Debug.getMemoryInfo(pid, mi);
15471                        } else {
15472                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15473                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15474                        }
15475                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15476                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15477                        if (isCheckinRequest) {
15478                            pw.println();
15479                        }
15480                    }
15481                    return;
15482                }
15483            }
15484            pw.println("No process found for: " + args[opti]);
15485            return;
15486        }
15487
15488        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15489            dumpDetails = true;
15490        }
15491
15492        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15493
15494        String[] innerArgs = new String[args.length-opti];
15495        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15496
15497        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15498        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15499        long nativePss = 0;
15500        long nativeSwapPss = 0;
15501        long dalvikPss = 0;
15502        long dalvikSwapPss = 0;
15503        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15504                EmptyArray.LONG;
15505        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15506                EmptyArray.LONG;
15507        long otherPss = 0;
15508        long otherSwapPss = 0;
15509        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15510        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15511
15512        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15513        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15514        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15515                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15516
15517        long totalPss = 0;
15518        long totalSwapPss = 0;
15519        long cachedPss = 0;
15520        long cachedSwapPss = 0;
15521        boolean hasSwapPss = false;
15522
15523        Debug.MemoryInfo mi = null;
15524        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15525            final ProcessRecord r = procs.get(i);
15526            final IApplicationThread thread;
15527            final int pid;
15528            final int oomAdj;
15529            final boolean hasActivities;
15530            synchronized (this) {
15531                thread = r.thread;
15532                pid = r.pid;
15533                oomAdj = r.getSetAdjWithServices();
15534                hasActivities = r.activities.size() > 0;
15535            }
15536            if (thread != null) {
15537                if (!isCheckinRequest && dumpDetails) {
15538                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15539                }
15540                if (mi == null) {
15541                    mi = new Debug.MemoryInfo();
15542                }
15543                if (dumpDetails || (!brief && !oomOnly)) {
15544                    Debug.getMemoryInfo(pid, mi);
15545                    hasSwapPss = mi.hasSwappedOutPss;
15546                } else {
15547                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15548                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15549                }
15550                if (dumpDetails) {
15551                    if (localOnly) {
15552                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15553                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15554                        if (isCheckinRequest) {
15555                            pw.println();
15556                        }
15557                    } else {
15558                        try {
15559                            pw.flush();
15560                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15561                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15562                        } catch (RemoteException e) {
15563                            if (!isCheckinRequest) {
15564                                pw.println("Got RemoteException!");
15565                                pw.flush();
15566                            }
15567                        }
15568                    }
15569                }
15570
15571                final long myTotalPss = mi.getTotalPss();
15572                final long myTotalUss = mi.getTotalUss();
15573                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15574
15575                synchronized (this) {
15576                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15577                        // Record this for posterity if the process has been stable.
15578                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15579                    }
15580                }
15581
15582                if (!isCheckinRequest && mi != null) {
15583                    totalPss += myTotalPss;
15584                    totalSwapPss += myTotalSwapPss;
15585                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15586                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15587                            myTotalSwapPss, pid, hasActivities);
15588                    procMems.add(pssItem);
15589                    procMemsMap.put(pid, pssItem);
15590
15591                    nativePss += mi.nativePss;
15592                    nativeSwapPss += mi.nativeSwappedOutPss;
15593                    dalvikPss += mi.dalvikPss;
15594                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15595                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15596                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15597                        dalvikSubitemSwapPss[j] +=
15598                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15599                    }
15600                    otherPss += mi.otherPss;
15601                    otherSwapPss += mi.otherSwappedOutPss;
15602                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15603                        long mem = mi.getOtherPss(j);
15604                        miscPss[j] += mem;
15605                        otherPss -= mem;
15606                        mem = mi.getOtherSwappedOutPss(j);
15607                        miscSwapPss[j] += mem;
15608                        otherSwapPss -= mem;
15609                    }
15610
15611                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15612                        cachedPss += myTotalPss;
15613                        cachedSwapPss += myTotalSwapPss;
15614                    }
15615
15616                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15617                        if (oomIndex == (oomPss.length - 1)
15618                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15619                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15620                            oomPss[oomIndex] += myTotalPss;
15621                            oomSwapPss[oomIndex] += myTotalSwapPss;
15622                            if (oomProcs[oomIndex] == null) {
15623                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15624                            }
15625                            oomProcs[oomIndex].add(pssItem);
15626                            break;
15627                        }
15628                    }
15629                }
15630            }
15631        }
15632
15633        long nativeProcTotalPss = 0;
15634
15635        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15636            // If we are showing aggregations, also look for native processes to
15637            // include so that our aggregations are more accurate.
15638            updateCpuStatsNow();
15639            mi = null;
15640            synchronized (mProcessCpuTracker) {
15641                final int N = mProcessCpuTracker.countStats();
15642                for (int i=0; i<N; i++) {
15643                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15644                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15645                        if (mi == null) {
15646                            mi = new Debug.MemoryInfo();
15647                        }
15648                        if (!brief && !oomOnly) {
15649                            Debug.getMemoryInfo(st.pid, mi);
15650                        } else {
15651                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15652                            mi.nativePrivateDirty = (int)tmpLong[0];
15653                        }
15654
15655                        final long myTotalPss = mi.getTotalPss();
15656                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15657                        totalPss += myTotalPss;
15658                        nativeProcTotalPss += myTotalPss;
15659
15660                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15661                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15662                        procMems.add(pssItem);
15663
15664                        nativePss += mi.nativePss;
15665                        nativeSwapPss += mi.nativeSwappedOutPss;
15666                        dalvikPss += mi.dalvikPss;
15667                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15668                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15669                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15670                            dalvikSubitemSwapPss[j] +=
15671                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15672                        }
15673                        otherPss += mi.otherPss;
15674                        otherSwapPss += mi.otherSwappedOutPss;
15675                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15676                            long mem = mi.getOtherPss(j);
15677                            miscPss[j] += mem;
15678                            otherPss -= mem;
15679                            mem = mi.getOtherSwappedOutPss(j);
15680                            miscSwapPss[j] += mem;
15681                            otherSwapPss -= mem;
15682                        }
15683                        oomPss[0] += myTotalPss;
15684                        oomSwapPss[0] += myTotalSwapPss;
15685                        if (oomProcs[0] == null) {
15686                            oomProcs[0] = new ArrayList<MemItem>();
15687                        }
15688                        oomProcs[0].add(pssItem);
15689                    }
15690                }
15691            }
15692
15693            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15694
15695            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15696            final MemItem dalvikItem =
15697                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15698            if (dalvikSubitemPss.length > 0) {
15699                dalvikItem.subitems = new ArrayList<MemItem>();
15700                for (int j=0; j<dalvikSubitemPss.length; j++) {
15701                    final String name = Debug.MemoryInfo.getOtherLabel(
15702                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15703                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15704                                    dalvikSubitemSwapPss[j], j));
15705                }
15706            }
15707            catMems.add(dalvikItem);
15708            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15709            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15710                String label = Debug.MemoryInfo.getOtherLabel(j);
15711                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15712            }
15713
15714            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15715            for (int j=0; j<oomPss.length; j++) {
15716                if (oomPss[j] != 0) {
15717                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15718                            : DUMP_MEM_OOM_LABEL[j];
15719                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15720                            DUMP_MEM_OOM_ADJ[j]);
15721                    item.subitems = oomProcs[j];
15722                    oomMems.add(item);
15723                }
15724            }
15725
15726            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15727            if (!brief && !oomOnly && !isCompact) {
15728                pw.println();
15729                pw.println("Total PSS by process:");
15730                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15731                pw.println();
15732            }
15733            if (!isCompact) {
15734                pw.println("Total PSS by OOM adjustment:");
15735            }
15736            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15737            if (!brief && !oomOnly) {
15738                PrintWriter out = categoryPw != null ? categoryPw : pw;
15739                if (!isCompact) {
15740                    out.println();
15741                    out.println("Total PSS by category:");
15742                }
15743                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15744            }
15745            if (!isCompact) {
15746                pw.println();
15747            }
15748            MemInfoReader memInfo = new MemInfoReader();
15749            memInfo.readMemInfo();
15750            if (nativeProcTotalPss > 0) {
15751                synchronized (this) {
15752                    final long cachedKb = memInfo.getCachedSizeKb();
15753                    final long freeKb = memInfo.getFreeSizeKb();
15754                    final long zramKb = memInfo.getZramTotalSizeKb();
15755                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15756                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15757                            kernelKb*1024, nativeProcTotalPss*1024);
15758                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15759                            nativeProcTotalPss);
15760                }
15761            }
15762            if (!brief) {
15763                if (!isCompact) {
15764                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15765                    pw.print(" (status ");
15766                    switch (mLastMemoryLevel) {
15767                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15768                            pw.println("normal)");
15769                            break;
15770                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15771                            pw.println("moderate)");
15772                            break;
15773                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15774                            pw.println("low)");
15775                            break;
15776                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15777                            pw.println("critical)");
15778                            break;
15779                        default:
15780                            pw.print(mLastMemoryLevel);
15781                            pw.println(")");
15782                            break;
15783                    }
15784                    pw.print(" Free RAM: ");
15785                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15786                            + memInfo.getFreeSizeKb()));
15787                    pw.print(" (");
15788                    pw.print(stringifyKBSize(cachedPss));
15789                    pw.print(" cached pss + ");
15790                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15791                    pw.print(" cached kernel + ");
15792                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15793                    pw.println(" free)");
15794                } else {
15795                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15796                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15797                            + memInfo.getFreeSizeKb()); pw.print(",");
15798                    pw.println(totalPss - cachedPss);
15799                }
15800            }
15801            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15802                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15803                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15804            if (!isCompact) {
15805                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15806                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15807                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15808                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15809                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15810            } else {
15811                pw.print("lostram,"); pw.println(lostRAM);
15812            }
15813            if (!brief) {
15814                if (memInfo.getZramTotalSizeKb() != 0) {
15815                    if (!isCompact) {
15816                        pw.print("     ZRAM: ");
15817                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15818                                pw.print(" physical used for ");
15819                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15820                                        - memInfo.getSwapFreeSizeKb()));
15821                                pw.print(" in swap (");
15822                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15823                                pw.println(" total swap)");
15824                    } else {
15825                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15826                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15827                                pw.println(memInfo.getSwapFreeSizeKb());
15828                    }
15829                }
15830                final long[] ksm = getKsmInfo();
15831                if (!isCompact) {
15832                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15833                            || ksm[KSM_VOLATILE] != 0) {
15834                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15835                                pw.print(" saved from shared ");
15836                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15837                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15838                                pw.print(" unshared; ");
15839                                pw.print(stringifyKBSize(
15840                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15841                    }
15842                    pw.print("   Tuning: ");
15843                    pw.print(ActivityManager.staticGetMemoryClass());
15844                    pw.print(" (large ");
15845                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15846                    pw.print("), oom ");
15847                    pw.print(stringifySize(
15848                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15849                    pw.print(", restore limit ");
15850                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15851                    if (ActivityManager.isLowRamDeviceStatic()) {
15852                        pw.print(" (low-ram)");
15853                    }
15854                    if (ActivityManager.isHighEndGfx()) {
15855                        pw.print(" (high-end-gfx)");
15856                    }
15857                    pw.println();
15858                } else {
15859                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15860                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15861                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15862                    pw.print("tuning,");
15863                    pw.print(ActivityManager.staticGetMemoryClass());
15864                    pw.print(',');
15865                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15866                    pw.print(',');
15867                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15868                    if (ActivityManager.isLowRamDeviceStatic()) {
15869                        pw.print(",low-ram");
15870                    }
15871                    if (ActivityManager.isHighEndGfx()) {
15872                        pw.print(",high-end-gfx");
15873                    }
15874                    pw.println();
15875                }
15876            }
15877        }
15878    }
15879
15880    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15881            long memtrack, String name) {
15882        sb.append("  ");
15883        sb.append(ProcessList.makeOomAdjString(oomAdj));
15884        sb.append(' ');
15885        sb.append(ProcessList.makeProcStateString(procState));
15886        sb.append(' ');
15887        ProcessList.appendRamKb(sb, pss);
15888        sb.append(": ");
15889        sb.append(name);
15890        if (memtrack > 0) {
15891            sb.append(" (");
15892            sb.append(stringifyKBSize(memtrack));
15893            sb.append(" memtrack)");
15894        }
15895    }
15896
15897    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15898        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15899        sb.append(" (pid ");
15900        sb.append(mi.pid);
15901        sb.append(") ");
15902        sb.append(mi.adjType);
15903        sb.append('\n');
15904        if (mi.adjReason != null) {
15905            sb.append("                      ");
15906            sb.append(mi.adjReason);
15907            sb.append('\n');
15908        }
15909    }
15910
15911    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15912        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15913        for (int i=0, N=memInfos.size(); i<N; i++) {
15914            ProcessMemInfo mi = memInfos.get(i);
15915            infoMap.put(mi.pid, mi);
15916        }
15917        updateCpuStatsNow();
15918        long[] memtrackTmp = new long[1];
15919        synchronized (mProcessCpuTracker) {
15920            final int N = mProcessCpuTracker.countStats();
15921            for (int i=0; i<N; i++) {
15922                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15923                if (st.vsize > 0) {
15924                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15925                    if (pss > 0) {
15926                        if (infoMap.indexOfKey(st.pid) < 0) {
15927                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15928                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15929                            mi.pss = pss;
15930                            mi.memtrack = memtrackTmp[0];
15931                            memInfos.add(mi);
15932                        }
15933                    }
15934                }
15935            }
15936        }
15937
15938        long totalPss = 0;
15939        long totalMemtrack = 0;
15940        for (int i=0, N=memInfos.size(); i<N; i++) {
15941            ProcessMemInfo mi = memInfos.get(i);
15942            if (mi.pss == 0) {
15943                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15944                mi.memtrack = memtrackTmp[0];
15945            }
15946            totalPss += mi.pss;
15947            totalMemtrack += mi.memtrack;
15948        }
15949        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15950            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15951                if (lhs.oomAdj != rhs.oomAdj) {
15952                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15953                }
15954                if (lhs.pss != rhs.pss) {
15955                    return lhs.pss < rhs.pss ? 1 : -1;
15956                }
15957                return 0;
15958            }
15959        });
15960
15961        StringBuilder tag = new StringBuilder(128);
15962        StringBuilder stack = new StringBuilder(128);
15963        tag.append("Low on memory -- ");
15964        appendMemBucket(tag, totalPss, "total", false);
15965        appendMemBucket(stack, totalPss, "total", true);
15966
15967        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15968        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15969        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15970
15971        boolean firstLine = true;
15972        int lastOomAdj = Integer.MIN_VALUE;
15973        long extraNativeRam = 0;
15974        long extraNativeMemtrack = 0;
15975        long cachedPss = 0;
15976        for (int i=0, N=memInfos.size(); i<N; i++) {
15977            ProcessMemInfo mi = memInfos.get(i);
15978
15979            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15980                cachedPss += mi.pss;
15981            }
15982
15983            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15984                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15985                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15986                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15987                if (lastOomAdj != mi.oomAdj) {
15988                    lastOomAdj = mi.oomAdj;
15989                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15990                        tag.append(" / ");
15991                    }
15992                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15993                        if (firstLine) {
15994                            stack.append(":");
15995                            firstLine = false;
15996                        }
15997                        stack.append("\n\t at ");
15998                    } else {
15999                        stack.append("$");
16000                    }
16001                } else {
16002                    tag.append(" ");
16003                    stack.append("$");
16004                }
16005                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16006                    appendMemBucket(tag, mi.pss, mi.name, false);
16007                }
16008                appendMemBucket(stack, mi.pss, mi.name, true);
16009                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16010                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16011                    stack.append("(");
16012                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16013                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16014                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16015                            stack.append(":");
16016                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16017                        }
16018                    }
16019                    stack.append(")");
16020                }
16021            }
16022
16023            appendMemInfo(fullNativeBuilder, mi);
16024            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16025                // The short form only has native processes that are >= 512K.
16026                if (mi.pss >= 512) {
16027                    appendMemInfo(shortNativeBuilder, mi);
16028                } else {
16029                    extraNativeRam += mi.pss;
16030                    extraNativeMemtrack += mi.memtrack;
16031                }
16032            } else {
16033                // Short form has all other details, but if we have collected RAM
16034                // from smaller native processes let's dump a summary of that.
16035                if (extraNativeRam > 0) {
16036                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16037                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16038                    shortNativeBuilder.append('\n');
16039                    extraNativeRam = 0;
16040                }
16041                appendMemInfo(fullJavaBuilder, mi);
16042            }
16043        }
16044
16045        fullJavaBuilder.append("           ");
16046        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16047        fullJavaBuilder.append(": TOTAL");
16048        if (totalMemtrack > 0) {
16049            fullJavaBuilder.append(" (");
16050            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16051            fullJavaBuilder.append(" memtrack)");
16052        } else {
16053        }
16054        fullJavaBuilder.append("\n");
16055
16056        MemInfoReader memInfo = new MemInfoReader();
16057        memInfo.readMemInfo();
16058        final long[] infos = memInfo.getRawInfo();
16059
16060        StringBuilder memInfoBuilder = new StringBuilder(1024);
16061        Debug.getMemInfo(infos);
16062        memInfoBuilder.append("  MemInfo: ");
16063        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16064        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16065        memInfoBuilder.append(stringifyKBSize(
16066                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16067        memInfoBuilder.append(stringifyKBSize(
16068                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16069        memInfoBuilder.append(stringifyKBSize(
16070                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16071        memInfoBuilder.append("           ");
16072        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16073        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16074        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16075        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16076        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16077            memInfoBuilder.append("  ZRAM: ");
16078            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16079            memInfoBuilder.append(" RAM, ");
16080            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16081            memInfoBuilder.append(" swap total, ");
16082            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16083            memInfoBuilder.append(" swap free\n");
16084        }
16085        final long[] ksm = getKsmInfo();
16086        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16087                || ksm[KSM_VOLATILE] != 0) {
16088            memInfoBuilder.append("  KSM: ");
16089            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16090            memInfoBuilder.append(" saved from shared ");
16091            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16092            memInfoBuilder.append("\n       ");
16093            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16094            memInfoBuilder.append(" unshared; ");
16095            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16096            memInfoBuilder.append(" volatile\n");
16097        }
16098        memInfoBuilder.append("  Free RAM: ");
16099        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16100                + memInfo.getFreeSizeKb()));
16101        memInfoBuilder.append("\n");
16102        memInfoBuilder.append("  Used RAM: ");
16103        memInfoBuilder.append(stringifyKBSize(
16104                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16105        memInfoBuilder.append("\n");
16106        memInfoBuilder.append("  Lost RAM: ");
16107        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16108                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16109                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16110        memInfoBuilder.append("\n");
16111        Slog.i(TAG, "Low on memory:");
16112        Slog.i(TAG, shortNativeBuilder.toString());
16113        Slog.i(TAG, fullJavaBuilder.toString());
16114        Slog.i(TAG, memInfoBuilder.toString());
16115
16116        StringBuilder dropBuilder = new StringBuilder(1024);
16117        /*
16118        StringWriter oomSw = new StringWriter();
16119        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16120        StringWriter catSw = new StringWriter();
16121        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16122        String[] emptyArgs = new String[] { };
16123        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16124        oomPw.flush();
16125        String oomString = oomSw.toString();
16126        */
16127        dropBuilder.append("Low on memory:");
16128        dropBuilder.append(stack);
16129        dropBuilder.append('\n');
16130        dropBuilder.append(fullNativeBuilder);
16131        dropBuilder.append(fullJavaBuilder);
16132        dropBuilder.append('\n');
16133        dropBuilder.append(memInfoBuilder);
16134        dropBuilder.append('\n');
16135        /*
16136        dropBuilder.append(oomString);
16137        dropBuilder.append('\n');
16138        */
16139        StringWriter catSw = new StringWriter();
16140        synchronized (ActivityManagerService.this) {
16141            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16142            String[] emptyArgs = new String[] { };
16143            catPw.println();
16144            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16145            catPw.println();
16146            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16147                    false, false, null);
16148            catPw.println();
16149            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16150            catPw.flush();
16151        }
16152        dropBuilder.append(catSw.toString());
16153        addErrorToDropBox("lowmem", null, "system_server", null,
16154                null, tag.toString(), dropBuilder.toString(), null, null);
16155        //Slog.i(TAG, "Sent to dropbox:");
16156        //Slog.i(TAG, dropBuilder.toString());
16157        synchronized (ActivityManagerService.this) {
16158            long now = SystemClock.uptimeMillis();
16159            if (mLastMemUsageReportTime < now) {
16160                mLastMemUsageReportTime = now;
16161            }
16162        }
16163    }
16164
16165    /**
16166     * Searches array of arguments for the specified string
16167     * @param args array of argument strings
16168     * @param value value to search for
16169     * @return true if the value is contained in the array
16170     */
16171    private static boolean scanArgs(String[] args, String value) {
16172        if (args != null) {
16173            for (String arg : args) {
16174                if (value.equals(arg)) {
16175                    return true;
16176                }
16177            }
16178        }
16179        return false;
16180    }
16181
16182    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16183            ContentProviderRecord cpr, boolean always) {
16184        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16185
16186        if (!inLaunching || always) {
16187            synchronized (cpr) {
16188                cpr.launchingApp = null;
16189                cpr.notifyAll();
16190            }
16191            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16192            String names[] = cpr.info.authority.split(";");
16193            for (int j = 0; j < names.length; j++) {
16194                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16195            }
16196        }
16197
16198        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16199            ContentProviderConnection conn = cpr.connections.get(i);
16200            if (conn.waiting) {
16201                // If this connection is waiting for the provider, then we don't
16202                // need to mess with its process unless we are always removing
16203                // or for some reason the provider is not currently launching.
16204                if (inLaunching && !always) {
16205                    continue;
16206                }
16207            }
16208            ProcessRecord capp = conn.client;
16209            conn.dead = true;
16210            if (conn.stableCount > 0) {
16211                if (!capp.persistent && capp.thread != null
16212                        && capp.pid != 0
16213                        && capp.pid != MY_PID) {
16214                    capp.kill("depends on provider "
16215                            + cpr.name.flattenToShortString()
16216                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16217                }
16218            } else if (capp.thread != null && conn.provider.provider != null) {
16219                try {
16220                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16221                } catch (RemoteException e) {
16222                }
16223                // In the protocol here, we don't expect the client to correctly
16224                // clean up this connection, we'll just remove it.
16225                cpr.connections.remove(i);
16226                if (conn.client.conProviders.remove(conn)) {
16227                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16228                }
16229            }
16230        }
16231
16232        if (inLaunching && always) {
16233            mLaunchingProviders.remove(cpr);
16234        }
16235        return inLaunching;
16236    }
16237
16238    /**
16239     * Main code for cleaning up a process when it has gone away.  This is
16240     * called both as a result of the process dying, or directly when stopping
16241     * a process when running in single process mode.
16242     *
16243     * @return Returns true if the given process has been restarted, so the
16244     * app that was passed in must remain on the process lists.
16245     */
16246    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16247            boolean restarting, boolean allowRestart, int index) {
16248        if (index >= 0) {
16249            removeLruProcessLocked(app);
16250            ProcessList.remove(app.pid);
16251        }
16252
16253        mProcessesToGc.remove(app);
16254        mPendingPssProcesses.remove(app);
16255
16256        // Dismiss any open dialogs.
16257        if (app.crashDialog != null && !app.forceCrashReport) {
16258            app.crashDialog.dismiss();
16259            app.crashDialog = null;
16260        }
16261        if (app.anrDialog != null) {
16262            app.anrDialog.dismiss();
16263            app.anrDialog = null;
16264        }
16265        if (app.waitDialog != null) {
16266            app.waitDialog.dismiss();
16267            app.waitDialog = null;
16268        }
16269
16270        app.crashing = false;
16271        app.notResponding = false;
16272
16273        app.resetPackageList(mProcessStats);
16274        app.unlinkDeathRecipient();
16275        app.makeInactive(mProcessStats);
16276        app.waitingToKill = null;
16277        app.forcingToForeground = null;
16278        updateProcessForegroundLocked(app, false, false);
16279        app.foregroundActivities = false;
16280        app.hasShownUi = false;
16281        app.treatLikeActivity = false;
16282        app.hasAboveClient = false;
16283        app.hasClientActivities = false;
16284
16285        mServices.killServicesLocked(app, allowRestart);
16286
16287        boolean restart = false;
16288
16289        // Remove published content providers.
16290        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16291            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16292            final boolean always = app.bad || !allowRestart;
16293            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16294            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16295                // We left the provider in the launching list, need to
16296                // restart it.
16297                restart = true;
16298            }
16299
16300            cpr.provider = null;
16301            cpr.proc = null;
16302        }
16303        app.pubProviders.clear();
16304
16305        // Take care of any launching providers waiting for this process.
16306        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16307            restart = true;
16308        }
16309
16310        // Unregister from connected content providers.
16311        if (!app.conProviders.isEmpty()) {
16312            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16313                ContentProviderConnection conn = app.conProviders.get(i);
16314                conn.provider.connections.remove(conn);
16315                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16316                        conn.provider.name);
16317            }
16318            app.conProviders.clear();
16319        }
16320
16321        // At this point there may be remaining entries in mLaunchingProviders
16322        // where we were the only one waiting, so they are no longer of use.
16323        // Look for these and clean up if found.
16324        // XXX Commented out for now.  Trying to figure out a way to reproduce
16325        // the actual situation to identify what is actually going on.
16326        if (false) {
16327            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16328                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16329                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16330                    synchronized (cpr) {
16331                        cpr.launchingApp = null;
16332                        cpr.notifyAll();
16333                    }
16334                }
16335            }
16336        }
16337
16338        skipCurrentReceiverLocked(app);
16339
16340        // Unregister any receivers.
16341        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16342            removeReceiverLocked(app.receivers.valueAt(i));
16343        }
16344        app.receivers.clear();
16345
16346        // If the app is undergoing backup, tell the backup manager about it
16347        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16348            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16349                    + mBackupTarget.appInfo + " died during backup");
16350            try {
16351                IBackupManager bm = IBackupManager.Stub.asInterface(
16352                        ServiceManager.getService(Context.BACKUP_SERVICE));
16353                bm.agentDisconnected(app.info.packageName);
16354            } catch (RemoteException e) {
16355                // can't happen; backup manager is local
16356            }
16357        }
16358
16359        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16360            ProcessChangeItem item = mPendingProcessChanges.get(i);
16361            if (item.pid == app.pid) {
16362                mPendingProcessChanges.remove(i);
16363                mAvailProcessChanges.add(item);
16364            }
16365        }
16366        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16367                null).sendToTarget();
16368
16369        // If the caller is restarting this app, then leave it in its
16370        // current lists and let the caller take care of it.
16371        if (restarting) {
16372            return false;
16373        }
16374
16375        if (!app.persistent || app.isolated) {
16376            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16377                    "Removing non-persistent process during cleanup: " + app);
16378            removeProcessNameLocked(app.processName, app.uid);
16379            if (mHeavyWeightProcess == app) {
16380                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16381                        mHeavyWeightProcess.userId, 0));
16382                mHeavyWeightProcess = null;
16383            }
16384        } else if (!app.removed) {
16385            // This app is persistent, so we need to keep its record around.
16386            // If it is not already on the pending app list, add it there
16387            // and start a new process for it.
16388            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16389                mPersistentStartingProcesses.add(app);
16390                restart = true;
16391            }
16392        }
16393        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16394                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16395        mProcessesOnHold.remove(app);
16396
16397        if (app == mHomeProcess) {
16398            mHomeProcess = null;
16399        }
16400        if (app == mPreviousProcess) {
16401            mPreviousProcess = null;
16402        }
16403
16404        if (restart && !app.isolated) {
16405            // We have components that still need to be running in the
16406            // process, so re-launch it.
16407            if (index < 0) {
16408                ProcessList.remove(app.pid);
16409            }
16410            addProcessNameLocked(app);
16411            startProcessLocked(app, "restart", app.processName);
16412            return true;
16413        } else if (app.pid > 0 && app.pid != MY_PID) {
16414            // Goodbye!
16415            boolean removed;
16416            synchronized (mPidsSelfLocked) {
16417                mPidsSelfLocked.remove(app.pid);
16418                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16419            }
16420            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16421            if (app.isolated) {
16422                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16423            }
16424            app.setPid(0);
16425        }
16426        return false;
16427    }
16428
16429    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16430        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16431            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16432            if (cpr.launchingApp == app) {
16433                return true;
16434            }
16435        }
16436        return false;
16437    }
16438
16439    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16440        // Look through the content providers we are waiting to have launched,
16441        // and if any run in this process then either schedule a restart of
16442        // the process or kill the client waiting for it if this process has
16443        // gone bad.
16444        boolean restart = false;
16445        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16446            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16447            if (cpr.launchingApp == app) {
16448                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16449                    restart = true;
16450                } else {
16451                    removeDyingProviderLocked(app, cpr, true);
16452                }
16453            }
16454        }
16455        return restart;
16456    }
16457
16458    // =========================================================
16459    // SERVICES
16460    // =========================================================
16461
16462    @Override
16463    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16464            int flags) {
16465        enforceNotIsolatedCaller("getServices");
16466        synchronized (this) {
16467            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16468        }
16469    }
16470
16471    @Override
16472    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16473        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16474        synchronized (this) {
16475            return mServices.getRunningServiceControlPanelLocked(name);
16476        }
16477    }
16478
16479    @Override
16480    public ComponentName startService(IApplicationThread caller, Intent service,
16481            String resolvedType, String callingPackage, int userId)
16482            throws TransactionTooLargeException {
16483        enforceNotIsolatedCaller("startService");
16484        // Refuse possible leaked file descriptors
16485        if (service != null && service.hasFileDescriptors() == true) {
16486            throw new IllegalArgumentException("File descriptors passed in Intent");
16487        }
16488
16489        if (callingPackage == null) {
16490            throw new IllegalArgumentException("callingPackage cannot be null");
16491        }
16492
16493        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16494                "startService: " + service + " type=" + resolvedType);
16495        synchronized(this) {
16496            final int callingPid = Binder.getCallingPid();
16497            final int callingUid = Binder.getCallingUid();
16498            final long origId = Binder.clearCallingIdentity();
16499            ComponentName res = mServices.startServiceLocked(caller, service,
16500                    resolvedType, callingPid, callingUid, callingPackage, userId);
16501            Binder.restoreCallingIdentity(origId);
16502            return res;
16503        }
16504    }
16505
16506    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16507            String callingPackage, int userId)
16508            throws TransactionTooLargeException {
16509        synchronized(this) {
16510            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16511                    "startServiceInPackage: " + service + " type=" + resolvedType);
16512            final long origId = Binder.clearCallingIdentity();
16513            ComponentName res = mServices.startServiceLocked(null, service,
16514                    resolvedType, -1, uid, callingPackage, userId);
16515            Binder.restoreCallingIdentity(origId);
16516            return res;
16517        }
16518    }
16519
16520    @Override
16521    public int stopService(IApplicationThread caller, Intent service,
16522            String resolvedType, int userId) {
16523        enforceNotIsolatedCaller("stopService");
16524        // Refuse possible leaked file descriptors
16525        if (service != null && service.hasFileDescriptors() == true) {
16526            throw new IllegalArgumentException("File descriptors passed in Intent");
16527        }
16528
16529        synchronized(this) {
16530            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16531        }
16532    }
16533
16534    @Override
16535    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16536        enforceNotIsolatedCaller("peekService");
16537        // Refuse possible leaked file descriptors
16538        if (service != null && service.hasFileDescriptors() == true) {
16539            throw new IllegalArgumentException("File descriptors passed in Intent");
16540        }
16541
16542        if (callingPackage == null) {
16543            throw new IllegalArgumentException("callingPackage cannot be null");
16544        }
16545
16546        synchronized(this) {
16547            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16548        }
16549    }
16550
16551    @Override
16552    public boolean stopServiceToken(ComponentName className, IBinder token,
16553            int startId) {
16554        synchronized(this) {
16555            return mServices.stopServiceTokenLocked(className, token, startId);
16556        }
16557    }
16558
16559    @Override
16560    public void setServiceForeground(ComponentName className, IBinder token,
16561            int id, Notification notification, int flags) {
16562        synchronized(this) {
16563            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16564        }
16565    }
16566
16567    @Override
16568    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16569            boolean requireFull, String name, String callerPackage) {
16570        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16571                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16572    }
16573
16574    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16575            String className, int flags) {
16576        boolean result = false;
16577        // For apps that don't have pre-defined UIDs, check for permission
16578        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16579            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16580                if (ActivityManager.checkUidPermission(
16581                        INTERACT_ACROSS_USERS,
16582                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16583                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16584                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16585                            + " requests FLAG_SINGLE_USER, but app does not hold "
16586                            + INTERACT_ACROSS_USERS;
16587                    Slog.w(TAG, msg);
16588                    throw new SecurityException(msg);
16589                }
16590                // Permission passed
16591                result = true;
16592            }
16593        } else if ("system".equals(componentProcessName)) {
16594            result = true;
16595        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16596            // Phone app and persistent apps are allowed to export singleuser providers.
16597            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16598                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16599        }
16600        if (DEBUG_MU) Slog.v(TAG_MU,
16601                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16602                + Integer.toHexString(flags) + ") = " + result);
16603        return result;
16604    }
16605
16606    /**
16607     * Checks to see if the caller is in the same app as the singleton
16608     * component, or the component is in a special app. It allows special apps
16609     * to export singleton components but prevents exporting singleton
16610     * components for regular apps.
16611     */
16612    boolean isValidSingletonCall(int callingUid, int componentUid) {
16613        int componentAppId = UserHandle.getAppId(componentUid);
16614        return UserHandle.isSameApp(callingUid, componentUid)
16615                || componentAppId == Process.SYSTEM_UID
16616                || componentAppId == Process.PHONE_UID
16617                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16618                        == PackageManager.PERMISSION_GRANTED;
16619    }
16620
16621    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16622            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16623            int userId) throws TransactionTooLargeException {
16624        enforceNotIsolatedCaller("bindService");
16625
16626        // Refuse possible leaked file descriptors
16627        if (service != null && service.hasFileDescriptors() == true) {
16628            throw new IllegalArgumentException("File descriptors passed in Intent");
16629        }
16630
16631        if (callingPackage == null) {
16632            throw new IllegalArgumentException("callingPackage cannot be null");
16633        }
16634
16635        synchronized(this) {
16636            return mServices.bindServiceLocked(caller, token, service,
16637                    resolvedType, connection, flags, callingPackage, userId);
16638        }
16639    }
16640
16641    public boolean unbindService(IServiceConnection connection) {
16642        synchronized (this) {
16643            return mServices.unbindServiceLocked(connection);
16644        }
16645    }
16646
16647    public void publishService(IBinder token, Intent intent, IBinder service) {
16648        // Refuse possible leaked file descriptors
16649        if (intent != null && intent.hasFileDescriptors() == true) {
16650            throw new IllegalArgumentException("File descriptors passed in Intent");
16651        }
16652
16653        synchronized(this) {
16654            if (!(token instanceof ServiceRecord)) {
16655                throw new IllegalArgumentException("Invalid service token");
16656            }
16657            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16658        }
16659    }
16660
16661    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16662        // Refuse possible leaked file descriptors
16663        if (intent != null && intent.hasFileDescriptors() == true) {
16664            throw new IllegalArgumentException("File descriptors passed in Intent");
16665        }
16666
16667        synchronized(this) {
16668            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16669        }
16670    }
16671
16672    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16673        synchronized(this) {
16674            if (!(token instanceof ServiceRecord)) {
16675                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16676                throw new IllegalArgumentException("Invalid service token");
16677            }
16678            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16679        }
16680    }
16681
16682    // =========================================================
16683    // BACKUP AND RESTORE
16684    // =========================================================
16685
16686    // Cause the target app to be launched if necessary and its backup agent
16687    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16688    // activity manager to announce its creation.
16689    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16690        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16691                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16692        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16693
16694        synchronized(this) {
16695            // !!! TODO: currently no check here that we're already bound
16696            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16697            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16698            synchronized (stats) {
16699                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16700            }
16701
16702            // Backup agent is now in use, its package can't be stopped.
16703            try {
16704                AppGlobals.getPackageManager().setPackageStoppedState(
16705                        app.packageName, false, UserHandle.getUserId(app.uid));
16706            } catch (RemoteException e) {
16707            } catch (IllegalArgumentException e) {
16708                Slog.w(TAG, "Failed trying to unstop package "
16709                        + app.packageName + ": " + e);
16710            }
16711
16712            BackupRecord r = new BackupRecord(ss, app, backupMode);
16713            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16714                    ? new ComponentName(app.packageName, app.backupAgentName)
16715                    : new ComponentName("android", "FullBackupAgent");
16716            // startProcessLocked() returns existing proc's record if it's already running
16717            ProcessRecord proc = startProcessLocked(app.processName, app,
16718                    false, 0, "backup", hostingName, false, false, false);
16719            if (proc == null) {
16720                Slog.e(TAG, "Unable to start backup agent process " + r);
16721                return false;
16722            }
16723
16724            r.app = proc;
16725            mBackupTarget = r;
16726            mBackupAppName = app.packageName;
16727
16728            // Try not to kill the process during backup
16729            updateOomAdjLocked(proc);
16730
16731            // If the process is already attached, schedule the creation of the backup agent now.
16732            // If it is not yet live, this will be done when it attaches to the framework.
16733            if (proc.thread != null) {
16734                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16735                try {
16736                    proc.thread.scheduleCreateBackupAgent(app,
16737                            compatibilityInfoForPackageLocked(app), backupMode);
16738                } catch (RemoteException e) {
16739                    // Will time out on the backup manager side
16740                }
16741            } else {
16742                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16743            }
16744            // Invariants: at this point, the target app process exists and the application
16745            // is either already running or in the process of coming up.  mBackupTarget and
16746            // mBackupAppName describe the app, so that when it binds back to the AM we
16747            // know that it's scheduled for a backup-agent operation.
16748        }
16749
16750        return true;
16751    }
16752
16753    @Override
16754    public void clearPendingBackup() {
16755        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16756        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16757
16758        synchronized (this) {
16759            mBackupTarget = null;
16760            mBackupAppName = null;
16761        }
16762    }
16763
16764    // A backup agent has just come up
16765    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16766        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16767                + " = " + agent);
16768
16769        synchronized(this) {
16770            if (!agentPackageName.equals(mBackupAppName)) {
16771                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16772                return;
16773            }
16774        }
16775
16776        long oldIdent = Binder.clearCallingIdentity();
16777        try {
16778            IBackupManager bm = IBackupManager.Stub.asInterface(
16779                    ServiceManager.getService(Context.BACKUP_SERVICE));
16780            bm.agentConnected(agentPackageName, agent);
16781        } catch (RemoteException e) {
16782            // can't happen; the backup manager service is local
16783        } catch (Exception e) {
16784            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16785            e.printStackTrace();
16786        } finally {
16787            Binder.restoreCallingIdentity(oldIdent);
16788        }
16789    }
16790
16791    // done with this agent
16792    public void unbindBackupAgent(ApplicationInfo appInfo) {
16793        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16794        if (appInfo == null) {
16795            Slog.w(TAG, "unbind backup agent for null app");
16796            return;
16797        }
16798
16799        synchronized(this) {
16800            try {
16801                if (mBackupAppName == null) {
16802                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16803                    return;
16804                }
16805
16806                if (!mBackupAppName.equals(appInfo.packageName)) {
16807                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16808                    return;
16809                }
16810
16811                // Not backing this app up any more; reset its OOM adjustment
16812                final ProcessRecord proc = mBackupTarget.app;
16813                updateOomAdjLocked(proc);
16814
16815                // If the app crashed during backup, 'thread' will be null here
16816                if (proc.thread != null) {
16817                    try {
16818                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16819                                compatibilityInfoForPackageLocked(appInfo));
16820                    } catch (Exception e) {
16821                        Slog.e(TAG, "Exception when unbinding backup agent:");
16822                        e.printStackTrace();
16823                    }
16824                }
16825            } finally {
16826                mBackupTarget = null;
16827                mBackupAppName = null;
16828            }
16829        }
16830    }
16831    // =========================================================
16832    // BROADCASTS
16833    // =========================================================
16834
16835    boolean isPendingBroadcastProcessLocked(int pid) {
16836        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16837                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16838    }
16839
16840    void skipPendingBroadcastLocked(int pid) {
16841            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16842            for (BroadcastQueue queue : mBroadcastQueues) {
16843                queue.skipPendingBroadcastLocked(pid);
16844            }
16845    }
16846
16847    // The app just attached; send any pending broadcasts that it should receive
16848    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16849        boolean didSomething = false;
16850        for (BroadcastQueue queue : mBroadcastQueues) {
16851            didSomething |= queue.sendPendingBroadcastsLocked(app);
16852        }
16853        return didSomething;
16854    }
16855
16856    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16857            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16858        enforceNotIsolatedCaller("registerReceiver");
16859        ArrayList<Intent> stickyIntents = null;
16860        ProcessRecord callerApp = null;
16861        int callingUid;
16862        int callingPid;
16863        synchronized(this) {
16864            if (caller != null) {
16865                callerApp = getRecordForAppLocked(caller);
16866                if (callerApp == null) {
16867                    throw new SecurityException(
16868                            "Unable to find app for caller " + caller
16869                            + " (pid=" + Binder.getCallingPid()
16870                            + ") when registering receiver " + receiver);
16871                }
16872                if (callerApp.info.uid != Process.SYSTEM_UID &&
16873                        !callerApp.pkgList.containsKey(callerPackage) &&
16874                        !"android".equals(callerPackage)) {
16875                    throw new SecurityException("Given caller package " + callerPackage
16876                            + " is not running in process " + callerApp);
16877                }
16878                callingUid = callerApp.info.uid;
16879                callingPid = callerApp.pid;
16880            } else {
16881                callerPackage = null;
16882                callingUid = Binder.getCallingUid();
16883                callingPid = Binder.getCallingPid();
16884            }
16885
16886            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16887                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16888
16889            Iterator<String> actions = filter.actionsIterator();
16890            if (actions == null) {
16891                ArrayList<String> noAction = new ArrayList<String>(1);
16892                noAction.add(null);
16893                actions = noAction.iterator();
16894            }
16895
16896            // Collect stickies of users
16897            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16898            while (actions.hasNext()) {
16899                String action = actions.next();
16900                for (int id : userIds) {
16901                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16902                    if (stickies != null) {
16903                        ArrayList<Intent> intents = stickies.get(action);
16904                        if (intents != null) {
16905                            if (stickyIntents == null) {
16906                                stickyIntents = new ArrayList<Intent>();
16907                            }
16908                            stickyIntents.addAll(intents);
16909                        }
16910                    }
16911                }
16912            }
16913        }
16914
16915        ArrayList<Intent> allSticky = null;
16916        if (stickyIntents != null) {
16917            final ContentResolver resolver = mContext.getContentResolver();
16918            // Look for any matching sticky broadcasts...
16919            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16920                Intent intent = stickyIntents.get(i);
16921                // If intent has scheme "content", it will need to acccess
16922                // provider that needs to lock mProviderMap in ActivityThread
16923                // and also it may need to wait application response, so we
16924                // cannot lock ActivityManagerService here.
16925                if (filter.match(resolver, intent, true, TAG) >= 0) {
16926                    if (allSticky == null) {
16927                        allSticky = new ArrayList<Intent>();
16928                    }
16929                    allSticky.add(intent);
16930                }
16931            }
16932        }
16933
16934        // The first sticky in the list is returned directly back to the client.
16935        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16936        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16937        if (receiver == null) {
16938            return sticky;
16939        }
16940
16941        synchronized (this) {
16942            if (callerApp != null && (callerApp.thread == null
16943                    || callerApp.thread.asBinder() != caller.asBinder())) {
16944                // Original caller already died
16945                return null;
16946            }
16947            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16948            if (rl == null) {
16949                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16950                        userId, receiver);
16951                if (rl.app != null) {
16952                    rl.app.receivers.add(rl);
16953                } else {
16954                    try {
16955                        receiver.asBinder().linkToDeath(rl, 0);
16956                    } catch (RemoteException e) {
16957                        return sticky;
16958                    }
16959                    rl.linkedToDeath = true;
16960                }
16961                mRegisteredReceivers.put(receiver.asBinder(), rl);
16962            } else if (rl.uid != callingUid) {
16963                throw new IllegalArgumentException(
16964                        "Receiver requested to register for uid " + callingUid
16965                        + " was previously registered for uid " + rl.uid);
16966            } else if (rl.pid != callingPid) {
16967                throw new IllegalArgumentException(
16968                        "Receiver requested to register for pid " + callingPid
16969                        + " was previously registered for pid " + rl.pid);
16970            } else if (rl.userId != userId) {
16971                throw new IllegalArgumentException(
16972                        "Receiver requested to register for user " + userId
16973                        + " was previously registered for user " + rl.userId);
16974            }
16975            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16976                    permission, callingUid, userId);
16977            rl.add(bf);
16978            if (!bf.debugCheck()) {
16979                Slog.w(TAG, "==> For Dynamic broadcast");
16980            }
16981            mReceiverResolver.addFilter(bf);
16982
16983            // Enqueue broadcasts for all existing stickies that match
16984            // this filter.
16985            if (allSticky != null) {
16986                ArrayList receivers = new ArrayList();
16987                receivers.add(bf);
16988
16989                final int stickyCount = allSticky.size();
16990                for (int i = 0; i < stickyCount; i++) {
16991                    Intent intent = allSticky.get(i);
16992                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16993                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16994                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16995                            null, 0, null, null, false, true, true, -1);
16996                    queue.enqueueParallelBroadcastLocked(r);
16997                    queue.scheduleBroadcastsLocked();
16998                }
16999            }
17000
17001            return sticky;
17002        }
17003    }
17004
17005    public void unregisterReceiver(IIntentReceiver receiver) {
17006        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17007
17008        final long origId = Binder.clearCallingIdentity();
17009        try {
17010            boolean doTrim = false;
17011
17012            synchronized(this) {
17013                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17014                if (rl != null) {
17015                    final BroadcastRecord r = rl.curBroadcast;
17016                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17017                        final boolean doNext = r.queue.finishReceiverLocked(
17018                                r, r.resultCode, r.resultData, r.resultExtras,
17019                                r.resultAbort, false);
17020                        if (doNext) {
17021                            doTrim = true;
17022                            r.queue.processNextBroadcast(false);
17023                        }
17024                    }
17025
17026                    if (rl.app != null) {
17027                        rl.app.receivers.remove(rl);
17028                    }
17029                    removeReceiverLocked(rl);
17030                    if (rl.linkedToDeath) {
17031                        rl.linkedToDeath = false;
17032                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17033                    }
17034                }
17035            }
17036
17037            // If we actually concluded any broadcasts, we might now be able
17038            // to trim the recipients' apps from our working set
17039            if (doTrim) {
17040                trimApplications();
17041                return;
17042            }
17043
17044        } finally {
17045            Binder.restoreCallingIdentity(origId);
17046        }
17047    }
17048
17049    void removeReceiverLocked(ReceiverList rl) {
17050        mRegisteredReceivers.remove(rl.receiver.asBinder());
17051        for (int i = rl.size() - 1; i >= 0; i--) {
17052            mReceiverResolver.removeFilter(rl.get(i));
17053        }
17054    }
17055
17056    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17057        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17058            ProcessRecord r = mLruProcesses.get(i);
17059            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17060                try {
17061                    r.thread.dispatchPackageBroadcast(cmd, packages);
17062                } catch (RemoteException ex) {
17063                }
17064            }
17065        }
17066    }
17067
17068    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17069            int callingUid, int[] users) {
17070        // TODO: come back and remove this assumption to triage all broadcasts
17071        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17072
17073        List<ResolveInfo> receivers = null;
17074        try {
17075            HashSet<ComponentName> singleUserReceivers = null;
17076            boolean scannedFirstReceivers = false;
17077            for (int user : users) {
17078                // Skip users that have Shell restrictions, with exception of always permitted
17079                // Shell broadcasts
17080                if (callingUid == Process.SHELL_UID
17081                        && mUserController.hasUserRestriction(
17082                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17083                        && !isPermittedShellBroadcast(intent)) {
17084                    continue;
17085                }
17086                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17087                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17088                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17089                    // If this is not the system user, we need to check for
17090                    // any receivers that should be filtered out.
17091                    for (int i=0; i<newReceivers.size(); i++) {
17092                        ResolveInfo ri = newReceivers.get(i);
17093                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17094                            newReceivers.remove(i);
17095                            i--;
17096                        }
17097                    }
17098                }
17099                if (newReceivers != null && newReceivers.size() == 0) {
17100                    newReceivers = null;
17101                }
17102                if (receivers == null) {
17103                    receivers = newReceivers;
17104                } else if (newReceivers != null) {
17105                    // We need to concatenate the additional receivers
17106                    // found with what we have do far.  This would be easy,
17107                    // but we also need to de-dup any receivers that are
17108                    // singleUser.
17109                    if (!scannedFirstReceivers) {
17110                        // Collect any single user receivers we had already retrieved.
17111                        scannedFirstReceivers = true;
17112                        for (int i=0; i<receivers.size(); i++) {
17113                            ResolveInfo ri = receivers.get(i);
17114                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17115                                ComponentName cn = new ComponentName(
17116                                        ri.activityInfo.packageName, ri.activityInfo.name);
17117                                if (singleUserReceivers == null) {
17118                                    singleUserReceivers = new HashSet<ComponentName>();
17119                                }
17120                                singleUserReceivers.add(cn);
17121                            }
17122                        }
17123                    }
17124                    // Add the new results to the existing results, tracking
17125                    // and de-dupping single user receivers.
17126                    for (int i=0; i<newReceivers.size(); i++) {
17127                        ResolveInfo ri = newReceivers.get(i);
17128                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17129                            ComponentName cn = new ComponentName(
17130                                    ri.activityInfo.packageName, ri.activityInfo.name);
17131                            if (singleUserReceivers == null) {
17132                                singleUserReceivers = new HashSet<ComponentName>();
17133                            }
17134                            if (!singleUserReceivers.contains(cn)) {
17135                                singleUserReceivers.add(cn);
17136                                receivers.add(ri);
17137                            }
17138                        } else {
17139                            receivers.add(ri);
17140                        }
17141                    }
17142                }
17143            }
17144        } catch (RemoteException ex) {
17145            // pm is in same process, this will never happen.
17146        }
17147        return receivers;
17148    }
17149
17150    private boolean isPermittedShellBroadcast(Intent intent) {
17151        // remote bugreport should always be allowed to be taken
17152        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17153    }
17154
17155    final int broadcastIntentLocked(ProcessRecord callerApp,
17156            String callerPackage, Intent intent, String resolvedType,
17157            IIntentReceiver resultTo, int resultCode, String resultData,
17158            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17159            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17160        intent = new Intent(intent);
17161
17162        // By default broadcasts do not go to stopped apps.
17163        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17164
17165        // If we have not finished booting, don't allow this to launch new processes.
17166        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17167            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17168        }
17169
17170        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17171                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17172                + " ordered=" + ordered + " userid=" + userId);
17173        if ((resultTo != null) && !ordered) {
17174            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17175        }
17176
17177        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17178                ALLOW_NON_FULL, "broadcast", callerPackage);
17179
17180        // Make sure that the user who is receiving this broadcast is running.
17181        // If not, we will just skip it. Make an exception for shutdown broadcasts
17182        // and upgrade steps.
17183
17184        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17185            if ((callingUid != Process.SYSTEM_UID
17186                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17187                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17188                Slog.w(TAG, "Skipping broadcast of " + intent
17189                        + ": user " + userId + " is stopped");
17190                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17191            }
17192        }
17193
17194        BroadcastOptions brOptions = null;
17195        if (bOptions != null) {
17196            brOptions = new BroadcastOptions(bOptions);
17197            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17198                // See if the caller is allowed to do this.  Note we are checking against
17199                // the actual real caller (not whoever provided the operation as say a
17200                // PendingIntent), because that who is actually supplied the arguments.
17201                if (checkComponentPermission(
17202                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17203                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17204                        != PackageManager.PERMISSION_GRANTED) {
17205                    String msg = "Permission Denial: " + intent.getAction()
17206                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17207                            + ", uid=" + callingUid + ")"
17208                            + " requires "
17209                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17210                    Slog.w(TAG, msg);
17211                    throw new SecurityException(msg);
17212                }
17213            }
17214        }
17215
17216        // Verify that protected broadcasts are only being sent by system code,
17217        // and that system code is only sending protected broadcasts.
17218        final String action = intent.getAction();
17219        final boolean isProtectedBroadcast;
17220        try {
17221            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17222        } catch (RemoteException e) {
17223            Slog.w(TAG, "Remote exception", e);
17224            return ActivityManager.BROADCAST_SUCCESS;
17225        }
17226
17227        final boolean isCallerSystem;
17228        switch (UserHandle.getAppId(callingUid)) {
17229            case Process.ROOT_UID:
17230            case Process.SYSTEM_UID:
17231            case Process.PHONE_UID:
17232            case Process.BLUETOOTH_UID:
17233            case Process.NFC_UID:
17234                isCallerSystem = true;
17235                break;
17236            default:
17237                isCallerSystem = (callerApp != null) && callerApp.persistent;
17238                break;
17239        }
17240
17241        if (isCallerSystem) {
17242            if (isProtectedBroadcast
17243                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17244                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17245                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17246                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17247                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17248                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17249                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17250                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17251                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)) {
17252                // Broadcast is either protected, or it's a public action that
17253                // we've relaxed, so it's fine for system internals to send.
17254            } else {
17255                // The vast majority of broadcasts sent from system internals
17256                // should be protected to avoid security holes, so yell loudly
17257                // to ensure we examine these cases.
17258                Log.wtf(TAG, "Sending non-protected broadcast " + action
17259                        + " from system", new Throwable());
17260            }
17261
17262        } else {
17263            if (isProtectedBroadcast) {
17264                String msg = "Permission Denial: not allowed to send broadcast "
17265                        + action + " from pid="
17266                        + callingPid + ", uid=" + callingUid;
17267                Slog.w(TAG, msg);
17268                throw new SecurityException(msg);
17269
17270            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17271                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17272                // Special case for compatibility: we don't want apps to send this,
17273                // but historically it has not been protected and apps may be using it
17274                // to poke their own app widget.  So, instead of making it protected,
17275                // just limit it to the caller.
17276                if (callerPackage == null) {
17277                    String msg = "Permission Denial: not allowed to send broadcast "
17278                            + action + " from unknown caller.";
17279                    Slog.w(TAG, msg);
17280                    throw new SecurityException(msg);
17281                } else if (intent.getComponent() != null) {
17282                    // They are good enough to send to an explicit component...  verify
17283                    // it is being sent to the calling app.
17284                    if (!intent.getComponent().getPackageName().equals(
17285                            callerPackage)) {
17286                        String msg = "Permission Denial: not allowed to send broadcast "
17287                                + action + " to "
17288                                + intent.getComponent().getPackageName() + " from "
17289                                + callerPackage;
17290                        Slog.w(TAG, msg);
17291                        throw new SecurityException(msg);
17292                    }
17293                } else {
17294                    // Limit broadcast to their own package.
17295                    intent.setPackage(callerPackage);
17296                }
17297            }
17298        }
17299
17300        if (action != null) {
17301            switch (action) {
17302                case Intent.ACTION_UID_REMOVED:
17303                case Intent.ACTION_PACKAGE_REMOVED:
17304                case Intent.ACTION_PACKAGE_CHANGED:
17305                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17306                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17307                case Intent.ACTION_PACKAGES_SUSPENDED:
17308                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17309                    // Handle special intents: if this broadcast is from the package
17310                    // manager about a package being removed, we need to remove all of
17311                    // its activities from the history stack.
17312                    if (checkComponentPermission(
17313                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17314                            callingPid, callingUid, -1, true)
17315                            != PackageManager.PERMISSION_GRANTED) {
17316                        String msg = "Permission Denial: " + intent.getAction()
17317                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17318                                + ", uid=" + callingUid + ")"
17319                                + " requires "
17320                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17321                        Slog.w(TAG, msg);
17322                        throw new SecurityException(msg);
17323                    }
17324                    switch (action) {
17325                        case Intent.ACTION_UID_REMOVED:
17326                            final Bundle intentExtras = intent.getExtras();
17327                            final int uid = intentExtras != null
17328                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17329                            if (uid >= 0) {
17330                                mBatteryStatsService.removeUid(uid);
17331                                mAppOpsService.uidRemoved(uid);
17332                            }
17333                            break;
17334                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17335                            // If resources are unavailable just force stop all those packages
17336                            // and flush the attribute cache as well.
17337                            String list[] =
17338                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17339                            if (list != null && list.length > 0) {
17340                                for (int i = 0; i < list.length; i++) {
17341                                    forceStopPackageLocked(list[i], -1, false, true, true,
17342                                            false, false, userId, "storage unmount");
17343                                }
17344                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17345                                sendPackageBroadcastLocked(
17346                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17347                                        userId);
17348                            }
17349                            break;
17350                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17351                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17352                            break;
17353                        case Intent.ACTION_PACKAGE_REMOVED:
17354                        case Intent.ACTION_PACKAGE_CHANGED:
17355                            Uri data = intent.getData();
17356                            String ssp;
17357                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17358                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17359                                final boolean replacing =
17360                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17361                                final boolean killProcess =
17362                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17363                                final boolean fullUninstall = removed && !replacing;
17364                                if (killProcess) {
17365                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17366                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17367                                            false, true, true, false, fullUninstall, userId,
17368                                            removed ? "pkg removed" : "pkg changed");
17369                                }
17370                                if (removed) {
17371                                    final int cmd = killProcess
17372                                            ? IApplicationThread.PACKAGE_REMOVED
17373                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17374                                    sendPackageBroadcastLocked(cmd,
17375                                            new String[] {ssp}, userId);
17376                                    if (fullUninstall) {
17377                                        mAppOpsService.packageRemoved(
17378                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17379
17380                                        // Remove all permissions granted from/to this package
17381                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17382
17383                                        removeTasksByPackageNameLocked(ssp, userId);
17384                                        mBatteryStatsService.notePackageUninstalled(ssp);
17385                                    }
17386                                } else {
17387                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17388                                            intent.getStringArrayExtra(
17389                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17390                                }
17391                            }
17392                            break;
17393                        case Intent.ACTION_PACKAGES_SUSPENDED:
17394                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17395                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17396                                    intent.getAction());
17397                            final String[] packageNames = intent.getStringArrayExtra(
17398                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17399                            final int userHandle = intent.getIntExtra(
17400                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17401
17402                            synchronized(ActivityManagerService.this) {
17403                                mRecentTasks.onPackagesSuspendedChanged(
17404                                        packageNames, suspended, userHandle);
17405                            }
17406                            break;
17407                    }
17408                    break;
17409                case Intent.ACTION_PACKAGE_REPLACED:
17410                {
17411                    final Uri data = intent.getData();
17412                    final String ssp;
17413                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17414                        final ApplicationInfo aInfo =
17415                                getPackageManagerInternalLocked().getApplicationInfo(
17416                                        ssp,
17417                                        userId);
17418                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17419                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17420                                new String[] {ssp}, userId);
17421                    }
17422                    break;
17423                }
17424                case Intent.ACTION_PACKAGE_ADDED:
17425                {
17426                    // Special case for adding a package: by default turn on compatibility mode.
17427                    Uri data = intent.getData();
17428                    String ssp;
17429                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17430                        final boolean replacing =
17431                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17432                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17433
17434                        try {
17435                            ApplicationInfo ai = AppGlobals.getPackageManager().
17436                                    getApplicationInfo(ssp, 0, 0);
17437                            mBatteryStatsService.notePackageInstalled(ssp,
17438                                    ai != null ? ai.versionCode : 0);
17439                        } catch (RemoteException e) {
17440                        }
17441                    }
17442                    break;
17443                }
17444                case Intent.ACTION_TIMEZONE_CHANGED:
17445                    // If this is the time zone changed action, queue up a message that will reset
17446                    // the timezone of all currently running processes. This message will get
17447                    // queued up before the broadcast happens.
17448                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17449                    break;
17450                case Intent.ACTION_TIME_CHANGED:
17451                    // If the user set the time, let all running processes know.
17452                    final int is24Hour =
17453                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17454                                    : 0;
17455                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17456                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17457                    synchronized (stats) {
17458                        stats.noteCurrentTimeChangedLocked();
17459                    }
17460                    break;
17461                case Intent.ACTION_CLEAR_DNS_CACHE:
17462                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17463                    break;
17464                case Proxy.PROXY_CHANGE_ACTION:
17465                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17466                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17467                    break;
17468                case android.hardware.Camera.ACTION_NEW_PICTURE:
17469                case android.hardware.Camera.ACTION_NEW_VIDEO:
17470                    // These broadcasts are no longer allowed by the system, since they can
17471                    // cause significant thrashing at a crictical point (using the camera).
17472                    // Apps should use JobScehduler to monitor for media provider changes.
17473                    Slog.w(TAG, action + " no longer allowed; dropping from "
17474                            + UserHandle.formatUid(callingUid));
17475                    // Lie; we don't want to crash the app.
17476                    return ActivityManager.BROADCAST_SUCCESS;
17477            }
17478        }
17479
17480        // Add to the sticky list if requested.
17481        if (sticky) {
17482            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17483                    callingPid, callingUid)
17484                    != PackageManager.PERMISSION_GRANTED) {
17485                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17486                        + callingPid + ", uid=" + callingUid
17487                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17488                Slog.w(TAG, msg);
17489                throw new SecurityException(msg);
17490            }
17491            if (requiredPermissions != null && requiredPermissions.length > 0) {
17492                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17493                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17494                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17495            }
17496            if (intent.getComponent() != null) {
17497                throw new SecurityException(
17498                        "Sticky broadcasts can't target a specific component");
17499            }
17500            // We use userId directly here, since the "all" target is maintained
17501            // as a separate set of sticky broadcasts.
17502            if (userId != UserHandle.USER_ALL) {
17503                // But first, if this is not a broadcast to all users, then
17504                // make sure it doesn't conflict with an existing broadcast to
17505                // all users.
17506                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17507                        UserHandle.USER_ALL);
17508                if (stickies != null) {
17509                    ArrayList<Intent> list = stickies.get(intent.getAction());
17510                    if (list != null) {
17511                        int N = list.size();
17512                        int i;
17513                        for (i=0; i<N; i++) {
17514                            if (intent.filterEquals(list.get(i))) {
17515                                throw new IllegalArgumentException(
17516                                        "Sticky broadcast " + intent + " for user "
17517                                        + userId + " conflicts with existing global broadcast");
17518                            }
17519                        }
17520                    }
17521                }
17522            }
17523            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17524            if (stickies == null) {
17525                stickies = new ArrayMap<>();
17526                mStickyBroadcasts.put(userId, stickies);
17527            }
17528            ArrayList<Intent> list = stickies.get(intent.getAction());
17529            if (list == null) {
17530                list = new ArrayList<>();
17531                stickies.put(intent.getAction(), list);
17532            }
17533            final int stickiesCount = list.size();
17534            int i;
17535            for (i = 0; i < stickiesCount; i++) {
17536                if (intent.filterEquals(list.get(i))) {
17537                    // This sticky already exists, replace it.
17538                    list.set(i, new Intent(intent));
17539                    break;
17540                }
17541            }
17542            if (i >= stickiesCount) {
17543                list.add(new Intent(intent));
17544            }
17545        }
17546
17547        int[] users;
17548        if (userId == UserHandle.USER_ALL) {
17549            // Caller wants broadcast to go to all started users.
17550            users = mUserController.getStartedUserArrayLocked();
17551        } else {
17552            // Caller wants broadcast to go to one specific user.
17553            users = new int[] {userId};
17554        }
17555
17556        // Figure out who all will receive this broadcast.
17557        List receivers = null;
17558        List<BroadcastFilter> registeredReceivers = null;
17559        // Need to resolve the intent to interested receivers...
17560        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17561                 == 0) {
17562            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17563        }
17564        if (intent.getComponent() == null) {
17565            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17566                // Query one target user at a time, excluding shell-restricted users
17567                for (int i = 0; i < users.length; i++) {
17568                    if (mUserController.hasUserRestriction(
17569                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17570                        continue;
17571                    }
17572                    List<BroadcastFilter> registeredReceiversForUser =
17573                            mReceiverResolver.queryIntent(intent,
17574                                    resolvedType, false, users[i]);
17575                    if (registeredReceivers == null) {
17576                        registeredReceivers = registeredReceiversForUser;
17577                    } else if (registeredReceiversForUser != null) {
17578                        registeredReceivers.addAll(registeredReceiversForUser);
17579                    }
17580                }
17581            } else {
17582                registeredReceivers = mReceiverResolver.queryIntent(intent,
17583                        resolvedType, false, userId);
17584            }
17585        }
17586
17587        final boolean replacePending =
17588                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17589
17590        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17591                + " replacePending=" + replacePending);
17592
17593        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17594        if (!ordered && NR > 0) {
17595            // If we are not serializing this broadcast, then send the
17596            // registered receivers separately so they don't wait for the
17597            // components to be launched.
17598            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17599            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17600                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17601                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17602                    resultExtras, ordered, sticky, false, userId);
17603            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17604            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17605            if (!replaced) {
17606                queue.enqueueParallelBroadcastLocked(r);
17607                queue.scheduleBroadcastsLocked();
17608            }
17609            registeredReceivers = null;
17610            NR = 0;
17611        }
17612
17613        // Merge into one list.
17614        int ir = 0;
17615        if (receivers != null) {
17616            // A special case for PACKAGE_ADDED: do not allow the package
17617            // being added to see this broadcast.  This prevents them from
17618            // using this as a back door to get run as soon as they are
17619            // installed.  Maybe in the future we want to have a special install
17620            // broadcast or such for apps, but we'd like to deliberately make
17621            // this decision.
17622            String skipPackages[] = null;
17623            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17624                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17625                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17626                Uri data = intent.getData();
17627                if (data != null) {
17628                    String pkgName = data.getSchemeSpecificPart();
17629                    if (pkgName != null) {
17630                        skipPackages = new String[] { pkgName };
17631                    }
17632                }
17633            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17634                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17635            }
17636            if (skipPackages != null && (skipPackages.length > 0)) {
17637                for (String skipPackage : skipPackages) {
17638                    if (skipPackage != null) {
17639                        int NT = receivers.size();
17640                        for (int it=0; it<NT; it++) {
17641                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17642                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17643                                receivers.remove(it);
17644                                it--;
17645                                NT--;
17646                            }
17647                        }
17648                    }
17649                }
17650            }
17651
17652            int NT = receivers != null ? receivers.size() : 0;
17653            int it = 0;
17654            ResolveInfo curt = null;
17655            BroadcastFilter curr = null;
17656            while (it < NT && ir < NR) {
17657                if (curt == null) {
17658                    curt = (ResolveInfo)receivers.get(it);
17659                }
17660                if (curr == null) {
17661                    curr = registeredReceivers.get(ir);
17662                }
17663                if (curr.getPriority() >= curt.priority) {
17664                    // Insert this broadcast record into the final list.
17665                    receivers.add(it, curr);
17666                    ir++;
17667                    curr = null;
17668                    it++;
17669                    NT++;
17670                } else {
17671                    // Skip to the next ResolveInfo in the final list.
17672                    it++;
17673                    curt = null;
17674                }
17675            }
17676        }
17677        while (ir < NR) {
17678            if (receivers == null) {
17679                receivers = new ArrayList();
17680            }
17681            receivers.add(registeredReceivers.get(ir));
17682            ir++;
17683        }
17684
17685        if ((receivers != null && receivers.size() > 0)
17686                || resultTo != null) {
17687            BroadcastQueue queue = broadcastQueueForIntent(intent);
17688            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17689                    callerPackage, callingPid, callingUid, resolvedType,
17690                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17691                    resultData, resultExtras, ordered, sticky, false, userId);
17692
17693            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17694                    + ": prev had " + queue.mOrderedBroadcasts.size());
17695            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17696                    "Enqueueing broadcast " + r.intent.getAction());
17697
17698            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17699            if (!replaced) {
17700                queue.enqueueOrderedBroadcastLocked(r);
17701                queue.scheduleBroadcastsLocked();
17702            }
17703        }
17704
17705        return ActivityManager.BROADCAST_SUCCESS;
17706    }
17707
17708    final Intent verifyBroadcastLocked(Intent intent) {
17709        // Refuse possible leaked file descriptors
17710        if (intent != null && intent.hasFileDescriptors() == true) {
17711            throw new IllegalArgumentException("File descriptors passed in Intent");
17712        }
17713
17714        int flags = intent.getFlags();
17715
17716        if (!mProcessesReady) {
17717            // if the caller really truly claims to know what they're doing, go
17718            // ahead and allow the broadcast without launching any receivers
17719            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17720                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17721            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17722                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17723                        + " before boot completion");
17724                throw new IllegalStateException("Cannot broadcast before boot completed");
17725            }
17726        }
17727
17728        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17729            throw new IllegalArgumentException(
17730                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17731        }
17732
17733        return intent;
17734    }
17735
17736    public final int broadcastIntent(IApplicationThread caller,
17737            Intent intent, String resolvedType, IIntentReceiver resultTo,
17738            int resultCode, String resultData, Bundle resultExtras,
17739            String[] requiredPermissions, int appOp, Bundle bOptions,
17740            boolean serialized, boolean sticky, int userId) {
17741        enforceNotIsolatedCaller("broadcastIntent");
17742        synchronized(this) {
17743            intent = verifyBroadcastLocked(intent);
17744
17745            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17746            final int callingPid = Binder.getCallingPid();
17747            final int callingUid = Binder.getCallingUid();
17748            final long origId = Binder.clearCallingIdentity();
17749            int res = broadcastIntentLocked(callerApp,
17750                    callerApp != null ? callerApp.info.packageName : null,
17751                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17752                    requiredPermissions, appOp, bOptions, serialized, sticky,
17753                    callingPid, callingUid, userId);
17754            Binder.restoreCallingIdentity(origId);
17755            return res;
17756        }
17757    }
17758
17759
17760    int broadcastIntentInPackage(String packageName, int uid,
17761            Intent intent, String resolvedType, IIntentReceiver resultTo,
17762            int resultCode, String resultData, Bundle resultExtras,
17763            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17764            int userId) {
17765        synchronized(this) {
17766            intent = verifyBroadcastLocked(intent);
17767
17768            final long origId = Binder.clearCallingIdentity();
17769            String[] requiredPermissions = requiredPermission == null ? null
17770                    : new String[] {requiredPermission};
17771            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17772                    resultTo, resultCode, resultData, resultExtras,
17773                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17774                    sticky, -1, uid, userId);
17775            Binder.restoreCallingIdentity(origId);
17776            return res;
17777        }
17778    }
17779
17780    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17781        // Refuse possible leaked file descriptors
17782        if (intent != null && intent.hasFileDescriptors() == true) {
17783            throw new IllegalArgumentException("File descriptors passed in Intent");
17784        }
17785
17786        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17787                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17788
17789        synchronized(this) {
17790            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17791                    != PackageManager.PERMISSION_GRANTED) {
17792                String msg = "Permission Denial: unbroadcastIntent() from pid="
17793                        + Binder.getCallingPid()
17794                        + ", uid=" + Binder.getCallingUid()
17795                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17796                Slog.w(TAG, msg);
17797                throw new SecurityException(msg);
17798            }
17799            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17800            if (stickies != null) {
17801                ArrayList<Intent> list = stickies.get(intent.getAction());
17802                if (list != null) {
17803                    int N = list.size();
17804                    int i;
17805                    for (i=0; i<N; i++) {
17806                        if (intent.filterEquals(list.get(i))) {
17807                            list.remove(i);
17808                            break;
17809                        }
17810                    }
17811                    if (list.size() <= 0) {
17812                        stickies.remove(intent.getAction());
17813                    }
17814                }
17815                if (stickies.size() <= 0) {
17816                    mStickyBroadcasts.remove(userId);
17817                }
17818            }
17819        }
17820    }
17821
17822    void backgroundServicesFinishedLocked(int userId) {
17823        for (BroadcastQueue queue : mBroadcastQueues) {
17824            queue.backgroundServicesFinishedLocked(userId);
17825        }
17826    }
17827
17828    public void finishReceiver(IBinder who, int resultCode, String resultData,
17829            Bundle resultExtras, boolean resultAbort, int flags) {
17830        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17831
17832        // Refuse possible leaked file descriptors
17833        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17834            throw new IllegalArgumentException("File descriptors passed in Bundle");
17835        }
17836
17837        final long origId = Binder.clearCallingIdentity();
17838        try {
17839            boolean doNext = false;
17840            BroadcastRecord r;
17841
17842            synchronized(this) {
17843                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17844                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17845                r = queue.getMatchingOrderedReceiver(who);
17846                if (r != null) {
17847                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17848                        resultData, resultExtras, resultAbort, true);
17849                }
17850            }
17851
17852            if (doNext) {
17853                r.queue.processNextBroadcast(false);
17854            }
17855            trimApplications();
17856        } finally {
17857            Binder.restoreCallingIdentity(origId);
17858        }
17859    }
17860
17861    // =========================================================
17862    // INSTRUMENTATION
17863    // =========================================================
17864
17865    public boolean startInstrumentation(ComponentName className,
17866            String profileFile, int flags, Bundle arguments,
17867            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17868            int userId, String abiOverride) {
17869        enforceNotIsolatedCaller("startInstrumentation");
17870        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17871                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17872        // Refuse possible leaked file descriptors
17873        if (arguments != null && arguments.hasFileDescriptors()) {
17874            throw new IllegalArgumentException("File descriptors passed in Bundle");
17875        }
17876
17877        synchronized(this) {
17878            InstrumentationInfo ii = null;
17879            ApplicationInfo ai = null;
17880            try {
17881                ii = mContext.getPackageManager().getInstrumentationInfo(
17882                    className, STOCK_PM_FLAGS);
17883                ai = AppGlobals.getPackageManager().getApplicationInfo(
17884                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17885            } catch (PackageManager.NameNotFoundException e) {
17886            } catch (RemoteException e) {
17887            }
17888            if (ii == null) {
17889                reportStartInstrumentationFailureLocked(watcher, className,
17890                        "Unable to find instrumentation info for: " + className);
17891                return false;
17892            }
17893            if (ai == null) {
17894                reportStartInstrumentationFailureLocked(watcher, className,
17895                        "Unable to find instrumentation target package: " + ii.targetPackage);
17896                return false;
17897            }
17898            if (!ai.hasCode()) {
17899                reportStartInstrumentationFailureLocked(watcher, className,
17900                        "Instrumentation target has no code: " + ii.targetPackage);
17901                return false;
17902            }
17903
17904            int match = mContext.getPackageManager().checkSignatures(
17905                    ii.targetPackage, ii.packageName);
17906            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17907                String msg = "Permission Denial: starting instrumentation "
17908                        + className + " from pid="
17909                        + Binder.getCallingPid()
17910                        + ", uid=" + Binder.getCallingPid()
17911                        + " not allowed because package " + ii.packageName
17912                        + " does not have a signature matching the target "
17913                        + ii.targetPackage;
17914                reportStartInstrumentationFailureLocked(watcher, className, msg);
17915                throw new SecurityException(msg);
17916            }
17917
17918            final long origId = Binder.clearCallingIdentity();
17919            // Instrumentation can kill and relaunch even persistent processes
17920            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17921                    "start instr");
17922            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17923            app.instrumentationClass = className;
17924            app.instrumentationInfo = ai;
17925            app.instrumentationProfileFile = profileFile;
17926            app.instrumentationArguments = arguments;
17927            app.instrumentationWatcher = watcher;
17928            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17929            app.instrumentationResultClass = className;
17930            Binder.restoreCallingIdentity(origId);
17931        }
17932
17933        return true;
17934    }
17935
17936    /**
17937     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17938     * error to the logs, but if somebody is watching, send the report there too.  This enables
17939     * the "am" command to report errors with more information.
17940     *
17941     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17942     * @param cn The component name of the instrumentation.
17943     * @param report The error report.
17944     */
17945    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17946            ComponentName cn, String report) {
17947        Slog.w(TAG, report);
17948        if (watcher != null) {
17949            Bundle results = new Bundle();
17950            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17951            results.putString("Error", report);
17952            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17953        }
17954    }
17955
17956    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17957        if (app.instrumentationWatcher != null) {
17958            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17959                    app.instrumentationClass, resultCode, results);
17960        }
17961
17962        // Can't call out of the system process with a lock held, so post a message.
17963        if (app.instrumentationUiAutomationConnection != null) {
17964            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17965                    app.instrumentationUiAutomationConnection).sendToTarget();
17966        }
17967
17968        app.instrumentationWatcher = null;
17969        app.instrumentationUiAutomationConnection = null;
17970        app.instrumentationClass = null;
17971        app.instrumentationInfo = null;
17972        app.instrumentationProfileFile = null;
17973        app.instrumentationArguments = null;
17974
17975        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17976                "finished inst");
17977    }
17978
17979    public void finishInstrumentation(IApplicationThread target,
17980            int resultCode, Bundle results) {
17981        int userId = UserHandle.getCallingUserId();
17982        // Refuse possible leaked file descriptors
17983        if (results != null && results.hasFileDescriptors()) {
17984            throw new IllegalArgumentException("File descriptors passed in Intent");
17985        }
17986
17987        synchronized(this) {
17988            ProcessRecord app = getRecordForAppLocked(target);
17989            if (app == null) {
17990                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17991                return;
17992            }
17993            final long origId = Binder.clearCallingIdentity();
17994            finishInstrumentationLocked(app, resultCode, results);
17995            Binder.restoreCallingIdentity(origId);
17996        }
17997    }
17998
17999    // =========================================================
18000    // CONFIGURATION
18001    // =========================================================
18002
18003    public ConfigurationInfo getDeviceConfigurationInfo() {
18004        ConfigurationInfo config = new ConfigurationInfo();
18005        synchronized (this) {
18006            config.reqTouchScreen = mConfiguration.touchscreen;
18007            config.reqKeyboardType = mConfiguration.keyboard;
18008            config.reqNavigation = mConfiguration.navigation;
18009            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18010                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18011                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18012            }
18013            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18014                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18015                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18016            }
18017            config.reqGlEsVersion = GL_ES_VERSION;
18018        }
18019        return config;
18020    }
18021
18022    ActivityStack getFocusedStack() {
18023        return mStackSupervisor.getFocusedStack();
18024    }
18025
18026    @Override
18027    public int getFocusedStackId() throws RemoteException {
18028        ActivityStack focusedStack = getFocusedStack();
18029        if (focusedStack != null) {
18030            return focusedStack.getStackId();
18031        }
18032        return -1;
18033    }
18034
18035    public Configuration getConfiguration() {
18036        Configuration ci;
18037        synchronized(this) {
18038            ci = new Configuration(mConfiguration);
18039            ci.userSetLocale = false;
18040        }
18041        return ci;
18042    }
18043
18044    @Override
18045    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18046        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18047        synchronized (this) {
18048            mSuppressResizeConfigChanges = suppress;
18049        }
18050    }
18051
18052    @Override
18053    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18054        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18055        if (fromStackId == HOME_STACK_ID) {
18056            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18057        }
18058        synchronized (this) {
18059            final long origId = Binder.clearCallingIdentity();
18060            try {
18061                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18062            } finally {
18063                Binder.restoreCallingIdentity(origId);
18064            }
18065        }
18066    }
18067
18068    @Override
18069    public void updatePersistentConfiguration(Configuration values) {
18070        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18071                "updateConfiguration()");
18072        enforceWriteSettingsPermission("updateConfiguration()");
18073        if (values == null) {
18074            throw new NullPointerException("Configuration must not be null");
18075        }
18076
18077        int userId = UserHandle.getCallingUserId();
18078
18079        synchronized(this) {
18080            final long origId = Binder.clearCallingIdentity();
18081            updateConfigurationLocked(values, null, false, true, userId);
18082            Binder.restoreCallingIdentity(origId);
18083        }
18084    }
18085
18086    private void updateFontScaleIfNeeded() {
18087        final int currentUserId;
18088        synchronized(this) {
18089            currentUserId = mUserController.getCurrentUserIdLocked();
18090        }
18091        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18092                FONT_SCALE, 1.0f, currentUserId);
18093        if (mConfiguration.fontScale != scaleFactor) {
18094            final Configuration configuration = mWindowManager.computeNewConfiguration();
18095            configuration.fontScale = scaleFactor;
18096            updatePersistentConfiguration(configuration);
18097        }
18098    }
18099
18100    private void enforceWriteSettingsPermission(String func) {
18101        int uid = Binder.getCallingUid();
18102        if (uid == Process.ROOT_UID) {
18103            return;
18104        }
18105
18106        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18107                Settings.getPackageNameForUid(mContext, uid), false)) {
18108            return;
18109        }
18110
18111        String msg = "Permission Denial: " + func + " from pid="
18112                + Binder.getCallingPid()
18113                + ", uid=" + uid
18114                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18115        Slog.w(TAG, msg);
18116        throw new SecurityException(msg);
18117    }
18118
18119    public void updateConfiguration(Configuration values) {
18120        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18121                "updateConfiguration()");
18122
18123        synchronized(this) {
18124            if (values == null && mWindowManager != null) {
18125                // sentinel: fetch the current configuration from the window manager
18126                values = mWindowManager.computeNewConfiguration();
18127            }
18128
18129            if (mWindowManager != null) {
18130                mProcessList.applyDisplaySize(mWindowManager);
18131            }
18132
18133            final long origId = Binder.clearCallingIdentity();
18134            if (values != null) {
18135                Settings.System.clearConfiguration(values);
18136            }
18137            updateConfigurationLocked(values, null, false);
18138            Binder.restoreCallingIdentity(origId);
18139        }
18140    }
18141
18142    void updateUserConfigurationLocked() {
18143        Configuration configuration = new Configuration(mConfiguration);
18144        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18145                mUserController.getCurrentUserIdLocked());
18146        updateConfigurationLocked(configuration, null, false);
18147    }
18148
18149    boolean updateConfigurationLocked(Configuration values,
18150            ActivityRecord starting, boolean initLocale) {
18151        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18152        return updateConfigurationLocked(values, starting, initLocale, false,
18153                UserHandle.USER_NULL);
18154    }
18155
18156    // To cache the list of supported system locales
18157    private String[] mSupportedSystemLocales = null;
18158
18159    /**
18160     * Do either or both things: (1) change the current configuration, and (2)
18161     * make sure the given activity is running with the (now) current
18162     * configuration.  Returns true if the activity has been left running, or
18163     * false if <var>starting</var> is being destroyed to match the new
18164     * configuration.
18165     *
18166     * @param userId is only used when persistent parameter is set to true to persist configuration
18167     *               for that particular user
18168     */
18169    private boolean updateConfigurationLocked(Configuration values,
18170            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18171        int changes = 0;
18172
18173        if (mWindowManager != null) {
18174            mWindowManager.deferSurfaceLayout();
18175        }
18176        if (values != null) {
18177            Configuration newConfig = new Configuration(mConfiguration);
18178            changes = newConfig.updateFrom(values);
18179            if (changes != 0) {
18180                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18181                        "Updating configuration to: " + values);
18182
18183                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18184
18185                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18186                    final Locale locale;
18187                    if (values.getLocales().size() == 1) {
18188                        // This is an optimization to avoid the JNI call when the result of
18189                        // getFirstMatch() does not depend on the supported locales.
18190                        locale = values.getLocales().get(0);
18191                    } else {
18192                        if (mSupportedSystemLocales == null) {
18193                            mSupportedSystemLocales =
18194                                    Resources.getSystem().getAssets().getLocales();
18195                        }
18196                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18197                    }
18198                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18199                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18200                            locale));
18201                }
18202
18203                mConfigurationSeq++;
18204                if (mConfigurationSeq <= 0) {
18205                    mConfigurationSeq = 1;
18206                }
18207                newConfig.seq = mConfigurationSeq;
18208                mConfiguration = newConfig;
18209                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18210                mUsageStatsService.reportConfigurationChange(newConfig,
18211                        mUserController.getCurrentUserIdLocked());
18212                //mUsageStatsService.noteStartConfig(newConfig);
18213
18214                final Configuration configCopy = new Configuration(mConfiguration);
18215
18216                // TODO: If our config changes, should we auto dismiss any currently
18217                // showing dialogs?
18218                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18219
18220                AttributeCache ac = AttributeCache.instance();
18221                if (ac != null) {
18222                    ac.updateConfiguration(configCopy);
18223                }
18224
18225                // Make sure all resources in our process are updated
18226                // right now, so that anyone who is going to retrieve
18227                // resource values after we return will be sure to get
18228                // the new ones.  This is especially important during
18229                // boot, where the first config change needs to guarantee
18230                // all resources have that config before following boot
18231                // code is executed.
18232                mSystemThread.applyConfigurationToResources(configCopy);
18233
18234                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18235                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18236                    msg.obj = new Configuration(configCopy);
18237                    msg.arg1 = userId;
18238                    mHandler.sendMessage(msg);
18239                }
18240
18241                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18242                if (isDensityChange) {
18243                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18244                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18245                }
18246
18247                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18248                    ProcessRecord app = mLruProcesses.get(i);
18249                    try {
18250                        if (app.thread != null) {
18251                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18252                                    + app.processName + " new config " + mConfiguration);
18253                            app.thread.scheduleConfigurationChanged(configCopy);
18254                        }
18255                    } catch (Exception e) {
18256                    }
18257                }
18258                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18259                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18260                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18261                        | Intent.FLAG_RECEIVER_FOREGROUND);
18262                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18263                        null, AppOpsManager.OP_NONE, null, false, false,
18264                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18265                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18266                    // Tell the shortcut manager that the system locale changed.  It needs to know
18267                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18268                    // we "push" from here, rather than having the service listen to the broadcast.
18269                    final ShortcutServiceInternal shortcutService =
18270                            LocalServices.getService(ShortcutServiceInternal.class);
18271                    if (shortcutService != null) {
18272                        shortcutService.onSystemLocaleChangedNoLock();
18273                    }
18274
18275                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18276                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18277                    if (!mProcessesReady) {
18278                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18279                    }
18280                    broadcastIntentLocked(null, null, intent,
18281                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18282                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18283                }
18284            }
18285            // Update the configuration with WM first and check if any of the stacks need to be
18286            // resized due to the configuration change. If so, resize the stacks now and do any
18287            // relaunches if necessary. This way we don't need to relaunch again below in
18288            // ensureActivityConfigurationLocked().
18289            if (mWindowManager != null) {
18290                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18291                if (resizedStacks != null) {
18292                    for (int stackId : resizedStacks) {
18293                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18294                        mStackSupervisor.resizeStackLocked(
18295                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18296                    }
18297                }
18298            }
18299        }
18300
18301        boolean kept = true;
18302        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18303        // mainStack is null during startup.
18304        if (mainStack != null) {
18305            if (changes != 0 && starting == null) {
18306                // If the configuration changed, and the caller is not already
18307                // in the process of starting an activity, then find the top
18308                // activity to check if its configuration needs to change.
18309                starting = mainStack.topRunningActivityLocked();
18310            }
18311
18312            if (starting != null) {
18313                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18314                // And we need to make sure at this point that all other activities
18315                // are made visible with the correct configuration.
18316                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18317                        !PRESERVE_WINDOWS);
18318            }
18319        }
18320        if (mWindowManager != null) {
18321            mWindowManager.continueSurfaceLayout();
18322        }
18323        return kept;
18324    }
18325
18326    /**
18327     * Decide based on the configuration whether we should shouw the ANR,
18328     * crash, etc dialogs.  The idea is that if there is no affordnace to
18329     * press the on-screen buttons, we shouldn't show the dialog.
18330     *
18331     * A thought: SystemUI might also want to get told about this, the Power
18332     * dialog / global actions also might want different behaviors.
18333     */
18334    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18335        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18336                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18337                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18338        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18339                                    == Configuration.UI_MODE_TYPE_CAR);
18340        return inputMethodExists && uiIsNotCarType && !inVrMode;
18341    }
18342
18343    @Override
18344    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18345        synchronized (this) {
18346            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18347            if (srec != null) {
18348                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18349            }
18350        }
18351        return false;
18352    }
18353
18354    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18355            Intent resultData) {
18356
18357        synchronized (this) {
18358            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18359            if (r != null) {
18360                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18361            }
18362            return false;
18363        }
18364    }
18365
18366    public int getLaunchedFromUid(IBinder activityToken) {
18367        ActivityRecord srec;
18368        synchronized (this) {
18369            srec = ActivityRecord.forTokenLocked(activityToken);
18370        }
18371        if (srec == null) {
18372            return -1;
18373        }
18374        return srec.launchedFromUid;
18375    }
18376
18377    public String getLaunchedFromPackage(IBinder activityToken) {
18378        ActivityRecord srec;
18379        synchronized (this) {
18380            srec = ActivityRecord.forTokenLocked(activityToken);
18381        }
18382        if (srec == null) {
18383            return null;
18384        }
18385        return srec.launchedFromPackage;
18386    }
18387
18388    // =========================================================
18389    // LIFETIME MANAGEMENT
18390    // =========================================================
18391
18392    // Returns which broadcast queue the app is the current [or imminent] receiver
18393    // on, or 'null' if the app is not an active broadcast recipient.
18394    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18395        BroadcastRecord r = app.curReceiver;
18396        if (r != null) {
18397            return r.queue;
18398        }
18399
18400        // It's not the current receiver, but it might be starting up to become one
18401        synchronized (this) {
18402            for (BroadcastQueue queue : mBroadcastQueues) {
18403                r = queue.mPendingBroadcast;
18404                if (r != null && r.curApp == app) {
18405                    // found it; report which queue it's in
18406                    return queue;
18407                }
18408            }
18409        }
18410
18411        return null;
18412    }
18413
18414    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18415            int targetUid, ComponentName targetComponent, String targetProcess) {
18416        if (!mTrackingAssociations) {
18417            return null;
18418        }
18419        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18420                = mAssociations.get(targetUid);
18421        if (components == null) {
18422            components = new ArrayMap<>();
18423            mAssociations.put(targetUid, components);
18424        }
18425        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18426        if (sourceUids == null) {
18427            sourceUids = new SparseArray<>();
18428            components.put(targetComponent, sourceUids);
18429        }
18430        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18431        if (sourceProcesses == null) {
18432            sourceProcesses = new ArrayMap<>();
18433            sourceUids.put(sourceUid, sourceProcesses);
18434        }
18435        Association ass = sourceProcesses.get(sourceProcess);
18436        if (ass == null) {
18437            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18438                    targetProcess);
18439            sourceProcesses.put(sourceProcess, ass);
18440        }
18441        ass.mCount++;
18442        ass.mNesting++;
18443        if (ass.mNesting == 1) {
18444            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18445            ass.mLastState = sourceState;
18446        }
18447        return ass;
18448    }
18449
18450    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18451            ComponentName targetComponent) {
18452        if (!mTrackingAssociations) {
18453            return;
18454        }
18455        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18456                = mAssociations.get(targetUid);
18457        if (components == null) {
18458            return;
18459        }
18460        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18461        if (sourceUids == null) {
18462            return;
18463        }
18464        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18465        if (sourceProcesses == null) {
18466            return;
18467        }
18468        Association ass = sourceProcesses.get(sourceProcess);
18469        if (ass == null || ass.mNesting <= 0) {
18470            return;
18471        }
18472        ass.mNesting--;
18473        if (ass.mNesting == 0) {
18474            long uptime = SystemClock.uptimeMillis();
18475            ass.mTime += uptime - ass.mStartTime;
18476            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18477                    += uptime - ass.mLastStateUptime;
18478            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18479        }
18480    }
18481
18482    private void noteUidProcessState(final int uid, final int state) {
18483        mBatteryStatsService.noteUidProcessState(uid, state);
18484        if (mTrackingAssociations) {
18485            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18486                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18487                        = mAssociations.valueAt(i1);
18488                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18489                    SparseArray<ArrayMap<String, Association>> sourceUids
18490                            = targetComponents.valueAt(i2);
18491                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18492                    if (sourceProcesses != null) {
18493                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18494                            Association ass = sourceProcesses.valueAt(i4);
18495                            if (ass.mNesting >= 1) {
18496                                // currently associated
18497                                long uptime = SystemClock.uptimeMillis();
18498                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18499                                        += uptime - ass.mLastStateUptime;
18500                                ass.mLastState = state;
18501                                ass.mLastStateUptime = uptime;
18502                            }
18503                        }
18504                    }
18505                }
18506            }
18507        }
18508    }
18509
18510    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18511            boolean doingAll, long now) {
18512        if (mAdjSeq == app.adjSeq) {
18513            // This adjustment has already been computed.
18514            return app.curRawAdj;
18515        }
18516
18517        if (app.thread == null) {
18518            app.adjSeq = mAdjSeq;
18519            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18520            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18521            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18522        }
18523
18524        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18525        app.adjSource = null;
18526        app.adjTarget = null;
18527        app.empty = false;
18528        app.cached = false;
18529
18530        final int activitiesSize = app.activities.size();
18531
18532        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18533            // The max adjustment doesn't allow this app to be anything
18534            // below foreground, so it is not worth doing work for it.
18535            app.adjType = "fixed";
18536            app.adjSeq = mAdjSeq;
18537            app.curRawAdj = app.maxAdj;
18538            app.foregroundActivities = false;
18539            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18540            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18541            // System processes can do UI, and when they do we want to have
18542            // them trim their memory after the user leaves the UI.  To
18543            // facilitate this, here we need to determine whether or not it
18544            // is currently showing UI.
18545            app.systemNoUi = true;
18546            if (app == TOP_APP) {
18547                app.systemNoUi = false;
18548            } else if (activitiesSize > 0) {
18549                for (int j = 0; j < activitiesSize; j++) {
18550                    final ActivityRecord r = app.activities.get(j);
18551                    if (r.visible) {
18552                        app.systemNoUi = false;
18553                    }
18554                }
18555            }
18556            if (!app.systemNoUi) {
18557                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18558            }
18559            return (app.curAdj=app.maxAdj);
18560        }
18561
18562        app.systemNoUi = false;
18563
18564        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18565
18566        // Determine the importance of the process, starting with most
18567        // important to least, and assign an appropriate OOM adjustment.
18568        int adj;
18569        int schedGroup;
18570        int procState;
18571        boolean foregroundActivities = false;
18572        BroadcastQueue queue;
18573        if (app == TOP_APP) {
18574            // The last app on the list is the foreground app.
18575            adj = ProcessList.FOREGROUND_APP_ADJ;
18576            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18577            app.adjType = "top-activity";
18578            foregroundActivities = true;
18579            procState = PROCESS_STATE_CUR_TOP;
18580        } else if (app.instrumentationClass != null) {
18581            // Don't want to kill running instrumentation.
18582            adj = ProcessList.FOREGROUND_APP_ADJ;
18583            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18584            app.adjType = "instrumentation";
18585            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18586        } else if ((queue = isReceivingBroadcast(app)) != null) {
18587            // An app that is currently receiving a broadcast also
18588            // counts as being in the foreground for OOM killer purposes.
18589            // It's placed in a sched group based on the nature of the
18590            // broadcast as reflected by which queue it's active in.
18591            adj = ProcessList.FOREGROUND_APP_ADJ;
18592            schedGroup = (queue == mFgBroadcastQueue)
18593                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18594            app.adjType = "broadcast";
18595            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18596        } else if (app.executingServices.size() > 0) {
18597            // An app that is currently executing a service callback also
18598            // counts as being in the foreground.
18599            adj = ProcessList.FOREGROUND_APP_ADJ;
18600            schedGroup = app.execServicesFg ?
18601                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18602            app.adjType = "exec-service";
18603            procState = ActivityManager.PROCESS_STATE_SERVICE;
18604            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18605        } else {
18606            // As far as we know the process is empty.  We may change our mind later.
18607            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18608            // At this point we don't actually know the adjustment.  Use the cached adj
18609            // value that the caller wants us to.
18610            adj = cachedAdj;
18611            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18612            app.cached = true;
18613            app.empty = true;
18614            app.adjType = "cch-empty";
18615        }
18616
18617        // Examine all activities if not already foreground.
18618        if (!foregroundActivities && activitiesSize > 0) {
18619            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18620            for (int j = 0; j < activitiesSize; j++) {
18621                final ActivityRecord r = app.activities.get(j);
18622                if (r.app != app) {
18623                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18624                            + " instead of expected " + app);
18625                    if (r.app == null || (r.app.uid == app.uid)) {
18626                        // Only fix things up when they look sane
18627                        r.app = app;
18628                    } else {
18629                        continue;
18630                    }
18631                }
18632                if (r.visible) {
18633                    // App has a visible activity; only upgrade adjustment.
18634                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18635                        adj = ProcessList.VISIBLE_APP_ADJ;
18636                        app.adjType = "visible";
18637                    }
18638                    if (procState > PROCESS_STATE_CUR_TOP) {
18639                        procState = PROCESS_STATE_CUR_TOP;
18640                    }
18641                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18642                    app.cached = false;
18643                    app.empty = false;
18644                    foregroundActivities = true;
18645                    if (r.task != null && minLayer > 0) {
18646                        final int layer = r.task.mLayerRank;
18647                        if (layer >= 0 && minLayer > layer) {
18648                            minLayer = layer;
18649                        }
18650                    }
18651                    break;
18652                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18653                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18654                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18655                        app.adjType = "pausing";
18656                    }
18657                    if (procState > PROCESS_STATE_CUR_TOP) {
18658                        procState = PROCESS_STATE_CUR_TOP;
18659                    }
18660                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18661                    app.cached = false;
18662                    app.empty = false;
18663                    foregroundActivities = true;
18664                } else if (r.state == ActivityState.STOPPING) {
18665                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18666                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18667                        app.adjType = "stopping";
18668                    }
18669                    // For the process state, we will at this point consider the
18670                    // process to be cached.  It will be cached either as an activity
18671                    // or empty depending on whether the activity is finishing.  We do
18672                    // this so that we can treat the process as cached for purposes of
18673                    // memory trimming (determing current memory level, trim command to
18674                    // send to process) since there can be an arbitrary number of stopping
18675                    // processes and they should soon all go into the cached state.
18676                    if (!r.finishing) {
18677                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18678                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18679                        }
18680                    }
18681                    app.cached = false;
18682                    app.empty = false;
18683                    foregroundActivities = true;
18684                } else {
18685                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18686                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18687                        app.adjType = "cch-act";
18688                    }
18689                }
18690            }
18691            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18692                adj += minLayer;
18693            }
18694        }
18695
18696        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18697                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18698            if (app.foregroundServices) {
18699                // The user is aware of this app, so make it visible.
18700                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18701                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18702                app.cached = false;
18703                app.adjType = "fg-service";
18704                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18705            } else if (app.forcingToForeground != null) {
18706                // The user is aware of this app, so make it visible.
18707                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18708                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18709                app.cached = false;
18710                app.adjType = "force-fg";
18711                app.adjSource = app.forcingToForeground;
18712                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18713            }
18714        }
18715
18716        if (app == mHeavyWeightProcess) {
18717            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18718                // We don't want to kill the current heavy-weight process.
18719                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18720                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18721                app.cached = false;
18722                app.adjType = "heavy";
18723            }
18724            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18725                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18726            }
18727        }
18728
18729        if (app == mHomeProcess) {
18730            if (adj > ProcessList.HOME_APP_ADJ) {
18731                // This process is hosting what we currently consider to be the
18732                // home app, so we don't want to let it go into the background.
18733                adj = ProcessList.HOME_APP_ADJ;
18734                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18735                app.cached = false;
18736                app.adjType = "home";
18737            }
18738            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18739                procState = ActivityManager.PROCESS_STATE_HOME;
18740            }
18741        }
18742
18743        if (app == mPreviousProcess && app.activities.size() > 0) {
18744            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18745                // This was the previous process that showed UI to the user.
18746                // We want to try to keep it around more aggressively, to give
18747                // a good experience around switching between two apps.
18748                adj = ProcessList.PREVIOUS_APP_ADJ;
18749                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18750                app.cached = false;
18751                app.adjType = "previous";
18752            }
18753            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18754                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18755            }
18756        }
18757
18758        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18759                + " reason=" + app.adjType);
18760
18761        // By default, we use the computed adjustment.  It may be changed if
18762        // there are applications dependent on our services or providers, but
18763        // this gives us a baseline and makes sure we don't get into an
18764        // infinite recursion.
18765        app.adjSeq = mAdjSeq;
18766        app.curRawAdj = adj;
18767        app.hasStartedServices = false;
18768
18769        if (mBackupTarget != null && app == mBackupTarget.app) {
18770            // If possible we want to avoid killing apps while they're being backed up
18771            if (adj > ProcessList.BACKUP_APP_ADJ) {
18772                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18773                adj = ProcessList.BACKUP_APP_ADJ;
18774                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18775                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18776                }
18777                app.adjType = "backup";
18778                app.cached = false;
18779            }
18780            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18781                procState = ActivityManager.PROCESS_STATE_BACKUP;
18782            }
18783        }
18784
18785        boolean mayBeTop = false;
18786
18787        for (int is = app.services.size()-1;
18788                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18789                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18790                        || procState > ActivityManager.PROCESS_STATE_TOP);
18791                is--) {
18792            ServiceRecord s = app.services.valueAt(is);
18793            if (s.startRequested) {
18794                app.hasStartedServices = true;
18795                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18796                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18797                }
18798                if (app.hasShownUi && app != mHomeProcess) {
18799                    // If this process has shown some UI, let it immediately
18800                    // go to the LRU list because it may be pretty heavy with
18801                    // UI stuff.  We'll tag it with a label just to help
18802                    // debug and understand what is going on.
18803                    if (adj > ProcessList.SERVICE_ADJ) {
18804                        app.adjType = "cch-started-ui-services";
18805                    }
18806                } else {
18807                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18808                        // This service has seen some activity within
18809                        // recent memory, so we will keep its process ahead
18810                        // of the background processes.
18811                        if (adj > ProcessList.SERVICE_ADJ) {
18812                            adj = ProcessList.SERVICE_ADJ;
18813                            app.adjType = "started-services";
18814                            app.cached = false;
18815                        }
18816                    }
18817                    // If we have let the service slide into the background
18818                    // state, still have some text describing what it is doing
18819                    // even though the service no longer has an impact.
18820                    if (adj > ProcessList.SERVICE_ADJ) {
18821                        app.adjType = "cch-started-services";
18822                    }
18823                }
18824            }
18825            for (int conni = s.connections.size()-1;
18826                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18827                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18828                            || procState > ActivityManager.PROCESS_STATE_TOP);
18829                    conni--) {
18830                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18831                for (int i = 0;
18832                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18833                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18834                                || procState > ActivityManager.PROCESS_STATE_TOP);
18835                        i++) {
18836                    // XXX should compute this based on the max of
18837                    // all connected clients.
18838                    ConnectionRecord cr = clist.get(i);
18839                    if (cr.binding.client == app) {
18840                        // Binding to ourself is not interesting.
18841                        continue;
18842                    }
18843                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18844                        ProcessRecord client = cr.binding.client;
18845                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18846                                TOP_APP, doingAll, now);
18847                        int clientProcState = client.curProcState;
18848                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18849                            // If the other app is cached for any reason, for purposes here
18850                            // we are going to consider it empty.  The specific cached state
18851                            // doesn't propagate except under certain conditions.
18852                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18853                        }
18854                        String adjType = null;
18855                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18856                            // Not doing bind OOM management, so treat
18857                            // this guy more like a started service.
18858                            if (app.hasShownUi && app != mHomeProcess) {
18859                                // If this process has shown some UI, let it immediately
18860                                // go to the LRU list because it may be pretty heavy with
18861                                // UI stuff.  We'll tag it with a label just to help
18862                                // debug and understand what is going on.
18863                                if (adj > clientAdj) {
18864                                    adjType = "cch-bound-ui-services";
18865                                }
18866                                app.cached = false;
18867                                clientAdj = adj;
18868                                clientProcState = procState;
18869                            } else {
18870                                if (now >= (s.lastActivity
18871                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18872                                    // This service has not seen activity within
18873                                    // recent memory, so allow it to drop to the
18874                                    // LRU list if there is no other reason to keep
18875                                    // it around.  We'll also tag it with a label just
18876                                    // to help debug and undertand what is going on.
18877                                    if (adj > clientAdj) {
18878                                        adjType = "cch-bound-services";
18879                                    }
18880                                    clientAdj = adj;
18881                                }
18882                            }
18883                        }
18884                        if (adj > clientAdj) {
18885                            // If this process has recently shown UI, and
18886                            // the process that is binding to it is less
18887                            // important than being visible, then we don't
18888                            // care about the binding as much as we care
18889                            // about letting this process get into the LRU
18890                            // list to be killed and restarted if needed for
18891                            // memory.
18892                            if (app.hasShownUi && app != mHomeProcess
18893                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18894                                adjType = "cch-bound-ui-services";
18895                            } else {
18896                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18897                                        |Context.BIND_IMPORTANT)) != 0) {
18898                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18899                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18900                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18901                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18902                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18903                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18904                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18905                                    adj = clientAdj;
18906                                } else {
18907                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18908                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18909                                    }
18910                                }
18911                                if (!client.cached) {
18912                                    app.cached = false;
18913                                }
18914                                adjType = "service";
18915                            }
18916                        }
18917                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18918                            // This will treat important bound services identically to
18919                            // the top app, which may behave differently than generic
18920                            // foreground work.
18921                            if (client.curSchedGroup > schedGroup) {
18922                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18923                                    schedGroup = client.curSchedGroup;
18924                                } else {
18925                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18926                                }
18927                            }
18928                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18929                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18930                                    // Special handling of clients who are in the top state.
18931                                    // We *may* want to consider this process to be in the
18932                                    // top state as well, but only if there is not another
18933                                    // reason for it to be running.  Being on the top is a
18934                                    // special state, meaning you are specifically running
18935                                    // for the current top app.  If the process is already
18936                                    // running in the background for some other reason, it
18937                                    // is more important to continue considering it to be
18938                                    // in the background state.
18939                                    mayBeTop = true;
18940                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18941                                } else {
18942                                    // Special handling for above-top states (persistent
18943                                    // processes).  These should not bring the current process
18944                                    // into the top state, since they are not on top.  Instead
18945                                    // give them the best state after that.
18946                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18947                                        clientProcState =
18948                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18949                                    } else if (mWakefulness
18950                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18951                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18952                                                    != 0) {
18953                                        clientProcState =
18954                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18955                                    } else {
18956                                        clientProcState =
18957                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18958                                    }
18959                                }
18960                            }
18961                        } else {
18962                            if (clientProcState <
18963                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18964                                clientProcState =
18965                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18966                            }
18967                        }
18968                        if (procState > clientProcState) {
18969                            procState = clientProcState;
18970                        }
18971                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18972                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18973                            app.pendingUiClean = true;
18974                        }
18975                        if (adjType != null) {
18976                            app.adjType = adjType;
18977                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18978                                    .REASON_SERVICE_IN_USE;
18979                            app.adjSource = cr.binding.client;
18980                            app.adjSourceProcState = clientProcState;
18981                            app.adjTarget = s.name;
18982                        }
18983                    }
18984                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18985                        app.treatLikeActivity = true;
18986                    }
18987                    final ActivityRecord a = cr.activity;
18988                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18989                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18990                            (a.visible || a.state == ActivityState.RESUMED ||
18991                             a.state == ActivityState.PAUSING)) {
18992                            adj = ProcessList.FOREGROUND_APP_ADJ;
18993                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18994                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18995                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18996                                } else {
18997                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18998                                }
18999                            }
19000                            app.cached = false;
19001                            app.adjType = "service";
19002                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19003                                    .REASON_SERVICE_IN_USE;
19004                            app.adjSource = a;
19005                            app.adjSourceProcState = procState;
19006                            app.adjTarget = s.name;
19007                        }
19008                    }
19009                }
19010            }
19011        }
19012
19013        for (int provi = app.pubProviders.size()-1;
19014                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19015                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19016                        || procState > ActivityManager.PROCESS_STATE_TOP);
19017                provi--) {
19018            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19019            for (int i = cpr.connections.size()-1;
19020                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19021                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19022                            || procState > ActivityManager.PROCESS_STATE_TOP);
19023                    i--) {
19024                ContentProviderConnection conn = cpr.connections.get(i);
19025                ProcessRecord client = conn.client;
19026                if (client == app) {
19027                    // Being our own client is not interesting.
19028                    continue;
19029                }
19030                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19031                int clientProcState = client.curProcState;
19032                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19033                    // If the other app is cached for any reason, for purposes here
19034                    // we are going to consider it empty.
19035                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19036                }
19037                if (adj > clientAdj) {
19038                    if (app.hasShownUi && app != mHomeProcess
19039                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19040                        app.adjType = "cch-ui-provider";
19041                    } else {
19042                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19043                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19044                        app.adjType = "provider";
19045                    }
19046                    app.cached &= client.cached;
19047                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19048                            .REASON_PROVIDER_IN_USE;
19049                    app.adjSource = client;
19050                    app.adjSourceProcState = clientProcState;
19051                    app.adjTarget = cpr.name;
19052                }
19053                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19054                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19055                        // Special handling of clients who are in the top state.
19056                        // We *may* want to consider this process to be in the
19057                        // top state as well, but only if there is not another
19058                        // reason for it to be running.  Being on the top is a
19059                        // special state, meaning you are specifically running
19060                        // for the current top app.  If the process is already
19061                        // running in the background for some other reason, it
19062                        // is more important to continue considering it to be
19063                        // in the background state.
19064                        mayBeTop = true;
19065                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19066                    } else {
19067                        // Special handling for above-top states (persistent
19068                        // processes).  These should not bring the current process
19069                        // into the top state, since they are not on top.  Instead
19070                        // give them the best state after that.
19071                        clientProcState =
19072                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19073                    }
19074                }
19075                if (procState > clientProcState) {
19076                    procState = clientProcState;
19077                }
19078                if (client.curSchedGroup > schedGroup) {
19079                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19080                }
19081            }
19082            // If the provider has external (non-framework) process
19083            // dependencies, ensure that its adjustment is at least
19084            // FOREGROUND_APP_ADJ.
19085            if (cpr.hasExternalProcessHandles()) {
19086                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19087                    adj = ProcessList.FOREGROUND_APP_ADJ;
19088                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19089                    app.cached = false;
19090                    app.adjType = "provider";
19091                    app.adjTarget = cpr.name;
19092                }
19093                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19094                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19095                }
19096            }
19097        }
19098
19099        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19100            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19101                adj = ProcessList.PREVIOUS_APP_ADJ;
19102                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19103                app.cached = false;
19104                app.adjType = "provider";
19105            }
19106            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19107                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19108            }
19109        }
19110
19111        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19112            // A client of one of our services or providers is in the top state.  We
19113            // *may* want to be in the top state, but not if we are already running in
19114            // the background for some other reason.  For the decision here, we are going
19115            // to pick out a few specific states that we want to remain in when a client
19116            // is top (states that tend to be longer-term) and otherwise allow it to go
19117            // to the top state.
19118            switch (procState) {
19119                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19120                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19121                case ActivityManager.PROCESS_STATE_SERVICE:
19122                    // These all are longer-term states, so pull them up to the top
19123                    // of the background states, but not all the way to the top state.
19124                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19125                    break;
19126                default:
19127                    // Otherwise, top is a better choice, so take it.
19128                    procState = ActivityManager.PROCESS_STATE_TOP;
19129                    break;
19130            }
19131        }
19132
19133        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19134            if (app.hasClientActivities) {
19135                // This is a cached process, but with client activities.  Mark it so.
19136                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19137                app.adjType = "cch-client-act";
19138            } else if (app.treatLikeActivity) {
19139                // This is a cached process, but somebody wants us to treat it like it has
19140                // an activity, okay!
19141                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19142                app.adjType = "cch-as-act";
19143            }
19144        }
19145
19146        if (adj == ProcessList.SERVICE_ADJ) {
19147            if (doingAll) {
19148                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19149                mNewNumServiceProcs++;
19150                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19151                if (!app.serviceb) {
19152                    // This service isn't far enough down on the LRU list to
19153                    // normally be a B service, but if we are low on RAM and it
19154                    // is large we want to force it down since we would prefer to
19155                    // keep launcher over it.
19156                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19157                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19158                        app.serviceHighRam = true;
19159                        app.serviceb = true;
19160                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19161                    } else {
19162                        mNewNumAServiceProcs++;
19163                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19164                    }
19165                } else {
19166                    app.serviceHighRam = false;
19167                }
19168            }
19169            if (app.serviceb) {
19170                adj = ProcessList.SERVICE_B_ADJ;
19171            }
19172        }
19173
19174        app.curRawAdj = adj;
19175
19176        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19177        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19178        if (adj > app.maxAdj) {
19179            adj = app.maxAdj;
19180            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19181                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19182            }
19183        }
19184
19185        // Do final modification to adj.  Everything we do between here and applying
19186        // the final setAdj must be done in this function, because we will also use
19187        // it when computing the final cached adj later.  Note that we don't need to
19188        // worry about this for max adj above, since max adj will always be used to
19189        // keep it out of the cached vaues.
19190        app.curAdj = app.modifyRawOomAdj(adj);
19191        app.curSchedGroup = schedGroup;
19192        app.curProcState = procState;
19193        app.foregroundActivities = foregroundActivities;
19194
19195        return app.curRawAdj;
19196    }
19197
19198    /**
19199     * Record new PSS sample for a process.
19200     */
19201    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19202            long now) {
19203        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19204                swapPss * 1024);
19205        proc.lastPssTime = now;
19206        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19207        if (DEBUG_PSS) Slog.d(TAG_PSS,
19208                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19209                + " state=" + ProcessList.makeProcStateString(procState));
19210        if (proc.initialIdlePss == 0) {
19211            proc.initialIdlePss = pss;
19212        }
19213        proc.lastPss = pss;
19214        proc.lastSwapPss = swapPss;
19215        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19216            proc.lastCachedPss = pss;
19217            proc.lastCachedSwapPss = swapPss;
19218        }
19219
19220        final SparseArray<Pair<Long, String>> watchUids
19221                = mMemWatchProcesses.getMap().get(proc.processName);
19222        Long check = null;
19223        if (watchUids != null) {
19224            Pair<Long, String> val = watchUids.get(proc.uid);
19225            if (val == null) {
19226                val = watchUids.get(0);
19227            }
19228            if (val != null) {
19229                check = val.first;
19230            }
19231        }
19232        if (check != null) {
19233            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19234                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19235                if (!isDebuggable) {
19236                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19237                        isDebuggable = true;
19238                    }
19239                }
19240                if (isDebuggable) {
19241                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19242                    final ProcessRecord myProc = proc;
19243                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19244                    mMemWatchDumpProcName = proc.processName;
19245                    mMemWatchDumpFile = heapdumpFile.toString();
19246                    mMemWatchDumpPid = proc.pid;
19247                    mMemWatchDumpUid = proc.uid;
19248                    BackgroundThread.getHandler().post(new Runnable() {
19249                        @Override
19250                        public void run() {
19251                            revokeUriPermission(ActivityThread.currentActivityThread()
19252                                            .getApplicationThread(),
19253                                    DumpHeapActivity.JAVA_URI,
19254                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19255                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19256                                    UserHandle.myUserId());
19257                            ParcelFileDescriptor fd = null;
19258                            try {
19259                                heapdumpFile.delete();
19260                                fd = ParcelFileDescriptor.open(heapdumpFile,
19261                                        ParcelFileDescriptor.MODE_CREATE |
19262                                                ParcelFileDescriptor.MODE_TRUNCATE |
19263                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19264                                                ParcelFileDescriptor.MODE_APPEND);
19265                                IApplicationThread thread = myProc.thread;
19266                                if (thread != null) {
19267                                    try {
19268                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19269                                                "Requesting dump heap from "
19270                                                + myProc + " to " + heapdumpFile);
19271                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19272                                    } catch (RemoteException e) {
19273                                    }
19274                                }
19275                            } catch (FileNotFoundException e) {
19276                                e.printStackTrace();
19277                            } finally {
19278                                if (fd != null) {
19279                                    try {
19280                                        fd.close();
19281                                    } catch (IOException e) {
19282                                    }
19283                                }
19284                            }
19285                        }
19286                    });
19287                } else {
19288                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19289                            + ", but debugging not enabled");
19290                }
19291            }
19292        }
19293    }
19294
19295    /**
19296     * Schedule PSS collection of a process.
19297     */
19298    void requestPssLocked(ProcessRecord proc, int procState) {
19299        if (mPendingPssProcesses.contains(proc)) {
19300            return;
19301        }
19302        if (mPendingPssProcesses.size() == 0) {
19303            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19304        }
19305        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19306        proc.pssProcState = procState;
19307        mPendingPssProcesses.add(proc);
19308    }
19309
19310    /**
19311     * Schedule PSS collection of all processes.
19312     */
19313    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19314        if (!always) {
19315            if (now < (mLastFullPssTime +
19316                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19317                return;
19318            }
19319        }
19320        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19321        mLastFullPssTime = now;
19322        mFullPssPending = true;
19323        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19324        mPendingPssProcesses.clear();
19325        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19326            ProcessRecord app = mLruProcesses.get(i);
19327            if (app.thread == null
19328                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19329                continue;
19330            }
19331            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19332                app.pssProcState = app.setProcState;
19333                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19334                        mTestPssMode, isSleeping(), now);
19335                mPendingPssProcesses.add(app);
19336            }
19337        }
19338        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19339    }
19340
19341    public void setTestPssMode(boolean enabled) {
19342        synchronized (this) {
19343            mTestPssMode = enabled;
19344            if (enabled) {
19345                // Whenever we enable the mode, we want to take a snapshot all of current
19346                // process mem use.
19347                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19348            }
19349        }
19350    }
19351
19352    /**
19353     * Ask a given process to GC right now.
19354     */
19355    final void performAppGcLocked(ProcessRecord app) {
19356        try {
19357            app.lastRequestedGc = SystemClock.uptimeMillis();
19358            if (app.thread != null) {
19359                if (app.reportLowMemory) {
19360                    app.reportLowMemory = false;
19361                    app.thread.scheduleLowMemory();
19362                } else {
19363                    app.thread.processInBackground();
19364                }
19365            }
19366        } catch (Exception e) {
19367            // whatever.
19368        }
19369    }
19370
19371    /**
19372     * Returns true if things are idle enough to perform GCs.
19373     */
19374    private final boolean canGcNowLocked() {
19375        boolean processingBroadcasts = false;
19376        for (BroadcastQueue q : mBroadcastQueues) {
19377            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19378                processingBroadcasts = true;
19379            }
19380        }
19381        return !processingBroadcasts
19382                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19383    }
19384
19385    /**
19386     * Perform GCs on all processes that are waiting for it, but only
19387     * if things are idle.
19388     */
19389    final void performAppGcsLocked() {
19390        final int N = mProcessesToGc.size();
19391        if (N <= 0) {
19392            return;
19393        }
19394        if (canGcNowLocked()) {
19395            while (mProcessesToGc.size() > 0) {
19396                ProcessRecord proc = mProcessesToGc.remove(0);
19397                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19398                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19399                            <= SystemClock.uptimeMillis()) {
19400                        // To avoid spamming the system, we will GC processes one
19401                        // at a time, waiting a few seconds between each.
19402                        performAppGcLocked(proc);
19403                        scheduleAppGcsLocked();
19404                        return;
19405                    } else {
19406                        // It hasn't been long enough since we last GCed this
19407                        // process...  put it in the list to wait for its time.
19408                        addProcessToGcListLocked(proc);
19409                        break;
19410                    }
19411                }
19412            }
19413
19414            scheduleAppGcsLocked();
19415        }
19416    }
19417
19418    /**
19419     * If all looks good, perform GCs on all processes waiting for them.
19420     */
19421    final void performAppGcsIfAppropriateLocked() {
19422        if (canGcNowLocked()) {
19423            performAppGcsLocked();
19424            return;
19425        }
19426        // Still not idle, wait some more.
19427        scheduleAppGcsLocked();
19428    }
19429
19430    /**
19431     * Schedule the execution of all pending app GCs.
19432     */
19433    final void scheduleAppGcsLocked() {
19434        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19435
19436        if (mProcessesToGc.size() > 0) {
19437            // Schedule a GC for the time to the next process.
19438            ProcessRecord proc = mProcessesToGc.get(0);
19439            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19440
19441            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19442            long now = SystemClock.uptimeMillis();
19443            if (when < (now+GC_TIMEOUT)) {
19444                when = now + GC_TIMEOUT;
19445            }
19446            mHandler.sendMessageAtTime(msg, when);
19447        }
19448    }
19449
19450    /**
19451     * Add a process to the array of processes waiting to be GCed.  Keeps the
19452     * list in sorted order by the last GC time.  The process can't already be
19453     * on the list.
19454     */
19455    final void addProcessToGcListLocked(ProcessRecord proc) {
19456        boolean added = false;
19457        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19458            if (mProcessesToGc.get(i).lastRequestedGc <
19459                    proc.lastRequestedGc) {
19460                added = true;
19461                mProcessesToGc.add(i+1, proc);
19462                break;
19463            }
19464        }
19465        if (!added) {
19466            mProcessesToGc.add(0, proc);
19467        }
19468    }
19469
19470    /**
19471     * Set up to ask a process to GC itself.  This will either do it
19472     * immediately, or put it on the list of processes to gc the next
19473     * time things are idle.
19474     */
19475    final void scheduleAppGcLocked(ProcessRecord app) {
19476        long now = SystemClock.uptimeMillis();
19477        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19478            return;
19479        }
19480        if (!mProcessesToGc.contains(app)) {
19481            addProcessToGcListLocked(app);
19482            scheduleAppGcsLocked();
19483        }
19484    }
19485
19486    final void checkExcessivePowerUsageLocked(boolean doKills) {
19487        updateCpuStatsNow();
19488
19489        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19490        boolean doWakeKills = doKills;
19491        boolean doCpuKills = doKills;
19492        if (mLastPowerCheckRealtime == 0) {
19493            doWakeKills = false;
19494        }
19495        if (mLastPowerCheckUptime == 0) {
19496            doCpuKills = false;
19497        }
19498        if (stats.isScreenOn()) {
19499            doWakeKills = false;
19500        }
19501        final long curRealtime = SystemClock.elapsedRealtime();
19502        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19503        final long curUptime = SystemClock.uptimeMillis();
19504        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19505        mLastPowerCheckRealtime = curRealtime;
19506        mLastPowerCheckUptime = curUptime;
19507        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19508            doWakeKills = false;
19509        }
19510        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19511            doCpuKills = false;
19512        }
19513        int i = mLruProcesses.size();
19514        while (i > 0) {
19515            i--;
19516            ProcessRecord app = mLruProcesses.get(i);
19517            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19518                long wtime;
19519                synchronized (stats) {
19520                    wtime = stats.getProcessWakeTime(app.info.uid,
19521                            app.pid, curRealtime);
19522                }
19523                long wtimeUsed = wtime - app.lastWakeTime;
19524                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19525                if (DEBUG_POWER) {
19526                    StringBuilder sb = new StringBuilder(128);
19527                    sb.append("Wake for ");
19528                    app.toShortString(sb);
19529                    sb.append(": over ");
19530                    TimeUtils.formatDuration(realtimeSince, sb);
19531                    sb.append(" used ");
19532                    TimeUtils.formatDuration(wtimeUsed, sb);
19533                    sb.append(" (");
19534                    sb.append((wtimeUsed*100)/realtimeSince);
19535                    sb.append("%)");
19536                    Slog.i(TAG_POWER, sb.toString());
19537                    sb.setLength(0);
19538                    sb.append("CPU for ");
19539                    app.toShortString(sb);
19540                    sb.append(": over ");
19541                    TimeUtils.formatDuration(uptimeSince, sb);
19542                    sb.append(" used ");
19543                    TimeUtils.formatDuration(cputimeUsed, sb);
19544                    sb.append(" (");
19545                    sb.append((cputimeUsed*100)/uptimeSince);
19546                    sb.append("%)");
19547                    Slog.i(TAG_POWER, sb.toString());
19548                }
19549                // If a process has held a wake lock for more
19550                // than 50% of the time during this period,
19551                // that sounds bad.  Kill!
19552                if (doWakeKills && realtimeSince > 0
19553                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19554                    synchronized (stats) {
19555                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19556                                realtimeSince, wtimeUsed);
19557                    }
19558                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19559                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19560                } else if (doCpuKills && uptimeSince > 0
19561                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19562                    synchronized (stats) {
19563                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19564                                uptimeSince, cputimeUsed);
19565                    }
19566                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19567                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19568                } else {
19569                    app.lastWakeTime = wtime;
19570                    app.lastCpuTime = app.curCpuTime;
19571                }
19572            }
19573        }
19574    }
19575
19576    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19577            long nowElapsed) {
19578        boolean success = true;
19579
19580        if (app.curRawAdj != app.setRawAdj) {
19581            app.setRawAdj = app.curRawAdj;
19582        }
19583
19584        int changes = 0;
19585
19586        if (app.curAdj != app.setAdj) {
19587            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19588            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19589                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19590                    + app.adjType);
19591            app.setAdj = app.curAdj;
19592        }
19593
19594        if (app.setSchedGroup != app.curSchedGroup) {
19595            app.setSchedGroup = app.curSchedGroup;
19596            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19597                    "Setting sched group of " + app.processName
19598                    + " to " + app.curSchedGroup);
19599            if (app.waitingToKill != null && app.curReceiver == null
19600                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19601                app.kill(app.waitingToKill, true);
19602                success = false;
19603            } else {
19604                int processGroup;
19605                switch (app.curSchedGroup) {
19606                    case ProcessList.SCHED_GROUP_BACKGROUND:
19607                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19608                        break;
19609                    case ProcessList.SCHED_GROUP_TOP_APP:
19610                        processGroup = Process.THREAD_GROUP_TOP_APP;
19611                        break;
19612                    default:
19613                        processGroup = Process.THREAD_GROUP_DEFAULT;
19614                        break;
19615                }
19616                if (true) {
19617                    long oldId = Binder.clearCallingIdentity();
19618                    try {
19619                        Process.setProcessGroup(app.pid, processGroup);
19620                    } catch (Exception e) {
19621                        Slog.w(TAG, "Failed setting process group of " + app.pid
19622                                + " to " + app.curSchedGroup);
19623                        e.printStackTrace();
19624                    } finally {
19625                        Binder.restoreCallingIdentity(oldId);
19626                    }
19627                } else {
19628                    if (app.thread != null) {
19629                        try {
19630                            app.thread.setSchedulingGroup(processGroup);
19631                        } catch (RemoteException e) {
19632                        }
19633                    }
19634                }
19635            }
19636        }
19637        if (app.repForegroundActivities != app.foregroundActivities) {
19638            app.repForegroundActivities = app.foregroundActivities;
19639            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19640        }
19641        if (app.repProcState != app.curProcState) {
19642            app.repProcState = app.curProcState;
19643            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19644            if (app.thread != null) {
19645                try {
19646                    if (false) {
19647                        //RuntimeException h = new RuntimeException("here");
19648                        Slog.i(TAG, "Sending new process state " + app.repProcState
19649                                + " to " + app /*, h*/);
19650                    }
19651                    app.thread.setProcessState(app.repProcState);
19652                } catch (RemoteException e) {
19653                }
19654            }
19655        }
19656        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19657                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19658            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19659                // Experimental code to more aggressively collect pss while
19660                // running test...  the problem is that this tends to collect
19661                // the data right when a process is transitioning between process
19662                // states, which well tend to give noisy data.
19663                long start = SystemClock.uptimeMillis();
19664                long pss = Debug.getPss(app.pid, mTmpLong, null);
19665                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19666                mPendingPssProcesses.remove(app);
19667                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19668                        + " to " + app.curProcState + ": "
19669                        + (SystemClock.uptimeMillis()-start) + "ms");
19670            }
19671            app.lastStateTime = now;
19672            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19673                    mTestPssMode, isSleeping(), now);
19674            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19675                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19676                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19677                    + (app.nextPssTime-now) + ": " + app);
19678        } else {
19679            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19680                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19681                    mTestPssMode)))) {
19682                requestPssLocked(app, app.setProcState);
19683                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19684                        mTestPssMode, isSleeping(), now);
19685            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19686                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19687        }
19688        if (app.setProcState != app.curProcState) {
19689            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19690                    "Proc state change of " + app.processName
19691                            + " to " + app.curProcState);
19692            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19693            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19694            if (setImportant && !curImportant) {
19695                // This app is no longer something we consider important enough to allow to
19696                // use arbitrary amounts of battery power.  Note
19697                // its current wake lock time to later know to kill it if
19698                // it is not behaving well.
19699                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19700                synchronized (stats) {
19701                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19702                            app.pid, nowElapsed);
19703                }
19704                app.lastCpuTime = app.curCpuTime;
19705
19706            }
19707            // Inform UsageStats of important process state change
19708            // Must be called before updating setProcState
19709            maybeUpdateUsageStatsLocked(app, nowElapsed);
19710
19711            app.setProcState = app.curProcState;
19712            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19713                app.notCachedSinceIdle = false;
19714            }
19715            if (!doingAll) {
19716                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19717            } else {
19718                app.procStateChanged = true;
19719            }
19720        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19721                > USAGE_STATS_INTERACTION_INTERVAL) {
19722            // For apps that sit around for a long time in the interactive state, we need
19723            // to report this at least once a day so they don't go idle.
19724            maybeUpdateUsageStatsLocked(app, nowElapsed);
19725        }
19726
19727        if (changes != 0) {
19728            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19729                    "Changes in " + app + ": " + changes);
19730            int i = mPendingProcessChanges.size()-1;
19731            ProcessChangeItem item = null;
19732            while (i >= 0) {
19733                item = mPendingProcessChanges.get(i);
19734                if (item.pid == app.pid) {
19735                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19736                            "Re-using existing item: " + item);
19737                    break;
19738                }
19739                i--;
19740            }
19741            if (i < 0) {
19742                // No existing item in pending changes; need a new one.
19743                final int NA = mAvailProcessChanges.size();
19744                if (NA > 0) {
19745                    item = mAvailProcessChanges.remove(NA-1);
19746                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19747                            "Retrieving available item: " + item);
19748                } else {
19749                    item = new ProcessChangeItem();
19750                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19751                            "Allocating new item: " + item);
19752                }
19753                item.changes = 0;
19754                item.pid = app.pid;
19755                item.uid = app.info.uid;
19756                if (mPendingProcessChanges.size() == 0) {
19757                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19758                            "*** Enqueueing dispatch processes changed!");
19759                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19760                }
19761                mPendingProcessChanges.add(item);
19762            }
19763            item.changes |= changes;
19764            item.processState = app.repProcState;
19765            item.foregroundActivities = app.repForegroundActivities;
19766            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19767                    "Item " + Integer.toHexString(System.identityHashCode(item))
19768                    + " " + app.toShortString() + ": changes=" + item.changes
19769                    + " procState=" + item.processState
19770                    + " foreground=" + item.foregroundActivities
19771                    + " type=" + app.adjType + " source=" + app.adjSource
19772                    + " target=" + app.adjTarget);
19773        }
19774
19775        return success;
19776    }
19777
19778    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19779        final UidRecord.ChangeItem pendingChange;
19780        if (uidRec == null || uidRec.pendingChange == null) {
19781            if (mPendingUidChanges.size() == 0) {
19782                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19783                        "*** Enqueueing dispatch uid changed!");
19784                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19785            }
19786            final int NA = mAvailUidChanges.size();
19787            if (NA > 0) {
19788                pendingChange = mAvailUidChanges.remove(NA-1);
19789                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19790                        "Retrieving available item: " + pendingChange);
19791            } else {
19792                pendingChange = new UidRecord.ChangeItem();
19793                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19794                        "Allocating new item: " + pendingChange);
19795            }
19796            if (uidRec != null) {
19797                uidRec.pendingChange = pendingChange;
19798                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19799                    // If this uid is going away, and we haven't yet reported it is gone,
19800                    // then do so now.
19801                    change = UidRecord.CHANGE_GONE_IDLE;
19802                }
19803            } else if (uid < 0) {
19804                throw new IllegalArgumentException("No UidRecord or uid");
19805            }
19806            pendingChange.uidRecord = uidRec;
19807            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19808            mPendingUidChanges.add(pendingChange);
19809        } else {
19810            pendingChange = uidRec.pendingChange;
19811            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19812                change = UidRecord.CHANGE_GONE_IDLE;
19813            }
19814        }
19815        pendingChange.change = change;
19816        pendingChange.processState = uidRec != null
19817                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19818    }
19819
19820    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19821            String authority) {
19822        if (app == null) return;
19823        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19824            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19825            if (userState == null) return;
19826            final long now = SystemClock.elapsedRealtime();
19827            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19828            if (lastReported == null || lastReported < now - 60 * 1000L) {
19829                mUsageStatsService.reportContentProviderUsage(
19830                        authority, providerPkgName, app.userId);
19831                userState.mProviderLastReportedFg.put(authority, now);
19832            }
19833        }
19834    }
19835
19836    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19837        if (DEBUG_USAGE_STATS) {
19838            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19839                    + "] state changes: old = " + app.setProcState + ", new = "
19840                    + app.curProcState);
19841        }
19842        if (mUsageStatsService == null) {
19843            return;
19844        }
19845        boolean isInteraction;
19846        // To avoid some abuse patterns, we are going to be careful about what we consider
19847        // to be an app interaction.  Being the top activity doesn't count while the display
19848        // is sleeping, nor do short foreground services.
19849        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19850            isInteraction = true;
19851            app.fgInteractionTime = 0;
19852        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19853            if (app.fgInteractionTime == 0) {
19854                app.fgInteractionTime = nowElapsed;
19855                isInteraction = false;
19856            } else {
19857                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19858            }
19859        } else {
19860            isInteraction = app.curProcState
19861                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19862            app.fgInteractionTime = 0;
19863        }
19864        if (isInteraction && (!app.reportedInteraction
19865                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19866            app.interactionEventTime = nowElapsed;
19867            String[] packages = app.getPackageList();
19868            if (packages != null) {
19869                for (int i = 0; i < packages.length; i++) {
19870                    mUsageStatsService.reportEvent(packages[i], app.userId,
19871                            UsageEvents.Event.SYSTEM_INTERACTION);
19872                }
19873            }
19874        }
19875        app.reportedInteraction = isInteraction;
19876        if (!isInteraction) {
19877            app.interactionEventTime = 0;
19878        }
19879    }
19880
19881    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19882        if (proc.thread != null) {
19883            if (proc.baseProcessTracker != null) {
19884                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19885            }
19886        }
19887    }
19888
19889    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19890            ProcessRecord TOP_APP, boolean doingAll, long now) {
19891        if (app.thread == null) {
19892            return false;
19893        }
19894
19895        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19896
19897        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19898    }
19899
19900    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19901            boolean oomAdj) {
19902        if (isForeground != proc.foregroundServices) {
19903            proc.foregroundServices = isForeground;
19904            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19905                    proc.info.uid);
19906            if (isForeground) {
19907                if (curProcs == null) {
19908                    curProcs = new ArrayList<ProcessRecord>();
19909                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19910                }
19911                if (!curProcs.contains(proc)) {
19912                    curProcs.add(proc);
19913                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19914                            proc.info.packageName, proc.info.uid);
19915                }
19916            } else {
19917                if (curProcs != null) {
19918                    if (curProcs.remove(proc)) {
19919                        mBatteryStatsService.noteEvent(
19920                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19921                                proc.info.packageName, proc.info.uid);
19922                        if (curProcs.size() <= 0) {
19923                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19924                        }
19925                    }
19926                }
19927            }
19928            if (oomAdj) {
19929                updateOomAdjLocked();
19930            }
19931        }
19932    }
19933
19934    private final ActivityRecord resumedAppLocked() {
19935        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19936        String pkg;
19937        int uid;
19938        if (act != null) {
19939            pkg = act.packageName;
19940            uid = act.info.applicationInfo.uid;
19941        } else {
19942            pkg = null;
19943            uid = -1;
19944        }
19945        // Has the UID or resumed package name changed?
19946        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19947                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19948            if (mCurResumedPackage != null) {
19949                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19950                        mCurResumedPackage, mCurResumedUid);
19951            }
19952            mCurResumedPackage = pkg;
19953            mCurResumedUid = uid;
19954            if (mCurResumedPackage != null) {
19955                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19956                        mCurResumedPackage, mCurResumedUid);
19957            }
19958        }
19959        return act;
19960    }
19961
19962    final boolean updateOomAdjLocked(ProcessRecord app) {
19963        final ActivityRecord TOP_ACT = resumedAppLocked();
19964        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19965        final boolean wasCached = app.cached;
19966
19967        mAdjSeq++;
19968
19969        // This is the desired cached adjusment we want to tell it to use.
19970        // If our app is currently cached, we know it, and that is it.  Otherwise,
19971        // we don't know it yet, and it needs to now be cached we will then
19972        // need to do a complete oom adj.
19973        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19974                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19975        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19976                SystemClock.uptimeMillis());
19977        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19978            // Changed to/from cached state, so apps after it in the LRU
19979            // list may also be changed.
19980            updateOomAdjLocked();
19981        }
19982        return success;
19983    }
19984
19985    final void updateOomAdjLocked() {
19986        final ActivityRecord TOP_ACT = resumedAppLocked();
19987        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19988        final long now = SystemClock.uptimeMillis();
19989        final long nowElapsed = SystemClock.elapsedRealtime();
19990        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19991        final int N = mLruProcesses.size();
19992
19993        if (false) {
19994            RuntimeException e = new RuntimeException();
19995            e.fillInStackTrace();
19996            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19997        }
19998
19999        // Reset state in all uid records.
20000        for (int i=mActiveUids.size()-1; i>=0; i--) {
20001            final UidRecord uidRec = mActiveUids.valueAt(i);
20002            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20003                    "Starting update of " + uidRec);
20004            uidRec.reset();
20005        }
20006
20007        mStackSupervisor.rankTaskLayersIfNeeded();
20008
20009        mAdjSeq++;
20010        mNewNumServiceProcs = 0;
20011        mNewNumAServiceProcs = 0;
20012
20013        final int emptyProcessLimit;
20014        final int cachedProcessLimit;
20015        if (mProcessLimit <= 0) {
20016            emptyProcessLimit = cachedProcessLimit = 0;
20017        } else if (mProcessLimit == 1) {
20018            emptyProcessLimit = 1;
20019            cachedProcessLimit = 0;
20020        } else {
20021            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20022            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20023        }
20024
20025        // Let's determine how many processes we have running vs.
20026        // how many slots we have for background processes; we may want
20027        // to put multiple processes in a slot of there are enough of
20028        // them.
20029        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20030                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20031        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20032        if (numEmptyProcs > cachedProcessLimit) {
20033            // If there are more empty processes than our limit on cached
20034            // processes, then use the cached process limit for the factor.
20035            // This ensures that the really old empty processes get pushed
20036            // down to the bottom, so if we are running low on memory we will
20037            // have a better chance at keeping around more cached processes
20038            // instead of a gazillion empty processes.
20039            numEmptyProcs = cachedProcessLimit;
20040        }
20041        int emptyFactor = numEmptyProcs/numSlots;
20042        if (emptyFactor < 1) emptyFactor = 1;
20043        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20044        if (cachedFactor < 1) cachedFactor = 1;
20045        int stepCached = 0;
20046        int stepEmpty = 0;
20047        int numCached = 0;
20048        int numEmpty = 0;
20049        int numTrimming = 0;
20050
20051        mNumNonCachedProcs = 0;
20052        mNumCachedHiddenProcs = 0;
20053
20054        // First update the OOM adjustment for each of the
20055        // application processes based on their current state.
20056        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20057        int nextCachedAdj = curCachedAdj+1;
20058        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20059        int nextEmptyAdj = curEmptyAdj+2;
20060        for (int i=N-1; i>=0; i--) {
20061            ProcessRecord app = mLruProcesses.get(i);
20062            if (!app.killedByAm && app.thread != null) {
20063                app.procStateChanged = false;
20064                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20065
20066                // If we haven't yet assigned the final cached adj
20067                // to the process, do that now.
20068                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20069                    switch (app.curProcState) {
20070                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20071                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20072                            // This process is a cached process holding activities...
20073                            // assign it the next cached value for that type, and then
20074                            // step that cached level.
20075                            app.curRawAdj = curCachedAdj;
20076                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20077                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20078                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20079                                    + ")");
20080                            if (curCachedAdj != nextCachedAdj) {
20081                                stepCached++;
20082                                if (stepCached >= cachedFactor) {
20083                                    stepCached = 0;
20084                                    curCachedAdj = nextCachedAdj;
20085                                    nextCachedAdj += 2;
20086                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20087                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20088                                    }
20089                                }
20090                            }
20091                            break;
20092                        default:
20093                            // For everything else, assign next empty cached process
20094                            // level and bump that up.  Note that this means that
20095                            // long-running services that have dropped down to the
20096                            // cached level will be treated as empty (since their process
20097                            // state is still as a service), which is what we want.
20098                            app.curRawAdj = curEmptyAdj;
20099                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20100                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20101                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20102                                    + ")");
20103                            if (curEmptyAdj != nextEmptyAdj) {
20104                                stepEmpty++;
20105                                if (stepEmpty >= emptyFactor) {
20106                                    stepEmpty = 0;
20107                                    curEmptyAdj = nextEmptyAdj;
20108                                    nextEmptyAdj += 2;
20109                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20110                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20111                                    }
20112                                }
20113                            }
20114                            break;
20115                    }
20116                }
20117
20118                applyOomAdjLocked(app, true, now, nowElapsed);
20119
20120                // Count the number of process types.
20121                switch (app.curProcState) {
20122                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20123                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20124                        mNumCachedHiddenProcs++;
20125                        numCached++;
20126                        if (numCached > cachedProcessLimit) {
20127                            app.kill("cached #" + numCached, true);
20128                        }
20129                        break;
20130                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20131                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20132                                && app.lastActivityTime < oldTime) {
20133                            app.kill("empty for "
20134                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20135                                    / 1000) + "s", true);
20136                        } else {
20137                            numEmpty++;
20138                            if (numEmpty > emptyProcessLimit) {
20139                                app.kill("empty #" + numEmpty, true);
20140                            }
20141                        }
20142                        break;
20143                    default:
20144                        mNumNonCachedProcs++;
20145                        break;
20146                }
20147
20148                if (app.isolated && app.services.size() <= 0) {
20149                    // If this is an isolated process, and there are no
20150                    // services running in it, then the process is no longer
20151                    // needed.  We agressively kill these because we can by
20152                    // definition not re-use the same process again, and it is
20153                    // good to avoid having whatever code was running in them
20154                    // left sitting around after no longer needed.
20155                    app.kill("isolated not needed", true);
20156                } else {
20157                    // Keeping this process, update its uid.
20158                    final UidRecord uidRec = app.uidRecord;
20159                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20160                        uidRec.curProcState = app.curProcState;
20161                    }
20162                }
20163
20164                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20165                        && !app.killedByAm) {
20166                    numTrimming++;
20167                }
20168            }
20169        }
20170
20171        mNumServiceProcs = mNewNumServiceProcs;
20172
20173        // Now determine the memory trimming level of background processes.
20174        // Unfortunately we need to start at the back of the list to do this
20175        // properly.  We only do this if the number of background apps we
20176        // are managing to keep around is less than half the maximum we desire;
20177        // if we are keeping a good number around, we'll let them use whatever
20178        // memory they want.
20179        final int numCachedAndEmpty = numCached + numEmpty;
20180        int memFactor;
20181        if (numCached <= ProcessList.TRIM_CACHED_APPS
20182                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20183            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20184                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20185            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20186                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20187            } else {
20188                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20189            }
20190        } else {
20191            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20192        }
20193        // We always allow the memory level to go up (better).  We only allow it to go
20194        // down if we are in a state where that is allowed, *and* the total number of processes
20195        // has gone down since last time.
20196        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20197                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20198                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20199        if (memFactor > mLastMemoryLevel) {
20200            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20201                memFactor = mLastMemoryLevel;
20202                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20203            }
20204        }
20205        if (memFactor != mLastMemoryLevel) {
20206            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20207        }
20208        mLastMemoryLevel = memFactor;
20209        mLastNumProcesses = mLruProcesses.size();
20210        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20211        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20212        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20213            if (mLowRamStartTime == 0) {
20214                mLowRamStartTime = now;
20215            }
20216            int step = 0;
20217            int fgTrimLevel;
20218            switch (memFactor) {
20219                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20220                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20221                    break;
20222                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20223                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20224                    break;
20225                default:
20226                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20227                    break;
20228            }
20229            int factor = numTrimming/3;
20230            int minFactor = 2;
20231            if (mHomeProcess != null) minFactor++;
20232            if (mPreviousProcess != null) minFactor++;
20233            if (factor < minFactor) factor = minFactor;
20234            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20235            for (int i=N-1; i>=0; i--) {
20236                ProcessRecord app = mLruProcesses.get(i);
20237                if (allChanged || app.procStateChanged) {
20238                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20239                    app.procStateChanged = false;
20240                }
20241                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20242                        && !app.killedByAm) {
20243                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20244                        try {
20245                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20246                                    "Trimming memory of " + app.processName + " to " + curLevel);
20247                            app.thread.scheduleTrimMemory(curLevel);
20248                        } catch (RemoteException e) {
20249                        }
20250                        if (false) {
20251                            // For now we won't do this; our memory trimming seems
20252                            // to be good enough at this point that destroying
20253                            // activities causes more harm than good.
20254                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20255                                    && app != mHomeProcess && app != mPreviousProcess) {
20256                                // Need to do this on its own message because the stack may not
20257                                // be in a consistent state at this point.
20258                                // For these apps we will also finish their activities
20259                                // to help them free memory.
20260                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20261                            }
20262                        }
20263                    }
20264                    app.trimMemoryLevel = curLevel;
20265                    step++;
20266                    if (step >= factor) {
20267                        step = 0;
20268                        switch (curLevel) {
20269                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20270                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20271                                break;
20272                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20273                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20274                                break;
20275                        }
20276                    }
20277                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20278                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20279                            && app.thread != null) {
20280                        try {
20281                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20282                                    "Trimming memory of heavy-weight " + app.processName
20283                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20284                            app.thread.scheduleTrimMemory(
20285                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20286                        } catch (RemoteException e) {
20287                        }
20288                    }
20289                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20290                } else {
20291                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20292                            || app.systemNoUi) && app.pendingUiClean) {
20293                        // If this application is now in the background and it
20294                        // had done UI, then give it the special trim level to
20295                        // have it free UI resources.
20296                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20297                        if (app.trimMemoryLevel < level && app.thread != null) {
20298                            try {
20299                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20300                                        "Trimming memory of bg-ui " + app.processName
20301                                        + " to " + level);
20302                                app.thread.scheduleTrimMemory(level);
20303                            } catch (RemoteException e) {
20304                            }
20305                        }
20306                        app.pendingUiClean = false;
20307                    }
20308                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20309                        try {
20310                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20311                                    "Trimming memory of fg " + app.processName
20312                                    + " to " + fgTrimLevel);
20313                            app.thread.scheduleTrimMemory(fgTrimLevel);
20314                        } catch (RemoteException e) {
20315                        }
20316                    }
20317                    app.trimMemoryLevel = fgTrimLevel;
20318                }
20319            }
20320        } else {
20321            if (mLowRamStartTime != 0) {
20322                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20323                mLowRamStartTime = 0;
20324            }
20325            for (int i=N-1; i>=0; i--) {
20326                ProcessRecord app = mLruProcesses.get(i);
20327                if (allChanged || app.procStateChanged) {
20328                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20329                    app.procStateChanged = false;
20330                }
20331                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20332                        || app.systemNoUi) && app.pendingUiClean) {
20333                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20334                            && app.thread != null) {
20335                        try {
20336                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20337                                    "Trimming memory of ui hidden " + app.processName
20338                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20339                            app.thread.scheduleTrimMemory(
20340                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20341                        } catch (RemoteException e) {
20342                        }
20343                    }
20344                    app.pendingUiClean = false;
20345                }
20346                app.trimMemoryLevel = 0;
20347            }
20348        }
20349
20350        if (mAlwaysFinishActivities) {
20351            // Need to do this on its own message because the stack may not
20352            // be in a consistent state at this point.
20353            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20354        }
20355
20356        if (allChanged) {
20357            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20358        }
20359
20360        // Update from any uid changes.
20361        for (int i=mActiveUids.size()-1; i>=0; i--) {
20362            final UidRecord uidRec = mActiveUids.valueAt(i);
20363            int uidChange = UidRecord.CHANGE_PROCSTATE;
20364            if (uidRec.setProcState != uidRec.curProcState) {
20365                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20366                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20367                        + " to " + uidRec.curProcState);
20368                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20369                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20370                        uidRec.lastBackgroundTime = nowElapsed;
20371                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20372                            // Note: the background settle time is in elapsed realtime, while
20373                            // the handler time base is uptime.  All this means is that we may
20374                            // stop background uids later than we had intended, but that only
20375                            // happens because the device was sleeping so we are okay anyway.
20376                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20377                        }
20378                    }
20379                } else {
20380                    if (uidRec.idle) {
20381                        uidChange = UidRecord.CHANGE_ACTIVE;
20382                        uidRec.idle = false;
20383                    }
20384                    uidRec.lastBackgroundTime = 0;
20385                }
20386                uidRec.setProcState = uidRec.curProcState;
20387                enqueueUidChangeLocked(uidRec, -1, uidChange);
20388                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20389            }
20390        }
20391
20392        if (mProcessStats.shouldWriteNowLocked(now)) {
20393            mHandler.post(new Runnable() {
20394                @Override public void run() {
20395                    synchronized (ActivityManagerService.this) {
20396                        mProcessStats.writeStateAsyncLocked();
20397                    }
20398                }
20399            });
20400        }
20401
20402        if (DEBUG_OOM_ADJ) {
20403            final long duration = SystemClock.uptimeMillis() - now;
20404            if (false) {
20405                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20406                        new RuntimeException("here").fillInStackTrace());
20407            } else {
20408                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20409            }
20410        }
20411    }
20412
20413    final void idleUids() {
20414        synchronized (this) {
20415            final long nowElapsed = SystemClock.elapsedRealtime();
20416            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20417            long nextTime = 0;
20418            for (int i=mActiveUids.size()-1; i>=0; i--) {
20419                final UidRecord uidRec = mActiveUids.valueAt(i);
20420                final long bgTime = uidRec.lastBackgroundTime;
20421                if (bgTime > 0 && !uidRec.idle) {
20422                    if (bgTime <= maxBgTime) {
20423                        uidRec.idle = true;
20424                        doStopUidLocked(uidRec.uid, uidRec);
20425                    } else {
20426                        if (nextTime == 0 || nextTime > bgTime) {
20427                            nextTime = bgTime;
20428                        }
20429                    }
20430                }
20431            }
20432            if (nextTime > 0) {
20433                mHandler.removeMessages(IDLE_UIDS_MSG);
20434                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20435                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20436            }
20437        }
20438    }
20439
20440    final void runInBackgroundDisabled(int uid) {
20441        synchronized (this) {
20442            UidRecord uidRec = mActiveUids.get(uid);
20443            if (uidRec != null) {
20444                // This uid is actually running...  should it be considered background now?
20445                if (uidRec.idle) {
20446                    doStopUidLocked(uidRec.uid, uidRec);
20447                }
20448            } else {
20449                // This uid isn't actually running...  still send a report about it being "stopped".
20450                doStopUidLocked(uid, null);
20451            }
20452        }
20453    }
20454
20455    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20456        mServices.stopInBackgroundLocked(uid);
20457        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20458    }
20459
20460    final void trimApplications() {
20461        synchronized (this) {
20462            int i;
20463
20464            // First remove any unused application processes whose package
20465            // has been removed.
20466            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20467                final ProcessRecord app = mRemovedProcesses.get(i);
20468                if (app.activities.size() == 0
20469                        && app.curReceiver == null && app.services.size() == 0) {
20470                    Slog.i(
20471                        TAG, "Exiting empty application process "
20472                        + app.processName + " ("
20473                        + (app.thread != null ? app.thread.asBinder() : null)
20474                        + ")\n");
20475                    if (app.pid > 0 && app.pid != MY_PID) {
20476                        app.kill("empty", false);
20477                    } else {
20478                        try {
20479                            app.thread.scheduleExit();
20480                        } catch (Exception e) {
20481                            // Ignore exceptions.
20482                        }
20483                    }
20484                    cleanUpApplicationRecordLocked(app, false, true, -1);
20485                    mRemovedProcesses.remove(i);
20486
20487                    if (app.persistent) {
20488                        addAppLocked(app.info, false, null /* ABI override */);
20489                    }
20490                }
20491            }
20492
20493            // Now update the oom adj for all processes.
20494            updateOomAdjLocked();
20495        }
20496    }
20497
20498    /** This method sends the specified signal to each of the persistent apps */
20499    public void signalPersistentProcesses(int sig) throws RemoteException {
20500        if (sig != Process.SIGNAL_USR1) {
20501            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20502        }
20503
20504        synchronized (this) {
20505            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20506                    != PackageManager.PERMISSION_GRANTED) {
20507                throw new SecurityException("Requires permission "
20508                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20509            }
20510
20511            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20512                ProcessRecord r = mLruProcesses.get(i);
20513                if (r.thread != null && r.persistent) {
20514                    Process.sendSignal(r.pid, sig);
20515                }
20516            }
20517        }
20518    }
20519
20520    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20521        if (proc == null || proc == mProfileProc) {
20522            proc = mProfileProc;
20523            profileType = mProfileType;
20524            clearProfilerLocked();
20525        }
20526        if (proc == null) {
20527            return;
20528        }
20529        try {
20530            proc.thread.profilerControl(false, null, profileType);
20531        } catch (RemoteException e) {
20532            throw new IllegalStateException("Process disappeared");
20533        }
20534    }
20535
20536    private void clearProfilerLocked() {
20537        if (mProfileFd != null) {
20538            try {
20539                mProfileFd.close();
20540            } catch (IOException e) {
20541            }
20542        }
20543        mProfileApp = null;
20544        mProfileProc = null;
20545        mProfileFile = null;
20546        mProfileType = 0;
20547        mAutoStopProfiler = false;
20548        mSamplingInterval = 0;
20549    }
20550
20551    public boolean profileControl(String process, int userId, boolean start,
20552            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20553
20554        try {
20555            synchronized (this) {
20556                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20557                // its own permission.
20558                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20559                        != PackageManager.PERMISSION_GRANTED) {
20560                    throw new SecurityException("Requires permission "
20561                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20562                }
20563
20564                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20565                    throw new IllegalArgumentException("null profile info or fd");
20566                }
20567
20568                ProcessRecord proc = null;
20569                if (process != null) {
20570                    proc = findProcessLocked(process, userId, "profileControl");
20571                }
20572
20573                if (start && (proc == null || proc.thread == null)) {
20574                    throw new IllegalArgumentException("Unknown process: " + process);
20575                }
20576
20577                if (start) {
20578                    stopProfilerLocked(null, 0);
20579                    setProfileApp(proc.info, proc.processName, profilerInfo);
20580                    mProfileProc = proc;
20581                    mProfileType = profileType;
20582                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20583                    try {
20584                        fd = fd.dup();
20585                    } catch (IOException e) {
20586                        fd = null;
20587                    }
20588                    profilerInfo.profileFd = fd;
20589                    proc.thread.profilerControl(start, profilerInfo, profileType);
20590                    fd = null;
20591                    mProfileFd = null;
20592                } else {
20593                    stopProfilerLocked(proc, profileType);
20594                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20595                        try {
20596                            profilerInfo.profileFd.close();
20597                        } catch (IOException e) {
20598                        }
20599                    }
20600                }
20601
20602                return true;
20603            }
20604        } catch (RemoteException e) {
20605            throw new IllegalStateException("Process disappeared");
20606        } finally {
20607            if (profilerInfo != null && profilerInfo.profileFd != null) {
20608                try {
20609                    profilerInfo.profileFd.close();
20610                } catch (IOException e) {
20611                }
20612            }
20613        }
20614    }
20615
20616    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20617        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20618                userId, true, ALLOW_FULL_ONLY, callName, null);
20619        ProcessRecord proc = null;
20620        try {
20621            int pid = Integer.parseInt(process);
20622            synchronized (mPidsSelfLocked) {
20623                proc = mPidsSelfLocked.get(pid);
20624            }
20625        } catch (NumberFormatException e) {
20626        }
20627
20628        if (proc == null) {
20629            ArrayMap<String, SparseArray<ProcessRecord>> all
20630                    = mProcessNames.getMap();
20631            SparseArray<ProcessRecord> procs = all.get(process);
20632            if (procs != null && procs.size() > 0) {
20633                proc = procs.valueAt(0);
20634                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20635                    for (int i=1; i<procs.size(); i++) {
20636                        ProcessRecord thisProc = procs.valueAt(i);
20637                        if (thisProc.userId == userId) {
20638                            proc = thisProc;
20639                            break;
20640                        }
20641                    }
20642                }
20643            }
20644        }
20645
20646        return proc;
20647    }
20648
20649    public boolean dumpHeap(String process, int userId, boolean managed,
20650            String path, ParcelFileDescriptor fd) throws RemoteException {
20651
20652        try {
20653            synchronized (this) {
20654                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20655                // its own permission (same as profileControl).
20656                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20657                        != PackageManager.PERMISSION_GRANTED) {
20658                    throw new SecurityException("Requires permission "
20659                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20660                }
20661
20662                if (fd == null) {
20663                    throw new IllegalArgumentException("null fd");
20664                }
20665
20666                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20667                if (proc == null || proc.thread == null) {
20668                    throw new IllegalArgumentException("Unknown process: " + process);
20669                }
20670
20671                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20672                if (!isDebuggable) {
20673                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20674                        throw new SecurityException("Process not debuggable: " + proc);
20675                    }
20676                }
20677
20678                proc.thread.dumpHeap(managed, path, fd);
20679                fd = null;
20680                return true;
20681            }
20682        } catch (RemoteException e) {
20683            throw new IllegalStateException("Process disappeared");
20684        } finally {
20685            if (fd != null) {
20686                try {
20687                    fd.close();
20688                } catch (IOException e) {
20689                }
20690            }
20691        }
20692    }
20693
20694    @Override
20695    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20696            String reportPackage) {
20697        if (processName != null) {
20698            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20699                    "setDumpHeapDebugLimit()");
20700        } else {
20701            synchronized (mPidsSelfLocked) {
20702                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20703                if (proc == null) {
20704                    throw new SecurityException("No process found for calling pid "
20705                            + Binder.getCallingPid());
20706                }
20707                if (!Build.IS_DEBUGGABLE
20708                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20709                    throw new SecurityException("Not running a debuggable build");
20710                }
20711                processName = proc.processName;
20712                uid = proc.uid;
20713                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20714                    throw new SecurityException("Package " + reportPackage + " is not running in "
20715                            + proc);
20716                }
20717            }
20718        }
20719        synchronized (this) {
20720            if (maxMemSize > 0) {
20721                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20722            } else {
20723                if (uid != 0) {
20724                    mMemWatchProcesses.remove(processName, uid);
20725                } else {
20726                    mMemWatchProcesses.getMap().remove(processName);
20727                }
20728            }
20729        }
20730    }
20731
20732    @Override
20733    public void dumpHeapFinished(String path) {
20734        synchronized (this) {
20735            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20736                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20737                        + " does not match last pid " + mMemWatchDumpPid);
20738                return;
20739            }
20740            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20741                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20742                        + " does not match last path " + mMemWatchDumpFile);
20743                return;
20744            }
20745            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20746            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20747        }
20748    }
20749
20750    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20751    public void monitor() {
20752        synchronized (this) { }
20753    }
20754
20755    void onCoreSettingsChange(Bundle settings) {
20756        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20757            ProcessRecord processRecord = mLruProcesses.get(i);
20758            try {
20759                if (processRecord.thread != null) {
20760                    processRecord.thread.setCoreSettings(settings);
20761                }
20762            } catch (RemoteException re) {
20763                /* ignore */
20764            }
20765        }
20766    }
20767
20768    // Multi-user methods
20769
20770    /**
20771     * Start user, if its not already running, but don't bring it to foreground.
20772     */
20773    @Override
20774    public boolean startUserInBackground(final int userId) {
20775        return mUserController.startUser(userId, /* foreground */ false);
20776    }
20777
20778    @Override
20779    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20780        return mUserController.unlockUser(userId, token, secret, listener);
20781    }
20782
20783    @Override
20784    public boolean switchUser(final int targetUserId) {
20785        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20786        UserInfo currentUserInfo;
20787        UserInfo targetUserInfo;
20788        synchronized (this) {
20789            int currentUserId = mUserController.getCurrentUserIdLocked();
20790            currentUserInfo = mUserController.getUserInfo(currentUserId);
20791            targetUserInfo = mUserController.getUserInfo(targetUserId);
20792            if (targetUserInfo == null) {
20793                Slog.w(TAG, "No user info for user #" + targetUserId);
20794                return false;
20795            }
20796            if (!targetUserInfo.supportsSwitchTo()) {
20797                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20798                return false;
20799            }
20800            if (targetUserInfo.isManagedProfile()) {
20801                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20802                return false;
20803            }
20804            mUserController.setTargetUserIdLocked(targetUserId);
20805        }
20806        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20807        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20808        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20809        return true;
20810    }
20811
20812    void scheduleStartProfilesLocked() {
20813        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20814            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20815                    DateUtils.SECOND_IN_MILLIS);
20816        }
20817    }
20818
20819    @Override
20820    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20821        return mUserController.stopUser(userId, force, callback);
20822    }
20823
20824    @Override
20825    public UserInfo getCurrentUser() {
20826        return mUserController.getCurrentUser();
20827    }
20828
20829    @Override
20830    public boolean isUserRunning(int userId, int flags) {
20831        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20832                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20833            String msg = "Permission Denial: isUserRunning() from pid="
20834                    + Binder.getCallingPid()
20835                    + ", uid=" + Binder.getCallingUid()
20836                    + " requires " + INTERACT_ACROSS_USERS;
20837            Slog.w(TAG, msg);
20838            throw new SecurityException(msg);
20839        }
20840        synchronized (this) {
20841            return mUserController.isUserRunningLocked(userId, flags);
20842        }
20843    }
20844
20845    @Override
20846    public int[] getRunningUserIds() {
20847        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20848                != PackageManager.PERMISSION_GRANTED) {
20849            String msg = "Permission Denial: isUserRunning() from pid="
20850                    + Binder.getCallingPid()
20851                    + ", uid=" + Binder.getCallingUid()
20852                    + " requires " + INTERACT_ACROSS_USERS;
20853            Slog.w(TAG, msg);
20854            throw new SecurityException(msg);
20855        }
20856        synchronized (this) {
20857            return mUserController.getStartedUserArrayLocked();
20858        }
20859    }
20860
20861    @Override
20862    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20863        mUserController.registerUserSwitchObserver(observer);
20864    }
20865
20866    @Override
20867    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20868        mUserController.unregisterUserSwitchObserver(observer);
20869    }
20870
20871    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20872        if (info == null) return null;
20873        ApplicationInfo newInfo = new ApplicationInfo(info);
20874        newInfo.initForUser(userId);
20875        return newInfo;
20876    }
20877
20878    public boolean isUserStopped(int userId) {
20879        synchronized (this) {
20880            return mUserController.getStartedUserStateLocked(userId) == null;
20881        }
20882    }
20883
20884    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20885        if (aInfo == null
20886                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20887            return aInfo;
20888        }
20889
20890        ActivityInfo info = new ActivityInfo(aInfo);
20891        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20892        return info;
20893    }
20894
20895    private boolean processSanityChecksLocked(ProcessRecord process) {
20896        if (process == null || process.thread == null) {
20897            return false;
20898        }
20899
20900        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20901        if (!isDebuggable) {
20902            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20903                return false;
20904            }
20905        }
20906
20907        return true;
20908    }
20909
20910    public boolean startBinderTracking() throws RemoteException {
20911        synchronized (this) {
20912            mBinderTransactionTrackingEnabled = true;
20913            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20914            // permission (same as profileControl).
20915            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20916                    != PackageManager.PERMISSION_GRANTED) {
20917                throw new SecurityException("Requires permission "
20918                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20919            }
20920
20921            for (int i = 0; i < mLruProcesses.size(); i++) {
20922                ProcessRecord process = mLruProcesses.get(i);
20923                if (!processSanityChecksLocked(process)) {
20924                    continue;
20925                }
20926                try {
20927                    process.thread.startBinderTracking();
20928                } catch (RemoteException e) {
20929                    Log.v(TAG, "Process disappared");
20930                }
20931            }
20932            return true;
20933        }
20934    }
20935
20936    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20937        try {
20938            synchronized (this) {
20939                mBinderTransactionTrackingEnabled = false;
20940                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20941                // permission (same as profileControl).
20942                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20943                        != PackageManager.PERMISSION_GRANTED) {
20944                    throw new SecurityException("Requires permission "
20945                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20946                }
20947
20948                if (fd == null) {
20949                    throw new IllegalArgumentException("null fd");
20950                }
20951
20952                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20953                pw.println("Binder transaction traces for all processes.\n");
20954                for (ProcessRecord process : mLruProcesses) {
20955                    if (!processSanityChecksLocked(process)) {
20956                        continue;
20957                    }
20958
20959                    pw.println("Traces for process: " + process.processName);
20960                    pw.flush();
20961                    try {
20962                        TransferPipe tp = new TransferPipe();
20963                        try {
20964                            process.thread.stopBinderTrackingAndDump(
20965                                    tp.getWriteFd().getFileDescriptor());
20966                            tp.go(fd.getFileDescriptor());
20967                        } finally {
20968                            tp.kill();
20969                        }
20970                    } catch (IOException e) {
20971                        pw.println("Failure while dumping IPC traces from " + process +
20972                                ".  Exception: " + e);
20973                        pw.flush();
20974                    } catch (RemoteException e) {
20975                        pw.println("Got a RemoteException while dumping IPC traces from " +
20976                                process + ".  Exception: " + e);
20977                        pw.flush();
20978                    }
20979                }
20980                fd = null;
20981                return true;
20982            }
20983        } finally {
20984            if (fd != null) {
20985                try {
20986                    fd.close();
20987                } catch (IOException e) {
20988                }
20989            }
20990        }
20991    }
20992
20993    private final class LocalService extends ActivityManagerInternal {
20994        @Override
20995        public void onWakefulnessChanged(int wakefulness) {
20996            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20997        }
20998
20999        @Override
21000        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21001                String processName, String abiOverride, int uid, Runnable crashHandler) {
21002            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21003                    processName, abiOverride, uid, crashHandler);
21004        }
21005
21006        @Override
21007        public SleepToken acquireSleepToken(String tag) {
21008            Preconditions.checkNotNull(tag);
21009
21010            synchronized (ActivityManagerService.this) {
21011                SleepTokenImpl token = new SleepTokenImpl(tag);
21012                mSleepTokens.add(token);
21013                updateSleepIfNeededLocked();
21014                applyVrModeIfNeededLocked(mFocusedActivity, false);
21015                return token;
21016            }
21017        }
21018
21019        @Override
21020        public ComponentName getHomeActivityForUser(int userId) {
21021            synchronized (ActivityManagerService.this) {
21022                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21023                return homeActivity == null ? null : homeActivity.realActivity;
21024            }
21025        }
21026
21027        @Override
21028        public void onUserRemoved(int userId) {
21029            synchronized (ActivityManagerService.this) {
21030                ActivityManagerService.this.onUserStoppedLocked(userId);
21031            }
21032        }
21033
21034        @Override
21035        public void onLocalVoiceInteractionStarted(IBinder activity,
21036                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21037            synchronized (ActivityManagerService.this) {
21038                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21039                        voiceSession, voiceInteractor);
21040            }
21041        }
21042
21043        @Override
21044        public void notifyStartingWindowDrawn() {
21045            synchronized (ActivityManagerService.this) {
21046                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21047            }
21048        }
21049
21050        @Override
21051        public void notifyAppTransitionStarting(int reason) {
21052            synchronized (ActivityManagerService.this) {
21053                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21054            }
21055        }
21056
21057        @Override
21058        public void notifyAppTransitionFinished() {
21059            synchronized (ActivityManagerService.this) {
21060                mStackSupervisor.notifyAppTransitionDone();
21061            }
21062        }
21063
21064        @Override
21065        public void notifyAppTransitionCancelled() {
21066            synchronized (ActivityManagerService.this) {
21067                mStackSupervisor.notifyAppTransitionDone();
21068            }
21069        }
21070
21071        @Override
21072        public List<IBinder> getTopVisibleActivities() {
21073            synchronized (ActivityManagerService.this) {
21074                return mStackSupervisor.getTopVisibleActivities();
21075            }
21076        }
21077
21078        @Override
21079        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21080            synchronized (ActivityManagerService.this) {
21081                mStackSupervisor.setDockedStackMinimized(minimized);
21082            }
21083        }
21084
21085        @Override
21086        public void killForegroundAppsForUser(int userHandle) {
21087            synchronized (ActivityManagerService.this) {
21088                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21089                final int NP = mProcessNames.getMap().size();
21090                for (int ip = 0; ip < NP; ip++) {
21091                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21092                    final int NA = apps.size();
21093                    for (int ia = 0; ia < NA; ia++) {
21094                        final ProcessRecord app = apps.valueAt(ia);
21095                        if (app.persistent) {
21096                            // We don't kill persistent processes.
21097                            continue;
21098                        }
21099                        if (app.removed) {
21100                            procs.add(app);
21101                        } else if (app.userId == userHandle && app.foregroundActivities) {
21102                            app.removed = true;
21103                            procs.add(app);
21104                        }
21105                    }
21106                }
21107
21108                final int N = procs.size();
21109                for (int i = 0; i < N; i++) {
21110                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21111                }
21112            }
21113        }
21114    }
21115
21116    private final class SleepTokenImpl extends SleepToken {
21117        private final String mTag;
21118        private final long mAcquireTime;
21119
21120        public SleepTokenImpl(String tag) {
21121            mTag = tag;
21122            mAcquireTime = SystemClock.uptimeMillis();
21123        }
21124
21125        @Override
21126        public void release() {
21127            synchronized (ActivityManagerService.this) {
21128                if (mSleepTokens.remove(this)) {
21129                    updateSleepIfNeededLocked();
21130                }
21131            }
21132        }
21133
21134        @Override
21135        public String toString() {
21136            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21137        }
21138    }
21139
21140    /**
21141     * An implementation of IAppTask, that allows an app to manage its own tasks via
21142     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21143     * only the process that calls getAppTasks() can call the AppTask methods.
21144     */
21145    class AppTaskImpl extends IAppTask.Stub {
21146        private int mTaskId;
21147        private int mCallingUid;
21148
21149        public AppTaskImpl(int taskId, int callingUid) {
21150            mTaskId = taskId;
21151            mCallingUid = callingUid;
21152        }
21153
21154        private void checkCaller() {
21155            if (mCallingUid != Binder.getCallingUid()) {
21156                throw new SecurityException("Caller " + mCallingUid
21157                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21158            }
21159        }
21160
21161        @Override
21162        public void finishAndRemoveTask() {
21163            checkCaller();
21164
21165            synchronized (ActivityManagerService.this) {
21166                long origId = Binder.clearCallingIdentity();
21167                try {
21168                    // We remove the task from recents to preserve backwards
21169                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21170                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21171                    }
21172                } finally {
21173                    Binder.restoreCallingIdentity(origId);
21174                }
21175            }
21176        }
21177
21178        @Override
21179        public ActivityManager.RecentTaskInfo getTaskInfo() {
21180            checkCaller();
21181
21182            synchronized (ActivityManagerService.this) {
21183                long origId = Binder.clearCallingIdentity();
21184                try {
21185                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21186                    if (tr == null) {
21187                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21188                    }
21189                    return createRecentTaskInfoFromTaskRecord(tr);
21190                } finally {
21191                    Binder.restoreCallingIdentity(origId);
21192                }
21193            }
21194        }
21195
21196        @Override
21197        public void moveToFront() {
21198            checkCaller();
21199            // Will bring task to front if it already has a root activity.
21200            final long origId = Binder.clearCallingIdentity();
21201            try {
21202                synchronized (this) {
21203                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21204                }
21205            } finally {
21206                Binder.restoreCallingIdentity(origId);
21207            }
21208        }
21209
21210        @Override
21211        public int startActivity(IBinder whoThread, String callingPackage,
21212                Intent intent, String resolvedType, Bundle bOptions) {
21213            checkCaller();
21214
21215            int callingUser = UserHandle.getCallingUserId();
21216            TaskRecord tr;
21217            IApplicationThread appThread;
21218            synchronized (ActivityManagerService.this) {
21219                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21220                if (tr == null) {
21221                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21222                }
21223                appThread = ApplicationThreadNative.asInterface(whoThread);
21224                if (appThread == null) {
21225                    throw new IllegalArgumentException("Bad app thread " + appThread);
21226                }
21227            }
21228            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21229                    resolvedType, null, null, null, null, 0, 0, null, null,
21230                    null, bOptions, false, callingUser, null, tr);
21231        }
21232
21233        @Override
21234        public void setExcludeFromRecents(boolean exclude) {
21235            checkCaller();
21236
21237            synchronized (ActivityManagerService.this) {
21238                long origId = Binder.clearCallingIdentity();
21239                try {
21240                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21241                    if (tr == null) {
21242                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21243                    }
21244                    Intent intent = tr.getBaseIntent();
21245                    if (exclude) {
21246                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21247                    } else {
21248                        intent.setFlags(intent.getFlags()
21249                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21250                    }
21251                } finally {
21252                    Binder.restoreCallingIdentity(origId);
21253                }
21254            }
21255        }
21256    }
21257
21258    /**
21259     * Kill processes for the user with id userId and that depend on the package named packageName
21260     */
21261    @Override
21262    public void killPackageDependents(String packageName, int userId) {
21263        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21264        if (packageName == null) {
21265            throw new NullPointerException(
21266                    "Cannot kill the dependents of a package without its name.");
21267        }
21268
21269        long callingId = Binder.clearCallingIdentity();
21270        IPackageManager pm = AppGlobals.getPackageManager();
21271        int pkgUid = -1;
21272        try {
21273            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21274        } catch (RemoteException e) {
21275        }
21276        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21277            throw new IllegalArgumentException(
21278                    "Cannot kill dependents of non-existing package " + packageName);
21279        }
21280        try {
21281            synchronized(this) {
21282                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21283                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21284                        "dep: " + packageName);
21285            }
21286        } finally {
21287            Binder.restoreCallingIdentity(callingId);
21288        }
21289    }
21290}
21291