ActivityManagerService.java revision 9e2e1d56f468c108ac9bf5f94bfdb439ad76c35b
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.google.android.collect.Lists;
20import com.google.android.collect.Maps;
21import com.android.internal.R;
22import com.android.internal.annotations.GuardedBy;
23import com.android.internal.app.AssistUtils;
24import com.android.internal.app.DumpHeapActivity;
25import com.android.internal.app.IAppOpsCallback;
26import com.android.internal.app.IAppOpsService;
27import com.android.internal.app.IVoiceInteractor;
28import com.android.internal.app.ProcessMap;
29import com.android.internal.app.SystemUserHomeActivity;
30import com.android.internal.app.procstats.ProcessStats;
31import com.android.internal.os.BackgroundThread;
32import com.android.internal.os.BatteryStatsImpl;
33import com.android.internal.os.IResultReceiver;
34import com.android.internal.os.ProcessCpuTracker;
35import com.android.internal.os.TransferPipe;
36import com.android.internal.os.Zygote;
37import com.android.internal.os.InstallerConnection.InstallerException;
38import com.android.internal.util.ArrayUtils;
39import com.android.internal.util.FastPrintWriter;
40import com.android.internal.util.FastXmlSerializer;
41import com.android.internal.util.MemInfoReader;
42import com.android.internal.util.Preconditions;
43import com.android.internal.util.ProgressReporter;
44import com.android.server.AppOpsService;
45import com.android.server.AttributeCache;
46import com.android.server.DeviceIdleController;
47import com.android.server.IntentResolver;
48import com.android.server.LocalServices;
49import com.android.server.LockGuard;
50import com.android.server.ServiceThread;
51import com.android.server.SystemService;
52import com.android.server.SystemServiceManager;
53import com.android.server.Watchdog;
54import com.android.server.am.ActivityStack.ActivityState;
55import com.android.server.firewall.IntentFirewall;
56import com.android.server.pm.Installer;
57import com.android.server.statusbar.StatusBarManagerInternal;
58import com.android.server.vr.VrManagerInternal;
59import com.android.server.wm.WindowManagerService;
60
61import org.xmlpull.v1.XmlPullParser;
62import org.xmlpull.v1.XmlPullParserException;
63import org.xmlpull.v1.XmlSerializer;
64
65import android.Manifest;
66import android.annotation.UserIdInt;
67import android.app.Activity;
68import android.app.ActivityManager;
69import android.app.ActivityManager.RunningTaskInfo;
70import android.app.ActivityManager.StackId;
71import android.app.ActivityManager.StackInfo;
72import android.app.ActivityManager.TaskThumbnailInfo;
73import android.app.ActivityManagerInternal;
74import android.app.ActivityManagerInternal.SleepToken;
75import android.app.ActivityManagerNative;
76import android.app.ActivityOptions;
77import android.app.ActivityThread;
78import android.app.AlertDialog;
79import android.app.AppGlobals;
80import android.app.AppOpsManager;
81import android.app.ApplicationErrorReport;
82import android.app.ApplicationThreadNative;
83import android.app.BroadcastOptions;
84import android.app.Dialog;
85import android.app.IActivityContainer;
86import android.app.IActivityContainerCallback;
87import android.app.IActivityController;
88import android.app.IAppTask;
89import android.app.IApplicationThread;
90import android.app.IInstrumentationWatcher;
91import android.app.INotificationManager;
92import android.app.IProcessObserver;
93import android.app.IServiceConnection;
94import android.app.IStopUserCallback;
95import android.app.ITaskStackListener;
96import android.app.IUiAutomationConnection;
97import android.app.IUidObserver;
98import android.app.IUserSwitchObserver;
99import android.app.Instrumentation;
100import android.app.KeyguardManager;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.ProfilerInfo;
105import android.app.admin.DevicePolicyManager;
106import android.app.admin.DevicePolicyManagerInternal;
107import android.app.assist.AssistContent;
108import android.app.assist.AssistStructure;
109import android.app.backup.IBackupManager;
110import android.app.usage.UsageEvents;
111import android.app.usage.UsageStatsManagerInternal;
112import android.appwidget.AppWidgetManager;
113import android.content.ActivityNotFoundException;
114import android.content.BroadcastReceiver;
115import android.content.ClipData;
116import android.content.ComponentCallbacks2;
117import android.content.ComponentName;
118import android.content.ContentProvider;
119import android.content.ContentResolver;
120import android.content.Context;
121import android.content.DialogInterface;
122import android.content.IContentProvider;
123import android.content.IIntentReceiver;
124import android.content.IIntentSender;
125import android.content.Intent;
126import android.content.IntentFilter;
127import android.content.IntentSender;
128import android.content.pm.ActivityInfo;
129import android.content.pm.ApplicationInfo;
130import android.content.pm.ConfigurationInfo;
131import android.content.pm.IPackageDataObserver;
132import android.content.pm.IPackageManager;
133import android.content.pm.InstrumentationInfo;
134import android.content.pm.PackageInfo;
135import android.content.pm.PackageManager;
136import android.content.pm.PackageManager.NameNotFoundException;
137import android.content.pm.PackageManagerInternal;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.PathPermission;
140import android.content.pm.PermissionInfo;
141import android.content.pm.ProviderInfo;
142import android.content.pm.ResolveInfo;
143import android.content.pm.ServiceInfo;
144import android.content.pm.ShortcutServiceInternal;
145import android.content.pm.UserInfo;
146import android.content.res.CompatibilityInfo;
147import android.content.res.Configuration;
148import android.content.res.Resources;
149import android.database.ContentObserver;
150import android.graphics.Bitmap;
151import android.graphics.Point;
152import android.graphics.Rect;
153import android.location.LocationManager;
154import android.net.Proxy;
155import android.net.ProxyInfo;
156import android.net.Uri;
157import android.os.BatteryStats;
158import android.os.Binder;
159import android.os.Build;
160import android.os.Bundle;
161import android.os.Debug;
162import android.os.DropBoxManager;
163import android.os.Environment;
164import android.os.FactoryTest;
165import android.os.FileObserver;
166import android.os.FileUtils;
167import android.os.Handler;
168import android.os.IBinder;
169import android.os.IPermissionController;
170import android.os.IProcessInfoService;
171import android.os.IProgressListener;
172import android.os.Looper;
173import android.os.Message;
174import android.os.Parcel;
175import android.os.ParcelFileDescriptor;
176import android.os.PersistableBundle;
177import android.os.PowerManager;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.ResultReceiver;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.Trace;
188import android.os.TransactionTooLargeException;
189import android.os.UpdateLock;
190import android.os.UserHandle;
191import android.os.UserManager;
192import android.os.WorkSource;
193import android.os.storage.IMountService;
194import android.os.storage.MountServiceInternal;
195import android.os.storage.StorageManager;
196import android.provider.Settings;
197import android.service.voice.IVoiceInteractionSession;
198import android.service.voice.VoiceInteractionManagerInternal;
199import android.service.voice.VoiceInteractionSession;
200import android.text.format.DateUtils;
201import android.text.format.Time;
202import android.util.ArrayMap;
203import android.util.ArraySet;
204import android.util.AtomicFile;
205import android.util.DebugUtils;
206import android.util.EventLog;
207import android.util.LocaleList;
208import android.util.Log;
209import android.util.Pair;
210import android.util.PrintWriterPrinter;
211import android.util.Slog;
212import android.util.SparseArray;
213import android.util.TimeUtils;
214import android.util.Xml;
215import android.view.Display;
216import android.view.Gravity;
217import android.view.LayoutInflater;
218import android.view.View;
219import android.view.WindowManager;
220
221import java.io.File;
222import java.io.FileDescriptor;
223import java.io.FileInputStream;
224import java.io.FileNotFoundException;
225import java.io.FileOutputStream;
226import java.io.IOException;
227import java.io.InputStreamReader;
228import java.io.PrintWriter;
229import java.io.StringWriter;
230import java.lang.ref.WeakReference;
231import java.nio.charset.StandardCharsets;
232import java.util.ArrayList;
233import java.util.Arrays;
234import java.util.Collections;
235import java.util.Comparator;
236import java.util.HashMap;
237import java.util.HashSet;
238import java.util.Iterator;
239import java.util.List;
240import java.util.Locale;
241import java.util.Map;
242import java.util.Set;
243import java.util.concurrent.atomic.AtomicBoolean;
244import java.util.concurrent.atomic.AtomicLong;
245
246import dalvik.system.VMRuntime;
247
248import libcore.io.IoUtils;
249import libcore.util.EmptyArray;
250
251import static android.Manifest.permission.INTERACT_ACROSS_USERS;
252import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
253import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
254import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
255import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
256import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
257import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
258import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
259import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
260import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.HOME_STACK_ID;
262import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
263import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
264import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
265import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
266import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
267import static android.content.pm.PackageManager.GET_PROVIDERS;
268import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
269import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
270import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
271import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
272import static android.content.pm.PackageManager.PERMISSION_GRANTED;
273import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
274import static android.provider.Settings.Global.DEBUG_APP;
275import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
276import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
277import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
278import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
279import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
280import static android.provider.Settings.System.FONT_SCALE;
281import static com.android.internal.util.XmlUtils.readBooleanAttribute;
282import static com.android.internal.util.XmlUtils.readIntAttribute;
283import static com.android.internal.util.XmlUtils.readLongAttribute;
284import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
285import static com.android.internal.util.XmlUtils.writeIntAttribute;
286import static com.android.internal.util.XmlUtils.writeLongAttribute;
287import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
319import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
343import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
344import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
345import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
346import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
347import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
348import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
349import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
350import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
351import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
352import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
353import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
354import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
355import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
356import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
357import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
358import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
359import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
360import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
361import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
362import static org.xmlpull.v1.XmlPullParser.START_TAG;
363
364public final class ActivityManagerService extends ActivityManagerNative
365        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
366
367    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
368    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
369    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
370    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
371    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
372    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
373    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
374    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
375    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
376    private static final String TAG_LRU = TAG + POSTFIX_LRU;
377    private static final String TAG_MU = TAG + POSTFIX_MU;
378    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
379    private static final String TAG_POWER = TAG + POSTFIX_POWER;
380    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
381    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
382    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
383    private static final String TAG_PSS = TAG + POSTFIX_PSS;
384    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
385    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
386    private static final String TAG_STACK = TAG + POSTFIX_STACK;
387    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
388    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
389    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
390    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
391    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
392
393    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
394    // here so that while the job scheduler can depend on AMS, the other way around
395    // need not be the case.
396    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
397
398    /** Control over CPU and battery monitoring */
399    // write battery stats every 30 minutes.
400    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
401    static final boolean MONITOR_CPU_USAGE = true;
402    // don't sample cpu less than every 5 seconds.
403    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
404    // wait possibly forever for next cpu sample.
405    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
406    static final boolean MONITOR_THREAD_CPU_USAGE = false;
407
408    // The flags that are set for all calls we make to the package manager.
409    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
410
411    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
412
413    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
414
415    // Amount of time after a call to stopAppSwitches() during which we will
416    // prevent further untrusted switches from happening.
417    static final long APP_SWITCH_DELAY_TIME = 5*1000;
418
419    // How long we wait for a launched process to attach to the activity manager
420    // before we decide it's never going to come up for real.
421    static final int PROC_START_TIMEOUT = 10*1000;
422    // How long we wait for an attached process to publish its content providers
423    // before we decide it must be hung.
424    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
425
426    // How long we will retain processes hosting content providers in the "last activity"
427    // state before allowing them to drop down to the regular cached LRU list.  This is
428    // to avoid thrashing of provider processes under low memory situations.
429    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
430
431    // How long we wait for a launched process to attach to the activity manager
432    // before we decide it's never going to come up for real, when the process was
433    // started with a wrapper for instrumentation (such as Valgrind) because it
434    // could take much longer than usual.
435    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
436
437    // How long to wait after going idle before forcing apps to GC.
438    static final int GC_TIMEOUT = 5*1000;
439
440    // The minimum amount of time between successive GC requests for a process.
441    static final int GC_MIN_INTERVAL = 60*1000;
442
443    // The minimum amount of time between successive PSS requests for a process.
444    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
445
446    // The minimum amount of time between successive PSS requests for a process
447    // when the request is due to the memory state being lowered.
448    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
449
450    // The rate at which we check for apps using excessive power -- 15 mins.
451    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
452
453    // The minimum sample duration we will allow before deciding we have
454    // enough data on wake locks to start killing things.
455    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
456
457    // The minimum sample duration we will allow before deciding we have
458    // enough data on CPU usage to start killing things.
459    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
460
461    // How long we allow a receiver to run before giving up on it.
462    static final int BROADCAST_FG_TIMEOUT = 10*1000;
463    static final int BROADCAST_BG_TIMEOUT = 60*1000;
464
465    // How long we wait until we timeout on key dispatching.
466    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
467
468    // How long we wait until we timeout on key dispatching during instrumentation.
469    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
470
471    // This is the amount of time an app needs to be running a foreground service before
472    // we will consider it to be doing interaction for usage stats.
473    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
474
475    // Maximum amount of time we will allow to elapse before re-reporting usage stats
476    // interaction with foreground processes.
477    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
478
479    // This is the amount of time we allow an app to settle after it goes into the background,
480    // before we start restricting what it can do.
481    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
482
483    // How long to wait in getAssistContextExtras for the activity and foreground services
484    // to respond with the result.
485    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
486
487    // How long top wait when going through the modern assist (which doesn't need to block
488    // on getting this result before starting to launch its UI).
489    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
490
491    // Maximum number of persisted Uri grants a package is allowed
492    static final int MAX_PERSISTED_URI_GRANTS = 128;
493
494    static final int MY_PID = Process.myPid();
495
496    static final String[] EMPTY_STRING_ARRAY = new String[0];
497
498    // How many bytes to write into the dropbox log before truncating
499    static final int DROPBOX_MAX_SIZE = 256 * 1024;
500
501    // Access modes for handleIncomingUser.
502    static final int ALLOW_NON_FULL = 0;
503    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
504    static final int ALLOW_FULL_ONLY = 2;
505
506    // Delay in notifying task stack change listeners (in millis)
507    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
508
509    // Necessary ApplicationInfo flags to mark an app as persistent
510    private static final int PERSISTENT_MASK =
511            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
512
513    // Intent sent when remote bugreport collection has been completed
514    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
515            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
516
517    // Delay to disable app launch boost
518    static final int APP_BOOST_MESSAGE_DELAY = 3000;
519    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
520    static final int APP_BOOST_TIMEOUT = 2500;
521
522    // Used to indicate that a task is removed it should also be removed from recents.
523    private static final boolean REMOVE_FROM_RECENTS = true;
524    // Used to indicate that an app transition should be animated.
525    static final boolean ANIMATE = true;
526
527    // Determines whether to take full screen screenshots
528    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
529    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
530
531    private static native int nativeMigrateToBoost();
532    private static native int nativeMigrateFromBoost();
533    private boolean mIsBoosted = false;
534    private long mBoostStartTime = 0;
535
536    /** All system services */
537    SystemServiceManager mSystemServiceManager;
538
539    private Installer mInstaller;
540
541    /** Run all ActivityStacks through this */
542    final ActivityStackSupervisor mStackSupervisor;
543
544    final ActivityStarter mActivityStarter;
545
546    /** Task stack change listeners. */
547    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
548            new RemoteCallbackList<ITaskStackListener>();
549
550    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
551
552    public IntentFirewall mIntentFirewall;
553
554    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
555    // default actuion automatically.  Important for devices without direct input
556    // devices.
557    private boolean mShowDialogs = true;
558    private boolean mInVrMode = false;
559
560    BroadcastQueue mFgBroadcastQueue;
561    BroadcastQueue mBgBroadcastQueue;
562    // Convenient for easy iteration over the queues. Foreground is first
563    // so that dispatch of foreground broadcasts gets precedence.
564    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
565
566    BroadcastQueue broadcastQueueForIntent(Intent intent) {
567        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
568        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
569                "Broadcast intent " + intent + " on "
570                + (isFg ? "foreground" : "background") + " queue");
571        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
572    }
573
574    /**
575     * Activity we have told the window manager to have key focus.
576     */
577    ActivityRecord mFocusedActivity = null;
578
579    /**
580     * User id of the last activity mFocusedActivity was set to.
581     */
582    private int mLastFocusedUserId;
583
584    /**
585     * If non-null, we are tracking the time the user spends in the currently focused app.
586     */
587    private AppTimeTracker mCurAppTimeTracker;
588
589    /**
590     * List of intents that were used to start the most recent tasks.
591     */
592    final RecentTasks mRecentTasks;
593
594    /**
595     * For addAppTask: cached of the last activity component that was added.
596     */
597    ComponentName mLastAddedTaskComponent;
598
599    /**
600     * For addAppTask: cached of the last activity uid that was added.
601     */
602    int mLastAddedTaskUid;
603
604    /**
605     * For addAppTask: cached of the last ActivityInfo that was added.
606     */
607    ActivityInfo mLastAddedTaskActivity;
608
609    /**
610     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
611     */
612    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
613
614    /**
615     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
616     */
617    String mDeviceOwnerName;
618
619    final UserController mUserController;
620
621    final AppErrors mAppErrors;
622
623    boolean mDoingSetFocusedActivity;
624
625    public boolean canShowErrorDialogs() {
626        return mShowDialogs && !mSleeping && !mShuttingDown;
627    }
628
629    public class PendingAssistExtras extends Binder implements Runnable {
630        public final ActivityRecord activity;
631        public final Bundle extras;
632        public final Intent intent;
633        public final String hint;
634        public final IResultReceiver receiver;
635        public final int userHandle;
636        public boolean haveResult = false;
637        public Bundle result = null;
638        public AssistStructure structure = null;
639        public AssistContent content = null;
640        public Bundle receiverExtras;
641
642        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
643                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
644            activity = _activity;
645            extras = _extras;
646            intent = _intent;
647            hint = _hint;
648            receiver = _receiver;
649            receiverExtras = _receiverExtras;
650            userHandle = _userHandle;
651        }
652        @Override
653        public void run() {
654            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
655            synchronized (this) {
656                haveResult = true;
657                notifyAll();
658            }
659            pendingAssistExtrasTimedOut(this);
660        }
661    }
662
663    final ArrayList<PendingAssistExtras> mPendingAssistExtras
664            = new ArrayList<PendingAssistExtras>();
665
666    /**
667     * Process management.
668     */
669    final ProcessList mProcessList = new ProcessList();
670
671    /**
672     * All of the applications we currently have running organized by name.
673     * The keys are strings of the application package name (as
674     * returned by the package manager), and the keys are ApplicationRecord
675     * objects.
676     */
677    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
678
679    /**
680     * Tracking long-term execution of processes to look for abuse and other
681     * bad app behavior.
682     */
683    final ProcessStatsService mProcessStats;
684
685    /**
686     * The currently running isolated processes.
687     */
688    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
689
690    /**
691     * Counter for assigning isolated process uids, to avoid frequently reusing the
692     * same ones.
693     */
694    int mNextIsolatedProcessUid = 0;
695
696    /**
697     * The currently running heavy-weight process, if any.
698     */
699    ProcessRecord mHeavyWeightProcess = null;
700
701    /**
702     * All of the processes we currently have running organized by pid.
703     * The keys are the pid running the application.
704     *
705     * <p>NOTE: This object is protected by its own lock, NOT the global
706     * activity manager lock!
707     */
708    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
709
710    /**
711     * All of the processes that have been forced to be foreground.  The key
712     * is the pid of the caller who requested it (we hold a death
713     * link on it).
714     */
715    abstract class ForegroundToken implements IBinder.DeathRecipient {
716        int pid;
717        IBinder token;
718    }
719    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
720
721    /**
722     * List of records for processes that someone had tried to start before the
723     * system was ready.  We don't start them at that point, but ensure they
724     * are started by the time booting is complete.
725     */
726    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
727
728    /**
729     * List of persistent applications that are in the process
730     * of being started.
731     */
732    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
733
734    /**
735     * Processes that are being forcibly torn down.
736     */
737    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
738
739    /**
740     * List of running applications, sorted by recent usage.
741     * The first entry in the list is the least recently used.
742     */
743    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
744
745    /**
746     * Where in mLruProcesses that the processes hosting activities start.
747     */
748    int mLruProcessActivityStart = 0;
749
750    /**
751     * Where in mLruProcesses that the processes hosting services start.
752     * This is after (lower index) than mLruProcessesActivityStart.
753     */
754    int mLruProcessServiceStart = 0;
755
756    /**
757     * List of processes that should gc as soon as things are idle.
758     */
759    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
760
761    /**
762     * Processes we want to collect PSS data from.
763     */
764    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
765
766    private boolean mBinderTransactionTrackingEnabled = false;
767
768    /**
769     * Last time we requested PSS data of all processes.
770     */
771    long mLastFullPssTime = SystemClock.uptimeMillis();
772
773    /**
774     * If set, the next time we collect PSS data we should do a full collection
775     * with data from native processes and the kernel.
776     */
777    boolean mFullPssPending = false;
778
779    /**
780     * This is the process holding what we currently consider to be
781     * the "home" activity.
782     */
783    ProcessRecord mHomeProcess;
784
785    /**
786     * This is the process holding the activity the user last visited that
787     * is in a different process from the one they are currently in.
788     */
789    ProcessRecord mPreviousProcess;
790
791    /**
792     * The time at which the previous process was last visible.
793     */
794    long mPreviousProcessVisibleTime;
795
796    /**
797     * Track all uids that have actively running processes.
798     */
799    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
800
801    /**
802     * This is for verifying the UID report flow.
803     */
804    static final boolean VALIDATE_UID_STATES = true;
805    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
806
807    /**
808     * Packages that the user has asked to have run in screen size
809     * compatibility mode instead of filling the screen.
810     */
811    final CompatModePackages mCompatModePackages;
812
813    /**
814     * Set of IntentSenderRecord objects that are currently active.
815     */
816    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
817            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
818
819    /**
820     * Fingerprints (hashCode()) of stack traces that we've
821     * already logged DropBox entries for.  Guarded by itself.  If
822     * something (rogue user app) forces this over
823     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
824     */
825    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
826    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
827
828    /**
829     * Strict Mode background batched logging state.
830     *
831     * The string buffer is guarded by itself, and its lock is also
832     * used to determine if another batched write is already
833     * in-flight.
834     */
835    private final StringBuilder mStrictModeBuffer = new StringBuilder();
836
837    /**
838     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
839     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
840     */
841    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
842
843    /**
844     * Resolver for broadcast intents to registered receivers.
845     * Holds BroadcastFilter (subclass of IntentFilter).
846     */
847    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
848            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
849        @Override
850        protected boolean allowFilterResult(
851                BroadcastFilter filter, List<BroadcastFilter> dest) {
852            IBinder target = filter.receiverList.receiver.asBinder();
853            for (int i = dest.size() - 1; i >= 0; i--) {
854                if (dest.get(i).receiverList.receiver.asBinder() == target) {
855                    return false;
856                }
857            }
858            return true;
859        }
860
861        @Override
862        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
863            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
864                    || userId == filter.owningUserId) {
865                return super.newResult(filter, match, userId);
866            }
867            return null;
868        }
869
870        @Override
871        protected BroadcastFilter[] newArray(int size) {
872            return new BroadcastFilter[size];
873        }
874
875        @Override
876        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
877            return packageName.equals(filter.packageName);
878        }
879    };
880
881    /**
882     * State of all active sticky broadcasts per user.  Keys are the action of the
883     * sticky Intent, values are an ArrayList of all broadcasted intents with
884     * that action (which should usually be one).  The SparseArray is keyed
885     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
886     * for stickies that are sent to all users.
887     */
888    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
889            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
890
891    final ActiveServices mServices;
892
893    final static class Association {
894        final int mSourceUid;
895        final String mSourceProcess;
896        final int mTargetUid;
897        final ComponentName mTargetComponent;
898        final String mTargetProcess;
899
900        int mCount;
901        long mTime;
902
903        int mNesting;
904        long mStartTime;
905
906        // states of the source process when the bind occurred.
907        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
908        long mLastStateUptime;
909        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
910                - ActivityManager.MIN_PROCESS_STATE+1];
911
912        Association(int sourceUid, String sourceProcess, int targetUid,
913                ComponentName targetComponent, String targetProcess) {
914            mSourceUid = sourceUid;
915            mSourceProcess = sourceProcess;
916            mTargetUid = targetUid;
917            mTargetComponent = targetComponent;
918            mTargetProcess = targetProcess;
919        }
920    }
921
922    /**
923     * When service association tracking is enabled, this is all of the associations we
924     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
925     * -> association data.
926     */
927    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
928            mAssociations = new SparseArray<>();
929    boolean mTrackingAssociations;
930
931    /**
932     * Backup/restore process management
933     */
934    String mBackupAppName = null;
935    BackupRecord mBackupTarget = null;
936
937    final ProviderMap mProviderMap;
938
939    /**
940     * List of content providers who have clients waiting for them.  The
941     * application is currently being launched and the provider will be
942     * removed from this list once it is published.
943     */
944    final ArrayList<ContentProviderRecord> mLaunchingProviders
945            = new ArrayList<ContentProviderRecord>();
946
947    /**
948     * File storing persisted {@link #mGrantedUriPermissions}.
949     */
950    private final AtomicFile mGrantFile;
951
952    /** XML constants used in {@link #mGrantFile} */
953    private static final String TAG_URI_GRANTS = "uri-grants";
954    private static final String TAG_URI_GRANT = "uri-grant";
955    private static final String ATTR_USER_HANDLE = "userHandle";
956    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
957    private static final String ATTR_TARGET_USER_ID = "targetUserId";
958    private static final String ATTR_SOURCE_PKG = "sourcePkg";
959    private static final String ATTR_TARGET_PKG = "targetPkg";
960    private static final String ATTR_URI = "uri";
961    private static final String ATTR_MODE_FLAGS = "modeFlags";
962    private static final String ATTR_CREATED_TIME = "createdTime";
963    private static final String ATTR_PREFIX = "prefix";
964
965    /**
966     * Global set of specific {@link Uri} permissions that have been granted.
967     * This optimized lookup structure maps from {@link UriPermission#targetUid}
968     * to {@link UriPermission#uri} to {@link UriPermission}.
969     */
970    @GuardedBy("this")
971    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
972            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
973
974    public static class GrantUri {
975        public final int sourceUserId;
976        public final Uri uri;
977        public boolean prefix;
978
979        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
980            this.sourceUserId = sourceUserId;
981            this.uri = uri;
982            this.prefix = prefix;
983        }
984
985        @Override
986        public int hashCode() {
987            int hashCode = 1;
988            hashCode = 31 * hashCode + sourceUserId;
989            hashCode = 31 * hashCode + uri.hashCode();
990            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
991            return hashCode;
992        }
993
994        @Override
995        public boolean equals(Object o) {
996            if (o instanceof GrantUri) {
997                GrantUri other = (GrantUri) o;
998                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
999                        && prefix == other.prefix;
1000            }
1001            return false;
1002        }
1003
1004        @Override
1005        public String toString() {
1006            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1007            if (prefix) result += " [prefix]";
1008            return result;
1009        }
1010
1011        public String toSafeString() {
1012            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1013            if (prefix) result += " [prefix]";
1014            return result;
1015        }
1016
1017        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1018            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1019                    ContentProvider.getUriWithoutUserId(uri), false);
1020        }
1021    }
1022
1023    CoreSettingsObserver mCoreSettingsObserver;
1024
1025    FontScaleSettingObserver mFontScaleSettingObserver;
1026
1027    private final class FontScaleSettingObserver extends ContentObserver {
1028        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1029
1030        public FontScaleSettingObserver() {
1031            super(mHandler);
1032            ContentResolver resolver = mContext.getContentResolver();
1033            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1034        }
1035
1036        @Override
1037        public void onChange(boolean selfChange, Uri uri) {
1038            if (mFontScaleUri.equals(uri)) {
1039                updateFontScaleIfNeeded();
1040            }
1041        }
1042    }
1043
1044    /**
1045     * Thread-local storage used to carry caller permissions over through
1046     * indirect content-provider access.
1047     */
1048    private class Identity {
1049        public final IBinder token;
1050        public final int pid;
1051        public final int uid;
1052
1053        Identity(IBinder _token, int _pid, int _uid) {
1054            token = _token;
1055            pid = _pid;
1056            uid = _uid;
1057        }
1058    }
1059
1060    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1061
1062    /**
1063     * All information we have collected about the runtime performance of
1064     * any user id that can impact battery performance.
1065     */
1066    final BatteryStatsService mBatteryStatsService;
1067
1068    /**
1069     * Information about component usage
1070     */
1071    UsageStatsManagerInternal mUsageStatsService;
1072
1073    /**
1074     * Access to DeviceIdleController service.
1075     */
1076    DeviceIdleController.LocalService mLocalDeviceIdleController;
1077
1078    /**
1079     * Information about and control over application operations
1080     */
1081    final AppOpsService mAppOpsService;
1082
1083    /**
1084     * Current configuration information.  HistoryRecord objects are given
1085     * a reference to this object to indicate which configuration they are
1086     * currently running in, so this object must be kept immutable.
1087     */
1088    Configuration mConfiguration = new Configuration();
1089
1090    /**
1091     * Current sequencing integer of the configuration, for skipping old
1092     * configurations.
1093     */
1094    int mConfigurationSeq = 0;
1095
1096    boolean mSuppressResizeConfigChanges = false;
1097
1098    /**
1099     * Hardware-reported OpenGLES version.
1100     */
1101    final int GL_ES_VERSION;
1102
1103    /**
1104     * List of initialization arguments to pass to all processes when binding applications to them.
1105     * For example, references to the commonly used services.
1106     */
1107    HashMap<String, IBinder> mAppBindArgs;
1108
1109    /**
1110     * Temporary to avoid allocations.  Protected by main lock.
1111     */
1112    final StringBuilder mStringBuilder = new StringBuilder(256);
1113
1114    /**
1115     * Used to control how we initialize the service.
1116     */
1117    ComponentName mTopComponent;
1118    String mTopAction = Intent.ACTION_MAIN;
1119    String mTopData;
1120
1121    volatile boolean mProcessesReady = false;
1122    volatile boolean mSystemReady = false;
1123    volatile boolean mOnBattery = false;
1124    volatile int mFactoryTest;
1125
1126    @GuardedBy("this") boolean mBooting = false;
1127    @GuardedBy("this") boolean mCallFinishBooting = false;
1128    @GuardedBy("this") boolean mBootAnimationComplete = false;
1129    @GuardedBy("this") boolean mLaunchWarningShown = false;
1130    @GuardedBy("this") boolean mCheckedForSetup = false;
1131
1132    Context mContext;
1133
1134    /**
1135     * The time at which we will allow normal application switches again,
1136     * after a call to {@link #stopAppSwitches()}.
1137     */
1138    long mAppSwitchesAllowedTime;
1139
1140    /**
1141     * This is set to true after the first switch after mAppSwitchesAllowedTime
1142     * is set; any switches after that will clear the time.
1143     */
1144    boolean mDidAppSwitch;
1145
1146    /**
1147     * Last time (in realtime) at which we checked for power usage.
1148     */
1149    long mLastPowerCheckRealtime;
1150
1151    /**
1152     * Last time (in uptime) at which we checked for power usage.
1153     */
1154    long mLastPowerCheckUptime;
1155
1156    /**
1157     * Set while we are wanting to sleep, to prevent any
1158     * activities from being started/resumed.
1159     */
1160    private boolean mSleeping = false;
1161
1162    /**
1163     * The process state used for processes that are running the top activities.
1164     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1165     */
1166    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1167
1168    /**
1169     * Set while we are running a voice interaction.  This overrides
1170     * sleeping while it is active.
1171     */
1172    private IVoiceInteractionSession mRunningVoice;
1173
1174    /**
1175     * For some direct access we need to power manager.
1176     */
1177    PowerManagerInternal mLocalPowerManager;
1178
1179    /**
1180     * We want to hold a wake lock while running a voice interaction session, since
1181     * this may happen with the screen off and we need to keep the CPU running to
1182     * be able to continue to interact with the user.
1183     */
1184    PowerManager.WakeLock mVoiceWakeLock;
1185
1186    /**
1187     * State of external calls telling us if the device is awake or asleep.
1188     */
1189    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1190
1191    /**
1192     * A list of tokens that cause the top activity to be put to sleep.
1193     * They are used by components that may hide and block interaction with underlying
1194     * activities.
1195     */
1196    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1197
1198    static final int LOCK_SCREEN_HIDDEN = 0;
1199    static final int LOCK_SCREEN_LEAVING = 1;
1200    static final int LOCK_SCREEN_SHOWN = 2;
1201    /**
1202     * State of external call telling us if the lock screen is shown.
1203     */
1204    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1205
1206    /**
1207     * Set if we are shutting down the system, similar to sleeping.
1208     */
1209    boolean mShuttingDown = false;
1210
1211    /**
1212     * Current sequence id for oom_adj computation traversal.
1213     */
1214    int mAdjSeq = 0;
1215
1216    /**
1217     * Current sequence id for process LRU updating.
1218     */
1219    int mLruSeq = 0;
1220
1221    /**
1222     * Keep track of the non-cached/empty process we last found, to help
1223     * determine how to distribute cached/empty processes next time.
1224     */
1225    int mNumNonCachedProcs = 0;
1226
1227    /**
1228     * Keep track of the number of cached hidden procs, to balance oom adj
1229     * distribution between those and empty procs.
1230     */
1231    int mNumCachedHiddenProcs = 0;
1232
1233    /**
1234     * Keep track of the number of service processes we last found, to
1235     * determine on the next iteration which should be B services.
1236     */
1237    int mNumServiceProcs = 0;
1238    int mNewNumAServiceProcs = 0;
1239    int mNewNumServiceProcs = 0;
1240
1241    /**
1242     * Allow the current computed overall memory level of the system to go down?
1243     * This is set to false when we are killing processes for reasons other than
1244     * memory management, so that the now smaller process list will not be taken as
1245     * an indication that memory is tighter.
1246     */
1247    boolean mAllowLowerMemLevel = false;
1248
1249    /**
1250     * The last computed memory level, for holding when we are in a state that
1251     * processes are going away for other reasons.
1252     */
1253    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1254
1255    /**
1256     * The last total number of process we have, to determine if changes actually look
1257     * like a shrinking number of process due to lower RAM.
1258     */
1259    int mLastNumProcesses;
1260
1261    /**
1262     * The uptime of the last time we performed idle maintenance.
1263     */
1264    long mLastIdleTime = SystemClock.uptimeMillis();
1265
1266    /**
1267     * Total time spent with RAM that has been added in the past since the last idle time.
1268     */
1269    long mLowRamTimeSinceLastIdle = 0;
1270
1271    /**
1272     * If RAM is currently low, when that horrible situation started.
1273     */
1274    long mLowRamStartTime = 0;
1275
1276    /**
1277     * For reporting to battery stats the current top application.
1278     */
1279    private String mCurResumedPackage = null;
1280    private int mCurResumedUid = -1;
1281
1282    /**
1283     * For reporting to battery stats the apps currently running foreground
1284     * service.  The ProcessMap is package/uid tuples; each of these contain
1285     * an array of the currently foreground processes.
1286     */
1287    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1288            = new ProcessMap<ArrayList<ProcessRecord>>();
1289
1290    /**
1291     * This is set if we had to do a delayed dexopt of an app before launching
1292     * it, to increase the ANR timeouts in that case.
1293     */
1294    boolean mDidDexOpt;
1295
1296    /**
1297     * Set if the systemServer made a call to enterSafeMode.
1298     */
1299    boolean mSafeMode;
1300
1301    /**
1302     * If true, we are running under a test environment so will sample PSS from processes
1303     * much more rapidly to try to collect better data when the tests are rapidly
1304     * running through apps.
1305     */
1306    boolean mTestPssMode = false;
1307
1308    String mDebugApp = null;
1309    boolean mWaitForDebugger = false;
1310    boolean mDebugTransient = false;
1311    String mOrigDebugApp = null;
1312    boolean mOrigWaitForDebugger = false;
1313    boolean mAlwaysFinishActivities = false;
1314    boolean mLenientBackgroundCheck = false;
1315    boolean mForceResizableActivities;
1316    boolean mSupportsMultiWindow;
1317    boolean mSupportsFreeformWindowManagement;
1318    boolean mSupportsPictureInPicture;
1319    Rect mDefaultPinnedStackBounds;
1320    IActivityController mController = null;
1321    boolean mControllerIsAMonkey = false;
1322    String mProfileApp = null;
1323    ProcessRecord mProfileProc = null;
1324    String mProfileFile;
1325    ParcelFileDescriptor mProfileFd;
1326    int mSamplingInterval = 0;
1327    boolean mAutoStopProfiler = false;
1328    int mProfileType = 0;
1329    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1330    String mMemWatchDumpProcName;
1331    String mMemWatchDumpFile;
1332    int mMemWatchDumpPid;
1333    int mMemWatchDumpUid;
1334    String mTrackAllocationApp = null;
1335    String mNativeDebuggingApp = null;
1336
1337    final long[] mTmpLong = new long[2];
1338
1339    static final class ProcessChangeItem {
1340        static final int CHANGE_ACTIVITIES = 1<<0;
1341        static final int CHANGE_PROCESS_STATE = 1<<1;
1342        int changes;
1343        int uid;
1344        int pid;
1345        int processState;
1346        boolean foregroundActivities;
1347    }
1348
1349    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1350    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1351
1352    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1353    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1354
1355    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1356    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1357
1358    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1359    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1360
1361    /**
1362     * Runtime CPU use collection thread.  This object's lock is used to
1363     * perform synchronization with the thread (notifying it to run).
1364     */
1365    final Thread mProcessCpuThread;
1366
1367    /**
1368     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1369     * Must acquire this object's lock when accessing it.
1370     * NOTE: this lock will be held while doing long operations (trawling
1371     * through all processes in /proc), so it should never be acquired by
1372     * any critical paths such as when holding the main activity manager lock.
1373     */
1374    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1375            MONITOR_THREAD_CPU_USAGE);
1376    final AtomicLong mLastCpuTime = new AtomicLong(0);
1377    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1378
1379    long mLastWriteTime = 0;
1380
1381    /**
1382     * Used to retain an update lock when the foreground activity is in
1383     * immersive mode.
1384     */
1385    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1386
1387    /**
1388     * Set to true after the system has finished booting.
1389     */
1390    boolean mBooted = false;
1391
1392    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1393    int mProcessLimitOverride = -1;
1394
1395    WindowManagerService mWindowManager;
1396    final ActivityThread mSystemThread;
1397
1398    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1399        final ProcessRecord mApp;
1400        final int mPid;
1401        final IApplicationThread mAppThread;
1402
1403        AppDeathRecipient(ProcessRecord app, int pid,
1404                IApplicationThread thread) {
1405            if (DEBUG_ALL) Slog.v(
1406                TAG, "New death recipient " + this
1407                + " for thread " + thread.asBinder());
1408            mApp = app;
1409            mPid = pid;
1410            mAppThread = thread;
1411        }
1412
1413        @Override
1414        public void binderDied() {
1415            if (DEBUG_ALL) Slog.v(
1416                TAG, "Death received in " + this
1417                + " for thread " + mAppThread.asBinder());
1418            synchronized(ActivityManagerService.this) {
1419                appDiedLocked(mApp, mPid, mAppThread, true);
1420            }
1421        }
1422    }
1423
1424    static final int SHOW_ERROR_UI_MSG = 1;
1425    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1426    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1427    static final int UPDATE_CONFIGURATION_MSG = 4;
1428    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1429    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1430    static final int SERVICE_TIMEOUT_MSG = 12;
1431    static final int UPDATE_TIME_ZONE = 13;
1432    static final int SHOW_UID_ERROR_UI_MSG = 14;
1433    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1434    static final int PROC_START_TIMEOUT_MSG = 20;
1435    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1436    static final int KILL_APPLICATION_MSG = 22;
1437    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1438    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1439    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1440    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1441    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1442    static final int CLEAR_DNS_CACHE_MSG = 28;
1443    static final int UPDATE_HTTP_PROXY_MSG = 29;
1444    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1445    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1446    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1447    static final int REPORT_MEM_USAGE_MSG = 33;
1448    static final int REPORT_USER_SWITCH_MSG = 34;
1449    static final int CONTINUE_USER_SWITCH_MSG = 35;
1450    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1451    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1452    static final int PERSIST_URI_GRANTS_MSG = 38;
1453    static final int REQUEST_ALL_PSS_MSG = 39;
1454    static final int START_PROFILES_MSG = 40;
1455    static final int UPDATE_TIME = 41;
1456    static final int SYSTEM_USER_START_MSG = 42;
1457    static final int SYSTEM_USER_CURRENT_MSG = 43;
1458    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1459    static final int FINISH_BOOTING_MSG = 45;
1460    static final int START_USER_SWITCH_UI_MSG = 46;
1461    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1462    static final int DISMISS_DIALOG_UI_MSG = 48;
1463    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1464    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1465    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1466    static final int DELETE_DUMPHEAP_MSG = 52;
1467    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1468    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1469    static final int REPORT_TIME_TRACKER_MSG = 55;
1470    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1471    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1472    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1473    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1474    static final int IDLE_UIDS_MSG = 60;
1475    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1476    static final int LOG_STACK_STATE = 62;
1477    static final int VR_MODE_CHANGE_MSG = 63;
1478    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1479    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1480    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1481    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1482    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1483    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1484
1485    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1486    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1487    static final int FIRST_COMPAT_MODE_MSG = 300;
1488    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1489
1490    static ServiceThread sKillThread = null;
1491    static KillHandler sKillHandler = null;
1492
1493    CompatModeDialog mCompatModeDialog;
1494    long mLastMemUsageReportTime = 0;
1495
1496    /**
1497     * Flag whether the current user is a "monkey", i.e. whether
1498     * the UI is driven by a UI automation tool.
1499     */
1500    private boolean mUserIsMonkey;
1501
1502    /** Flag whether the device has a Recents UI */
1503    boolean mHasRecents;
1504
1505    /** The dimensions of the thumbnails in the Recents UI. */
1506    int mThumbnailWidth;
1507    int mThumbnailHeight;
1508    float mFullscreenThumbnailScale;
1509
1510    final ServiceThread mHandlerThread;
1511    final MainHandler mHandler;
1512    final UiHandler mUiHandler;
1513
1514    PackageManagerInternal mPackageManagerInt;
1515
1516    // VoiceInteraction session ID that changes for each new request except when
1517    // being called for multiwindow assist in a single session.
1518    private int mViSessionId = 1000;
1519
1520    final class KillHandler extends Handler {
1521        static final int KILL_PROCESS_GROUP_MSG = 4000;
1522
1523        public KillHandler(Looper looper) {
1524            super(looper, null, true);
1525        }
1526
1527        @Override
1528        public void handleMessage(Message msg) {
1529            switch (msg.what) {
1530                case KILL_PROCESS_GROUP_MSG:
1531                {
1532                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1533                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1534                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1535                }
1536                break;
1537
1538                default:
1539                    super.handleMessage(msg);
1540            }
1541        }
1542    }
1543
1544    final class UiHandler extends Handler {
1545        public UiHandler() {
1546            super(com.android.server.UiThread.get().getLooper(), null, true);
1547        }
1548
1549        @Override
1550        public void handleMessage(Message msg) {
1551            switch (msg.what) {
1552            case SHOW_ERROR_UI_MSG: {
1553                mAppErrors.handleShowAppErrorUi(msg);
1554                ensureBootCompleted();
1555            } break;
1556            case SHOW_NOT_RESPONDING_UI_MSG: {
1557                mAppErrors.handleShowAnrUi(msg);
1558                ensureBootCompleted();
1559            } break;
1560            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1561                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1562                synchronized (ActivityManagerService.this) {
1563                    ProcessRecord proc = (ProcessRecord) data.get("app");
1564                    if (proc == null) {
1565                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1566                        break;
1567                    }
1568                    if (proc.crashDialog != null) {
1569                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1570                        return;
1571                    }
1572                    AppErrorResult res = (AppErrorResult) data.get("result");
1573                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1574                        Dialog d = new StrictModeViolationDialog(mContext,
1575                                ActivityManagerService.this, res, proc);
1576                        d.show();
1577                        proc.crashDialog = d;
1578                    } else {
1579                        // The device is asleep, so just pretend that the user
1580                        // saw a crash dialog and hit "force quit".
1581                        res.set(0);
1582                    }
1583                }
1584                ensureBootCompleted();
1585            } break;
1586            case SHOW_FACTORY_ERROR_UI_MSG: {
1587                Dialog d = new FactoryErrorDialog(
1588                    mContext, msg.getData().getCharSequence("msg"));
1589                d.show();
1590                ensureBootCompleted();
1591            } break;
1592            case WAIT_FOR_DEBUGGER_UI_MSG: {
1593                synchronized (ActivityManagerService.this) {
1594                    ProcessRecord app = (ProcessRecord)msg.obj;
1595                    if (msg.arg1 != 0) {
1596                        if (!app.waitedForDebugger) {
1597                            Dialog d = new AppWaitingForDebuggerDialog(
1598                                    ActivityManagerService.this,
1599                                    mContext, app);
1600                            app.waitDialog = d;
1601                            app.waitedForDebugger = true;
1602                            d.show();
1603                        }
1604                    } else {
1605                        if (app.waitDialog != null) {
1606                            app.waitDialog.dismiss();
1607                            app.waitDialog = null;
1608                        }
1609                    }
1610                }
1611            } break;
1612            case SHOW_UID_ERROR_UI_MSG: {
1613                if (mShowDialogs) {
1614                    AlertDialog d = new BaseErrorDialog(mContext);
1615                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1616                    d.setCancelable(false);
1617                    d.setTitle(mContext.getText(R.string.android_system_label));
1618                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1619                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1620                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1621                    d.show();
1622                }
1623            } break;
1624            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1625                if (mShowDialogs) {
1626                    AlertDialog d = new BaseErrorDialog(mContext);
1627                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1628                    d.setCancelable(false);
1629                    d.setTitle(mContext.getText(R.string.android_system_label));
1630                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1631                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1632                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1633                    d.show();
1634                }
1635            } break;
1636            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1637                synchronized (ActivityManagerService.this) {
1638                    ActivityRecord ar = (ActivityRecord) msg.obj;
1639                    if (mCompatModeDialog != null) {
1640                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1641                                ar.info.applicationInfo.packageName)) {
1642                            return;
1643                        }
1644                        mCompatModeDialog.dismiss();
1645                        mCompatModeDialog = null;
1646                    }
1647                    if (ar != null && false) {
1648                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1649                                ar.packageName)) {
1650                            int mode = mCompatModePackages.computeCompatModeLocked(
1651                                    ar.info.applicationInfo);
1652                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1653                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1654                                mCompatModeDialog = new CompatModeDialog(
1655                                        ActivityManagerService.this, mContext,
1656                                        ar.info.applicationInfo);
1657                                mCompatModeDialog.show();
1658                            }
1659                        }
1660                    }
1661                }
1662                break;
1663            }
1664            case START_USER_SWITCH_UI_MSG: {
1665                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1666                break;
1667            }
1668            case DISMISS_DIALOG_UI_MSG: {
1669                final Dialog d = (Dialog) msg.obj;
1670                d.dismiss();
1671                break;
1672            }
1673            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1674                dispatchProcessesChanged();
1675                break;
1676            }
1677            case DISPATCH_PROCESS_DIED_UI_MSG: {
1678                final int pid = msg.arg1;
1679                final int uid = msg.arg2;
1680                dispatchProcessDied(pid, uid);
1681                break;
1682            }
1683            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1684                dispatchUidsChanged();
1685            } break;
1686            }
1687        }
1688    }
1689
1690    final class MainHandler extends Handler {
1691        public MainHandler(Looper looper) {
1692            super(looper, null, true);
1693        }
1694
1695        @Override
1696        public void handleMessage(Message msg) {
1697            switch (msg.what) {
1698            case UPDATE_CONFIGURATION_MSG: {
1699                final ContentResolver resolver = mContext.getContentResolver();
1700                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1701                        msg.arg1);
1702            } break;
1703            case GC_BACKGROUND_PROCESSES_MSG: {
1704                synchronized (ActivityManagerService.this) {
1705                    performAppGcsIfAppropriateLocked();
1706                }
1707            } break;
1708            case SERVICE_TIMEOUT_MSG: {
1709                if (mDidDexOpt) {
1710                    mDidDexOpt = false;
1711                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1712                    nmsg.obj = msg.obj;
1713                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1714                    return;
1715                }
1716                mServices.serviceTimeout((ProcessRecord)msg.obj);
1717            } break;
1718            case UPDATE_TIME_ZONE: {
1719                synchronized (ActivityManagerService.this) {
1720                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1721                        ProcessRecord r = mLruProcesses.get(i);
1722                        if (r.thread != null) {
1723                            try {
1724                                r.thread.updateTimeZone();
1725                            } catch (RemoteException ex) {
1726                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1727                            }
1728                        }
1729                    }
1730                }
1731            } break;
1732            case CLEAR_DNS_CACHE_MSG: {
1733                synchronized (ActivityManagerService.this) {
1734                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1735                        ProcessRecord r = mLruProcesses.get(i);
1736                        if (r.thread != null) {
1737                            try {
1738                                r.thread.clearDnsCache();
1739                            } catch (RemoteException ex) {
1740                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1741                            }
1742                        }
1743                    }
1744                }
1745            } break;
1746            case UPDATE_HTTP_PROXY_MSG: {
1747                ProxyInfo proxy = (ProxyInfo)msg.obj;
1748                String host = "";
1749                String port = "";
1750                String exclList = "";
1751                Uri pacFileUrl = Uri.EMPTY;
1752                if (proxy != null) {
1753                    host = proxy.getHost();
1754                    port = Integer.toString(proxy.getPort());
1755                    exclList = proxy.getExclusionListAsString();
1756                    pacFileUrl = proxy.getPacFileUrl();
1757                }
1758                synchronized (ActivityManagerService.this) {
1759                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1760                        ProcessRecord r = mLruProcesses.get(i);
1761                        if (r.thread != null) {
1762                            try {
1763                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1764                            } catch (RemoteException ex) {
1765                                Slog.w(TAG, "Failed to update http proxy for: " +
1766                                        r.info.processName);
1767                            }
1768                        }
1769                    }
1770                }
1771            } break;
1772            case PROC_START_TIMEOUT_MSG: {
1773                if (mDidDexOpt) {
1774                    mDidDexOpt = false;
1775                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1776                    nmsg.obj = msg.obj;
1777                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1778                    return;
1779                }
1780                ProcessRecord app = (ProcessRecord)msg.obj;
1781                synchronized (ActivityManagerService.this) {
1782                    processStartTimedOutLocked(app);
1783                }
1784            } break;
1785            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1786                ProcessRecord app = (ProcessRecord)msg.obj;
1787                synchronized (ActivityManagerService.this) {
1788                    processContentProviderPublishTimedOutLocked(app);
1789                }
1790            } break;
1791            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1792                synchronized (ActivityManagerService.this) {
1793                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1794                }
1795            } break;
1796            case KILL_APPLICATION_MSG: {
1797                synchronized (ActivityManagerService.this) {
1798                    int appid = msg.arg1;
1799                    boolean restart = (msg.arg2 == 1);
1800                    Bundle bundle = (Bundle)msg.obj;
1801                    String pkg = bundle.getString("pkg");
1802                    String reason = bundle.getString("reason");
1803                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1804                            false, UserHandle.USER_ALL, reason);
1805                }
1806            } break;
1807            case FINALIZE_PENDING_INTENT_MSG: {
1808                ((PendingIntentRecord)msg.obj).completeFinalize();
1809            } break;
1810            case POST_HEAVY_NOTIFICATION_MSG: {
1811                INotificationManager inm = NotificationManager.getService();
1812                if (inm == null) {
1813                    return;
1814                }
1815
1816                ActivityRecord root = (ActivityRecord)msg.obj;
1817                ProcessRecord process = root.app;
1818                if (process == null) {
1819                    return;
1820                }
1821
1822                try {
1823                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1824                    String text = mContext.getString(R.string.heavy_weight_notification,
1825                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1826                    Notification notification = new Notification.Builder(context)
1827                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1828                            .setWhen(0)
1829                            .setOngoing(true)
1830                            .setTicker(text)
1831                            .setColor(mContext.getColor(
1832                                    com.android.internal.R.color.system_notification_accent_color))
1833                            .setContentTitle(text)
1834                            .setContentText(
1835                                    mContext.getText(R.string.heavy_weight_notification_detail))
1836                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1837                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1838                                    new UserHandle(root.userId)))
1839                            .build();
1840                    try {
1841                        int[] outId = new int[1];
1842                        inm.enqueueNotificationWithTag("android", "android", null,
1843                                R.string.heavy_weight_notification,
1844                                notification, outId, root.userId);
1845                    } catch (RuntimeException e) {
1846                        Slog.w(ActivityManagerService.TAG,
1847                                "Error showing notification for heavy-weight app", e);
1848                    } catch (RemoteException e) {
1849                    }
1850                } catch (NameNotFoundException e) {
1851                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1852                }
1853            } break;
1854            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1855                INotificationManager inm = NotificationManager.getService();
1856                if (inm == null) {
1857                    return;
1858                }
1859                try {
1860                    inm.cancelNotificationWithTag("android", null,
1861                            R.string.heavy_weight_notification,  msg.arg1);
1862                } catch (RuntimeException e) {
1863                    Slog.w(ActivityManagerService.TAG,
1864                            "Error canceling notification for service", e);
1865                } catch (RemoteException e) {
1866                }
1867            } break;
1868            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1869                synchronized (ActivityManagerService.this) {
1870                    checkExcessivePowerUsageLocked(true);
1871                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1872                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1873                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1874                }
1875            } break;
1876            case REPORT_MEM_USAGE_MSG: {
1877                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1878                Thread thread = new Thread() {
1879                    @Override public void run() {
1880                        reportMemUsage(memInfos);
1881                    }
1882                };
1883                thread.start();
1884                break;
1885            }
1886            case REPORT_USER_SWITCH_MSG: {
1887                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1888                break;
1889            }
1890            case CONTINUE_USER_SWITCH_MSG: {
1891                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1892                break;
1893            }
1894            case USER_SWITCH_TIMEOUT_MSG: {
1895                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1896                break;
1897            }
1898            case IMMERSIVE_MODE_LOCK_MSG: {
1899                final boolean nextState = (msg.arg1 != 0);
1900                if (mUpdateLock.isHeld() != nextState) {
1901                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1902                            "Applying new update lock state '" + nextState
1903                            + "' for " + (ActivityRecord)msg.obj);
1904                    if (nextState) {
1905                        mUpdateLock.acquire();
1906                    } else {
1907                        mUpdateLock.release();
1908                    }
1909                }
1910                break;
1911            }
1912            case PERSIST_URI_GRANTS_MSG: {
1913                writeGrantedUriPermissions();
1914                break;
1915            }
1916            case REQUEST_ALL_PSS_MSG: {
1917                synchronized (ActivityManagerService.this) {
1918                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1919                }
1920                break;
1921            }
1922            case START_PROFILES_MSG: {
1923                synchronized (ActivityManagerService.this) {
1924                    mUserController.startProfilesLocked();
1925                }
1926                break;
1927            }
1928            case UPDATE_TIME: {
1929                synchronized (ActivityManagerService.this) {
1930                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1931                        ProcessRecord r = mLruProcesses.get(i);
1932                        if (r.thread != null) {
1933                            try {
1934                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1935                            } catch (RemoteException ex) {
1936                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1937                            }
1938                        }
1939                    }
1940                }
1941                break;
1942            }
1943            case SYSTEM_USER_START_MSG: {
1944                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1945                        Integer.toString(msg.arg1), msg.arg1);
1946                mSystemServiceManager.startUser(msg.arg1);
1947                break;
1948            }
1949            case SYSTEM_USER_UNLOCK_MSG: {
1950                final int userId = msg.arg1;
1951                mSystemServiceManager.unlockUser(userId);
1952                synchronized (ActivityManagerService.this) {
1953                    mRecentTasks.loadUserRecentsLocked(userId);
1954                }
1955                if (userId == UserHandle.USER_SYSTEM) {
1956                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1957                }
1958                installEncryptionUnawareProviders(userId);
1959                mUserController.finishUserUnlocked((UserState) msg.obj);
1960                break;
1961            }
1962            case SYSTEM_USER_CURRENT_MSG: {
1963                mBatteryStatsService.noteEvent(
1964                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1965                        Integer.toString(msg.arg2), msg.arg2);
1966                mBatteryStatsService.noteEvent(
1967                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1968                        Integer.toString(msg.arg1), msg.arg1);
1969                mSystemServiceManager.switchUser(msg.arg1);
1970                break;
1971            }
1972            case ENTER_ANIMATION_COMPLETE_MSG: {
1973                synchronized (ActivityManagerService.this) {
1974                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1975                    if (r != null && r.app != null && r.app.thread != null) {
1976                        try {
1977                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1978                        } catch (RemoteException e) {
1979                        }
1980                    }
1981                }
1982                break;
1983            }
1984            case FINISH_BOOTING_MSG: {
1985                if (msg.arg1 != 0) {
1986                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1987                    finishBooting();
1988                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1989                }
1990                if (msg.arg2 != 0) {
1991                    enableScreenAfterBoot();
1992                }
1993                break;
1994            }
1995            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1996                try {
1997                    Locale l = (Locale) msg.obj;
1998                    IBinder service = ServiceManager.getService("mount");
1999                    IMountService mountService = IMountService.Stub.asInterface(service);
2000                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2001                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2002                } catch (RemoteException e) {
2003                    Log.e(TAG, "Error storing locale for decryption UI", e);
2004                }
2005                break;
2006            }
2007            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2008                synchronized (ActivityManagerService.this) {
2009                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2010                        try {
2011                            // Make a one-way callback to the listener
2012                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2013                        } catch (RemoteException e){
2014                            // Handled by the RemoteCallbackList
2015                        }
2016                    }
2017                    mTaskStackListeners.finishBroadcast();
2018                }
2019                break;
2020            }
2021            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2022                synchronized (ActivityManagerService.this) {
2023                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2024                        try {
2025                            // Make a one-way callback to the listener
2026                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2027                        } catch (RemoteException e){
2028                            // Handled by the RemoteCallbackList
2029                        }
2030                    }
2031                    mTaskStackListeners.finishBroadcast();
2032                }
2033                break;
2034            }
2035            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2036                synchronized (ActivityManagerService.this) {
2037                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2038                        try {
2039                            // Make a one-way callback to the listener
2040                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2041                        } catch (RemoteException e){
2042                            // Handled by the RemoteCallbackList
2043                        }
2044                    }
2045                    mTaskStackListeners.finishBroadcast();
2046                }
2047                break;
2048            }
2049            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2050                synchronized (ActivityManagerService.this) {
2051                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2052                        try {
2053                            // Make a one-way callback to the listener
2054                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2055                        } catch (RemoteException e){
2056                            // Handled by the RemoteCallbackList
2057                        }
2058                    }
2059                    mTaskStackListeners.finishBroadcast();
2060                }
2061                break;
2062            }
2063            case NOTIFY_FORCED_RESIZABLE_MSG: {
2064                synchronized (ActivityManagerService.this) {
2065                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2066                        try {
2067                            // Make a one-way callback to the listener
2068                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2069                                    (String) msg.obj, msg.arg1);
2070                        } catch (RemoteException e){
2071                            // Handled by the RemoteCallbackList
2072                        }
2073                    }
2074                    mTaskStackListeners.finishBroadcast();
2075                }
2076                break;
2077            }
2078                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2079                    synchronized (ActivityManagerService.this) {
2080                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2081                            try {
2082                                // Make a one-way callback to the listener
2083                                mTaskStackListeners.getBroadcastItem(i)
2084                                        .onActivityDismissingDockedStack();
2085                            } catch (RemoteException e){
2086                                // Handled by the RemoteCallbackList
2087                            }
2088                        }
2089                        mTaskStackListeners.finishBroadcast();
2090                    }
2091                    break;
2092                }
2093            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2094                final int uid = msg.arg1;
2095                final byte[] firstPacket = (byte[]) msg.obj;
2096
2097                synchronized (mPidsSelfLocked) {
2098                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2099                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2100                        if (p.uid == uid) {
2101                            try {
2102                                p.thread.notifyCleartextNetwork(firstPacket);
2103                            } catch (RemoteException ignored) {
2104                            }
2105                        }
2106                    }
2107                }
2108                break;
2109            }
2110            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2111                final String procName;
2112                final int uid;
2113                final long memLimit;
2114                final String reportPackage;
2115                synchronized (ActivityManagerService.this) {
2116                    procName = mMemWatchDumpProcName;
2117                    uid = mMemWatchDumpUid;
2118                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2119                    if (val == null) {
2120                        val = mMemWatchProcesses.get(procName, 0);
2121                    }
2122                    if (val != null) {
2123                        memLimit = val.first;
2124                        reportPackage = val.second;
2125                    } else {
2126                        memLimit = 0;
2127                        reportPackage = null;
2128                    }
2129                }
2130                if (procName == null) {
2131                    return;
2132                }
2133
2134                if (DEBUG_PSS) Slog.d(TAG_PSS,
2135                        "Showing dump heap notification from " + procName + "/" + uid);
2136
2137                INotificationManager inm = NotificationManager.getService();
2138                if (inm == null) {
2139                    return;
2140                }
2141
2142                String text = mContext.getString(R.string.dump_heap_notification, procName);
2143
2144
2145                Intent deleteIntent = new Intent();
2146                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2147                Intent intent = new Intent();
2148                intent.setClassName("android", DumpHeapActivity.class.getName());
2149                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2150                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2151                if (reportPackage != null) {
2152                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2153                }
2154                int userId = UserHandle.getUserId(uid);
2155                Notification notification = new Notification.Builder(mContext)
2156                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2157                        .setWhen(0)
2158                        .setOngoing(true)
2159                        .setAutoCancel(true)
2160                        .setTicker(text)
2161                        .setColor(mContext.getColor(
2162                                com.android.internal.R.color.system_notification_accent_color))
2163                        .setContentTitle(text)
2164                        .setContentText(
2165                                mContext.getText(R.string.dump_heap_notification_detail))
2166                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2167                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2168                                new UserHandle(userId)))
2169                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2170                                deleteIntent, 0, UserHandle.SYSTEM))
2171                        .build();
2172
2173                try {
2174                    int[] outId = new int[1];
2175                    inm.enqueueNotificationWithTag("android", "android", null,
2176                            R.string.dump_heap_notification,
2177                            notification, outId, userId);
2178                } catch (RuntimeException e) {
2179                    Slog.w(ActivityManagerService.TAG,
2180                            "Error showing notification for dump heap", e);
2181                } catch (RemoteException e) {
2182                }
2183            } break;
2184            case DELETE_DUMPHEAP_MSG: {
2185                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2186                        DumpHeapActivity.JAVA_URI,
2187                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2188                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2189                        UserHandle.myUserId());
2190                synchronized (ActivityManagerService.this) {
2191                    mMemWatchDumpFile = null;
2192                    mMemWatchDumpProcName = null;
2193                    mMemWatchDumpPid = -1;
2194                    mMemWatchDumpUid = -1;
2195                }
2196            } break;
2197            case FOREGROUND_PROFILE_CHANGED_MSG: {
2198                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2199            } break;
2200            case REPORT_TIME_TRACKER_MSG: {
2201                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2202                tracker.deliverResult(mContext);
2203            } break;
2204            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2205                mUserController.dispatchUserSwitchComplete(msg.arg1);
2206            } break;
2207            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2208                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2209                try {
2210                    connection.shutdown();
2211                } catch (RemoteException e) {
2212                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2213                }
2214                // Only a UiAutomation can set this flag and now that
2215                // it is finished we make sure it is reset to its default.
2216                mUserIsMonkey = false;
2217            } break;
2218            case APP_BOOST_DEACTIVATE_MSG: {
2219                synchronized(ActivityManagerService.this) {
2220                    if (mIsBoosted) {
2221                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2222                            nativeMigrateFromBoost();
2223                            mIsBoosted = false;
2224                            mBoostStartTime = 0;
2225                        } else {
2226                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2227                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2228                        }
2229                    }
2230                }
2231            } break;
2232            case IDLE_UIDS_MSG: {
2233                idleUids();
2234            } break;
2235            case LOG_STACK_STATE: {
2236                synchronized (ActivityManagerService.this) {
2237                    mStackSupervisor.logStackState();
2238                }
2239            } break;
2240            case VR_MODE_CHANGE_MSG: {
2241                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2242                final ActivityRecord r = (ActivityRecord) msg.obj;
2243                boolean vrMode;
2244                ComponentName requestedPackage;
2245                ComponentName callingPackage;
2246                int userId;
2247                synchronized (ActivityManagerService.this) {
2248                    vrMode = r.requestedVrComponent != null;
2249                    requestedPackage = r.requestedVrComponent;
2250                    userId = r.userId;
2251                    callingPackage = r.info.getComponentName();
2252                    if (mInVrMode != vrMode) {
2253                        mInVrMode = vrMode;
2254                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2255                    }
2256                }
2257                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2258            } break;
2259            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2260                final ActivityRecord r = (ActivityRecord) msg.obj;
2261                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2262                if (needsVrMode) {
2263                    VrManagerInternal vrService =
2264                            LocalServices.getService(VrManagerInternal.class);
2265                    boolean enable = msg.arg1 == 1;
2266                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2267                            r.info.getComponentName());
2268                }
2269            } break;
2270            }
2271        }
2272    };
2273
2274    static final int COLLECT_PSS_BG_MSG = 1;
2275
2276    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2277        @Override
2278        public void handleMessage(Message msg) {
2279            switch (msg.what) {
2280            case COLLECT_PSS_BG_MSG: {
2281                long start = SystemClock.uptimeMillis();
2282                MemInfoReader memInfo = null;
2283                synchronized (ActivityManagerService.this) {
2284                    if (mFullPssPending) {
2285                        mFullPssPending = false;
2286                        memInfo = new MemInfoReader();
2287                    }
2288                }
2289                if (memInfo != null) {
2290                    updateCpuStatsNow();
2291                    long nativeTotalPss = 0;
2292                    synchronized (mProcessCpuTracker) {
2293                        final int N = mProcessCpuTracker.countStats();
2294                        for (int j=0; j<N; j++) {
2295                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2296                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2297                                // This is definitely an application process; skip it.
2298                                continue;
2299                            }
2300                            synchronized (mPidsSelfLocked) {
2301                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2302                                    // This is one of our own processes; skip it.
2303                                    continue;
2304                                }
2305                            }
2306                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2307                        }
2308                    }
2309                    memInfo.readMemInfo();
2310                    synchronized (ActivityManagerService.this) {
2311                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2312                                + (SystemClock.uptimeMillis()-start) + "ms");
2313                        final long cachedKb = memInfo.getCachedSizeKb();
2314                        final long freeKb = memInfo.getFreeSizeKb();
2315                        final long zramKb = memInfo.getZramTotalSizeKb();
2316                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2317                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2318                                kernelKb*1024, nativeTotalPss*1024);
2319                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2320                                nativeTotalPss);
2321                    }
2322                }
2323
2324                int num = 0;
2325                long[] tmp = new long[2];
2326                do {
2327                    ProcessRecord proc;
2328                    int procState;
2329                    int pid;
2330                    long lastPssTime;
2331                    synchronized (ActivityManagerService.this) {
2332                        if (mPendingPssProcesses.size() <= 0) {
2333                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2334                                    "Collected PSS of " + num + " processes in "
2335                                    + (SystemClock.uptimeMillis() - start) + "ms");
2336                            mPendingPssProcesses.clear();
2337                            return;
2338                        }
2339                        proc = mPendingPssProcesses.remove(0);
2340                        procState = proc.pssProcState;
2341                        lastPssTime = proc.lastPssTime;
2342                        if (proc.thread != null && procState == proc.setProcState
2343                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2344                                        < SystemClock.uptimeMillis()) {
2345                            pid = proc.pid;
2346                        } else {
2347                            proc = null;
2348                            pid = 0;
2349                        }
2350                    }
2351                    if (proc != null) {
2352                        long pss = Debug.getPss(pid, tmp, null);
2353                        synchronized (ActivityManagerService.this) {
2354                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2355                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2356                                num++;
2357                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2358                                        SystemClock.uptimeMillis());
2359                            }
2360                        }
2361                    }
2362                } while (true);
2363            }
2364            }
2365        }
2366    };
2367
2368    public void setSystemProcess() {
2369        try {
2370            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2371            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2372            ServiceManager.addService("meminfo", new MemBinder(this));
2373            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2374            ServiceManager.addService("dbinfo", new DbBinder(this));
2375            if (MONITOR_CPU_USAGE) {
2376                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2377            }
2378            ServiceManager.addService("permission", new PermissionController(this));
2379            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2380
2381            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2382                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2383            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2384
2385            synchronized (this) {
2386                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2387                app.persistent = true;
2388                app.pid = MY_PID;
2389                app.maxAdj = ProcessList.SYSTEM_ADJ;
2390                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2391                synchronized (mPidsSelfLocked) {
2392                    mPidsSelfLocked.put(app.pid, app);
2393                }
2394                updateLruProcessLocked(app, false, null);
2395                updateOomAdjLocked();
2396            }
2397        } catch (PackageManager.NameNotFoundException e) {
2398            throw new RuntimeException(
2399                    "Unable to find android system package", e);
2400        }
2401    }
2402
2403    public void setWindowManager(WindowManagerService wm) {
2404        mWindowManager = wm;
2405        mStackSupervisor.setWindowManager(wm);
2406        mActivityStarter.setWindowManager(wm);
2407    }
2408
2409    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2410        mUsageStatsService = usageStatsManager;
2411    }
2412
2413    public void startObservingNativeCrashes() {
2414        final NativeCrashListener ncl = new NativeCrashListener(this);
2415        ncl.start();
2416    }
2417
2418    public IAppOpsService getAppOpsService() {
2419        return mAppOpsService;
2420    }
2421
2422    static class MemBinder extends Binder {
2423        ActivityManagerService mActivityManagerService;
2424        MemBinder(ActivityManagerService activityManagerService) {
2425            mActivityManagerService = activityManagerService;
2426        }
2427
2428        @Override
2429        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2430            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2431                    != PackageManager.PERMISSION_GRANTED) {
2432                pw.println("Permission Denial: can't dump meminfo from from pid="
2433                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2434                        + " without permission " + android.Manifest.permission.DUMP);
2435                return;
2436            }
2437
2438            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2439        }
2440    }
2441
2442    static class GraphicsBinder extends Binder {
2443        ActivityManagerService mActivityManagerService;
2444        GraphicsBinder(ActivityManagerService activityManagerService) {
2445            mActivityManagerService = activityManagerService;
2446        }
2447
2448        @Override
2449        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2450            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2451                    != PackageManager.PERMISSION_GRANTED) {
2452                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2453                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2454                        + " without permission " + android.Manifest.permission.DUMP);
2455                return;
2456            }
2457
2458            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2459        }
2460    }
2461
2462    static class DbBinder extends Binder {
2463        ActivityManagerService mActivityManagerService;
2464        DbBinder(ActivityManagerService activityManagerService) {
2465            mActivityManagerService = activityManagerService;
2466        }
2467
2468        @Override
2469        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2470            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2471                    != PackageManager.PERMISSION_GRANTED) {
2472                pw.println("Permission Denial: can't dump dbinfo from from pid="
2473                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2474                        + " without permission " + android.Manifest.permission.DUMP);
2475                return;
2476            }
2477
2478            mActivityManagerService.dumpDbInfo(fd, pw, args);
2479        }
2480    }
2481
2482    static class CpuBinder extends Binder {
2483        ActivityManagerService mActivityManagerService;
2484        CpuBinder(ActivityManagerService activityManagerService) {
2485            mActivityManagerService = activityManagerService;
2486        }
2487
2488        @Override
2489        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2490            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2491                    != PackageManager.PERMISSION_GRANTED) {
2492                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2493                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2494                        + " without permission " + android.Manifest.permission.DUMP);
2495                return;
2496            }
2497
2498            synchronized (mActivityManagerService.mProcessCpuTracker) {
2499                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2500                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2501                        SystemClock.uptimeMillis()));
2502            }
2503        }
2504    }
2505
2506    public static final class Lifecycle extends SystemService {
2507        private final ActivityManagerService mService;
2508
2509        public Lifecycle(Context context) {
2510            super(context);
2511            mService = new ActivityManagerService(context);
2512        }
2513
2514        @Override
2515        public void onStart() {
2516            mService.start();
2517        }
2518
2519        public ActivityManagerService getService() {
2520            return mService;
2521        }
2522    }
2523
2524    // Note: This method is invoked on the main thread but may need to attach various
2525    // handlers to other threads.  So take care to be explicit about the looper.
2526    public ActivityManagerService(Context systemContext) {
2527        mContext = systemContext;
2528        mFactoryTest = FactoryTest.getMode();
2529        mSystemThread = ActivityThread.currentActivityThread();
2530
2531        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2532
2533        mHandlerThread = new ServiceThread(TAG,
2534                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2535        mHandlerThread.start();
2536        mHandler = new MainHandler(mHandlerThread.getLooper());
2537        mUiHandler = new UiHandler();
2538
2539        /* static; one-time init here */
2540        if (sKillHandler == null) {
2541            sKillThread = new ServiceThread(TAG + ":kill",
2542                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2543            sKillThread.start();
2544            sKillHandler = new KillHandler(sKillThread.getLooper());
2545        }
2546
2547        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2548                "foreground", BROADCAST_FG_TIMEOUT, false);
2549        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2550                "background", BROADCAST_BG_TIMEOUT, true);
2551        mBroadcastQueues[0] = mFgBroadcastQueue;
2552        mBroadcastQueues[1] = mBgBroadcastQueue;
2553
2554        mServices = new ActiveServices(this);
2555        mProviderMap = new ProviderMap(this);
2556        mAppErrors = new AppErrors(mContext, this);
2557
2558        // TODO: Move creation of battery stats service outside of activity manager service.
2559        File dataDir = Environment.getDataDirectory();
2560        File systemDir = new File(dataDir, "system");
2561        systemDir.mkdirs();
2562        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2563        mBatteryStatsService.getActiveStatistics().readLocked();
2564        mBatteryStatsService.scheduleWriteToDisk();
2565        mOnBattery = DEBUG_POWER ? true
2566                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2567        mBatteryStatsService.getActiveStatistics().setCallback(this);
2568
2569        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2570
2571        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2572        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2573                new IAppOpsCallback.Stub() {
2574                    @Override public void opChanged(int op, int uid, String packageName) {
2575                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2576                            if (mAppOpsService.checkOperation(op, uid, packageName)
2577                                    != AppOpsManager.MODE_ALLOWED) {
2578                                runInBackgroundDisabled(uid);
2579                            }
2580                        }
2581                    }
2582                });
2583
2584        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2585
2586        mUserController = new UserController(this);
2587
2588        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2589            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2590
2591        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2592
2593        mConfiguration.setToDefaults();
2594        mConfiguration.setLocales(LocaleList.getDefault());
2595
2596        mConfigurationSeq = mConfiguration.seq = 1;
2597        mProcessCpuTracker.init();
2598
2599        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2600        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2601        mStackSupervisor = new ActivityStackSupervisor(this);
2602        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2603        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2604
2605        mProcessCpuThread = new Thread("CpuTracker") {
2606            @Override
2607            public void run() {
2608                while (true) {
2609                    try {
2610                        try {
2611                            synchronized(this) {
2612                                final long now = SystemClock.uptimeMillis();
2613                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2614                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2615                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2616                                //        + ", write delay=" + nextWriteDelay);
2617                                if (nextWriteDelay < nextCpuDelay) {
2618                                    nextCpuDelay = nextWriteDelay;
2619                                }
2620                                if (nextCpuDelay > 0) {
2621                                    mProcessCpuMutexFree.set(true);
2622                                    this.wait(nextCpuDelay);
2623                                }
2624                            }
2625                        } catch (InterruptedException e) {
2626                        }
2627                        updateCpuStatsNow();
2628                    } catch (Exception e) {
2629                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2630                    }
2631                }
2632            }
2633        };
2634
2635        Watchdog.getInstance().addMonitor(this);
2636        Watchdog.getInstance().addThread(mHandler);
2637    }
2638
2639    public void setSystemServiceManager(SystemServiceManager mgr) {
2640        mSystemServiceManager = mgr;
2641    }
2642
2643    public void setInstaller(Installer installer) {
2644        mInstaller = installer;
2645    }
2646
2647    private void start() {
2648        Process.removeAllProcessGroups();
2649        mProcessCpuThread.start();
2650
2651        mBatteryStatsService.publish(mContext);
2652        mAppOpsService.publish(mContext);
2653        Slog.d("AppOps", "AppOpsService published");
2654        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2655    }
2656
2657    void onUserStoppedLocked(int userId) {
2658        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2659    }
2660
2661    public void initPowerManagement() {
2662        mStackSupervisor.initPowerManagement();
2663        mBatteryStatsService.initPowerManagement();
2664        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2665        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2666        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2667        mVoiceWakeLock.setReferenceCounted(false);
2668    }
2669
2670    @Override
2671    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2672            throws RemoteException {
2673        if (code == SYSPROPS_TRANSACTION) {
2674            // We need to tell all apps about the system property change.
2675            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2676            synchronized(this) {
2677                final int NP = mProcessNames.getMap().size();
2678                for (int ip=0; ip<NP; ip++) {
2679                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2680                    final int NA = apps.size();
2681                    for (int ia=0; ia<NA; ia++) {
2682                        ProcessRecord app = apps.valueAt(ia);
2683                        if (app.thread != null) {
2684                            procs.add(app.thread.asBinder());
2685                        }
2686                    }
2687                }
2688            }
2689
2690            int N = procs.size();
2691            for (int i=0; i<N; i++) {
2692                Parcel data2 = Parcel.obtain();
2693                try {
2694                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2695                } catch (RemoteException e) {
2696                }
2697                data2.recycle();
2698            }
2699        }
2700        try {
2701            return super.onTransact(code, data, reply, flags);
2702        } catch (RuntimeException e) {
2703            // The activity manager only throws security exceptions, so let's
2704            // log all others.
2705            if (!(e instanceof SecurityException)) {
2706                Slog.wtf(TAG, "Activity Manager Crash", e);
2707            }
2708            throw e;
2709        }
2710    }
2711
2712    void updateCpuStats() {
2713        final long now = SystemClock.uptimeMillis();
2714        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2715            return;
2716        }
2717        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2718            synchronized (mProcessCpuThread) {
2719                mProcessCpuThread.notify();
2720            }
2721        }
2722    }
2723
2724    void updateCpuStatsNow() {
2725        synchronized (mProcessCpuTracker) {
2726            mProcessCpuMutexFree.set(false);
2727            final long now = SystemClock.uptimeMillis();
2728            boolean haveNewCpuStats = false;
2729
2730            if (MONITOR_CPU_USAGE &&
2731                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2732                mLastCpuTime.set(now);
2733                mProcessCpuTracker.update();
2734                if (mProcessCpuTracker.hasGoodLastStats()) {
2735                    haveNewCpuStats = true;
2736                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2737                    //Slog.i(TAG, "Total CPU usage: "
2738                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2739
2740                    // Slog the cpu usage if the property is set.
2741                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2742                        int user = mProcessCpuTracker.getLastUserTime();
2743                        int system = mProcessCpuTracker.getLastSystemTime();
2744                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2745                        int irq = mProcessCpuTracker.getLastIrqTime();
2746                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2747                        int idle = mProcessCpuTracker.getLastIdleTime();
2748
2749                        int total = user + system + iowait + irq + softIrq + idle;
2750                        if (total == 0) total = 1;
2751
2752                        EventLog.writeEvent(EventLogTags.CPU,
2753                                ((user+system+iowait+irq+softIrq) * 100) / total,
2754                                (user * 100) / total,
2755                                (system * 100) / total,
2756                                (iowait * 100) / total,
2757                                (irq * 100) / total,
2758                                (softIrq * 100) / total);
2759                    }
2760                }
2761            }
2762
2763            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2764            synchronized(bstats) {
2765                synchronized(mPidsSelfLocked) {
2766                    if (haveNewCpuStats) {
2767                        if (bstats.startAddingCpuLocked()) {
2768                            int totalUTime = 0;
2769                            int totalSTime = 0;
2770                            final int N = mProcessCpuTracker.countStats();
2771                            for (int i=0; i<N; i++) {
2772                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2773                                if (!st.working) {
2774                                    continue;
2775                                }
2776                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2777                                totalUTime += st.rel_utime;
2778                                totalSTime += st.rel_stime;
2779                                if (pr != null) {
2780                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2781                                    if (ps == null || !ps.isActive()) {
2782                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2783                                                pr.info.uid, pr.processName);
2784                                    }
2785                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2786                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2787                                } else {
2788                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2789                                    if (ps == null || !ps.isActive()) {
2790                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2791                                                bstats.mapUid(st.uid), st.name);
2792                                    }
2793                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2794                                }
2795                            }
2796                            final int userTime = mProcessCpuTracker.getLastUserTime();
2797                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2798                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2799                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2800                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2801                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2802                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2803                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2804                        }
2805                    }
2806                }
2807
2808                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2809                    mLastWriteTime = now;
2810                    mBatteryStatsService.scheduleWriteToDisk();
2811                }
2812            }
2813        }
2814    }
2815
2816    @Override
2817    public void batteryNeedsCpuUpdate() {
2818        updateCpuStatsNow();
2819    }
2820
2821    @Override
2822    public void batteryPowerChanged(boolean onBattery) {
2823        // When plugging in, update the CPU stats first before changing
2824        // the plug state.
2825        updateCpuStatsNow();
2826        synchronized (this) {
2827            synchronized(mPidsSelfLocked) {
2828                mOnBattery = DEBUG_POWER ? true : onBattery;
2829            }
2830        }
2831    }
2832
2833    @Override
2834    public void batterySendBroadcast(Intent intent) {
2835        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2836                AppOpsManager.OP_NONE, null, false, false,
2837                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2838    }
2839
2840    /**
2841     * Initialize the application bind args. These are passed to each
2842     * process when the bindApplication() IPC is sent to the process. They're
2843     * lazily setup to make sure the services are running when they're asked for.
2844     */
2845    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2846        if (mAppBindArgs == null) {
2847            mAppBindArgs = new HashMap<>();
2848
2849            // Isolated processes won't get this optimization, so that we don't
2850            // violate the rules about which services they have access to.
2851            if (!isolated) {
2852                // Setup the application init args
2853                mAppBindArgs.put("package", ServiceManager.getService("package"));
2854                mAppBindArgs.put("window", ServiceManager.getService("window"));
2855                mAppBindArgs.put(Context.ALARM_SERVICE,
2856                        ServiceManager.getService(Context.ALARM_SERVICE));
2857            }
2858        }
2859        return mAppBindArgs;
2860    }
2861
2862    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2863        if (r == null || mFocusedActivity == r) {
2864            return false;
2865        }
2866
2867        if (!r.isFocusable()) {
2868            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2869            return false;
2870        }
2871
2872        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2873
2874        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2875        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2876                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2877        mDoingSetFocusedActivity = true;
2878
2879        final ActivityRecord last = mFocusedActivity;
2880        mFocusedActivity = r;
2881        if (r.task.isApplicationTask()) {
2882            if (mCurAppTimeTracker != r.appTimeTracker) {
2883                // We are switching app tracking.  Complete the current one.
2884                if (mCurAppTimeTracker != null) {
2885                    mCurAppTimeTracker.stop();
2886                    mHandler.obtainMessage(
2887                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2888                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2889                    mCurAppTimeTracker = null;
2890                }
2891                if (r.appTimeTracker != null) {
2892                    mCurAppTimeTracker = r.appTimeTracker;
2893                    startTimeTrackingFocusedActivityLocked();
2894                }
2895            } else {
2896                startTimeTrackingFocusedActivityLocked();
2897            }
2898        } else {
2899            r.appTimeTracker = null;
2900        }
2901        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2902        // TODO: Probably not, because we don't want to resume voice on switching
2903        // back to this activity
2904        if (r.task.voiceInteractor != null) {
2905            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2906        } else {
2907            finishRunningVoiceLocked();
2908            IVoiceInteractionSession session;
2909            if (last != null && ((session = last.task.voiceSession) != null
2910                    || (session = last.voiceSession) != null)) {
2911                // We had been in a voice interaction session, but now focused has
2912                // move to something different.  Just finish the session, we can't
2913                // return to it and retain the proper state and synchronization with
2914                // the voice interaction service.
2915                finishVoiceTask(session);
2916            }
2917        }
2918        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2919            mWindowManager.setFocusedApp(r.appToken, true);
2920        }
2921        applyUpdateLockStateLocked(r);
2922        applyUpdateVrModeLocked(r);
2923        if (mFocusedActivity.userId != mLastFocusedUserId) {
2924            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2925            mHandler.obtainMessage(
2926                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2927            mLastFocusedUserId = mFocusedActivity.userId;
2928        }
2929
2930        // Log a warning if the focused app is changed during the process. This could
2931        // indicate a problem of the focus setting logic!
2932        if (mFocusedActivity != r) Slog.w(TAG,
2933                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2934        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2935
2936        EventLogTags.writeAmFocusedActivity(
2937                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2938                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2939                reason);
2940        return true;
2941    }
2942
2943    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2944        if (mFocusedActivity != goingAway) {
2945            return;
2946        }
2947
2948        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2949        if (focusedStack != null) {
2950            final ActivityRecord top = focusedStack.topActivity();
2951            if (top != null && top.userId != mLastFocusedUserId) {
2952                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2953                mHandler.sendMessage(
2954                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2955                mLastFocusedUserId = top.userId;
2956            }
2957        }
2958
2959        // Try to move focus to another activity if possible.
2960        if (setFocusedActivityLocked(
2961                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2962            return;
2963        }
2964
2965        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2966                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2967        mFocusedActivity = null;
2968        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2969    }
2970
2971    @Override
2972    public void setFocusedStack(int stackId) {
2973        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2974        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2975        final long callingId = Binder.clearCallingIdentity();
2976        try {
2977            synchronized (this) {
2978                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2979                if (stack == null) {
2980                    return;
2981                }
2982                final ActivityRecord r = stack.topRunningActivityLocked();
2983                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2984                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2985                }
2986            }
2987        } finally {
2988            Binder.restoreCallingIdentity(callingId);
2989        }
2990    }
2991
2992    @Override
2993    public void setFocusedTask(int taskId) {
2994        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2995        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2996        final long callingId = Binder.clearCallingIdentity();
2997        try {
2998            synchronized (this) {
2999                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3000                if (task == null) {
3001                    return;
3002                }
3003                final ActivityRecord r = task.topRunningActivityLocked();
3004                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3005                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3006                }
3007            }
3008        } finally {
3009            Binder.restoreCallingIdentity(callingId);
3010        }
3011    }
3012
3013    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3014    @Override
3015    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3016        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3017        synchronized (this) {
3018            if (listener != null) {
3019                mTaskStackListeners.register(listener);
3020            }
3021        }
3022    }
3023
3024    @Override
3025    public void notifyActivityDrawn(IBinder token) {
3026        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3027        synchronized (this) {
3028            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3029            if (r != null) {
3030                r.task.stack.notifyActivityDrawnLocked(r);
3031            }
3032        }
3033    }
3034
3035    final void applyUpdateLockStateLocked(ActivityRecord r) {
3036        // Modifications to the UpdateLock state are done on our handler, outside
3037        // the activity manager's locks.  The new state is determined based on the
3038        // state *now* of the relevant activity record.  The object is passed to
3039        // the handler solely for logging detail, not to be consulted/modified.
3040        final boolean nextState = r != null && r.immersive;
3041        mHandler.sendMessage(
3042                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3043    }
3044
3045    final void applyUpdateVrModeLocked(ActivityRecord r) {
3046        mHandler.sendMessage(
3047                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3048    }
3049
3050    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3051        mHandler.sendMessage(
3052                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3053    }
3054
3055    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3056        Message msg = Message.obtain();
3057        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3058        msg.obj = r.task.askedCompatMode ? null : r;
3059        mUiHandler.sendMessage(msg);
3060    }
3061
3062    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3063            String what, Object obj, ProcessRecord srcApp) {
3064        app.lastActivityTime = now;
3065
3066        if (app.activities.size() > 0) {
3067            // Don't want to touch dependent processes that are hosting activities.
3068            return index;
3069        }
3070
3071        int lrui = mLruProcesses.lastIndexOf(app);
3072        if (lrui < 0) {
3073            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3074                    + what + " " + obj + " from " + srcApp);
3075            return index;
3076        }
3077
3078        if (lrui >= index) {
3079            // Don't want to cause this to move dependent processes *back* in the
3080            // list as if they were less frequently used.
3081            return index;
3082        }
3083
3084        if (lrui >= mLruProcessActivityStart) {
3085            // Don't want to touch dependent processes that are hosting activities.
3086            return index;
3087        }
3088
3089        mLruProcesses.remove(lrui);
3090        if (index > 0) {
3091            index--;
3092        }
3093        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3094                + " in LRU list: " + app);
3095        mLruProcesses.add(index, app);
3096        return index;
3097    }
3098
3099    static void killProcessGroup(int uid, int pid) {
3100        if (sKillHandler != null) {
3101            sKillHandler.sendMessage(
3102                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3103        } else {
3104            Slog.w(TAG, "Asked to kill process group before system bringup!");
3105            Process.killProcessGroup(uid, pid);
3106        }
3107    }
3108
3109    final void removeLruProcessLocked(ProcessRecord app) {
3110        int lrui = mLruProcesses.lastIndexOf(app);
3111        if (lrui >= 0) {
3112            if (!app.killed) {
3113                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3114                Process.killProcessQuiet(app.pid);
3115                killProcessGroup(app.uid, app.pid);
3116            }
3117            if (lrui <= mLruProcessActivityStart) {
3118                mLruProcessActivityStart--;
3119            }
3120            if (lrui <= mLruProcessServiceStart) {
3121                mLruProcessServiceStart--;
3122            }
3123            mLruProcesses.remove(lrui);
3124        }
3125    }
3126
3127    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3128            ProcessRecord client) {
3129        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3130                || app.treatLikeActivity;
3131        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3132        if (!activityChange && hasActivity) {
3133            // The process has activities, so we are only allowing activity-based adjustments
3134            // to move it.  It should be kept in the front of the list with other
3135            // processes that have activities, and we don't want those to change their
3136            // order except due to activity operations.
3137            return;
3138        }
3139
3140        mLruSeq++;
3141        final long now = SystemClock.uptimeMillis();
3142        app.lastActivityTime = now;
3143
3144        // First a quick reject: if the app is already at the position we will
3145        // put it, then there is nothing to do.
3146        if (hasActivity) {
3147            final int N = mLruProcesses.size();
3148            if (N > 0 && mLruProcesses.get(N-1) == app) {
3149                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3150                return;
3151            }
3152        } else {
3153            if (mLruProcessServiceStart > 0
3154                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3155                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3156                return;
3157            }
3158        }
3159
3160        int lrui = mLruProcesses.lastIndexOf(app);
3161
3162        if (app.persistent && lrui >= 0) {
3163            // We don't care about the position of persistent processes, as long as
3164            // they are in the list.
3165            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3166            return;
3167        }
3168
3169        /* In progress: compute new position first, so we can avoid doing work
3170           if the process is not actually going to move.  Not yet working.
3171        int addIndex;
3172        int nextIndex;
3173        boolean inActivity = false, inService = false;
3174        if (hasActivity) {
3175            // Process has activities, put it at the very tipsy-top.
3176            addIndex = mLruProcesses.size();
3177            nextIndex = mLruProcessServiceStart;
3178            inActivity = true;
3179        } else if (hasService) {
3180            // Process has services, put it at the top of the service list.
3181            addIndex = mLruProcessActivityStart;
3182            nextIndex = mLruProcessServiceStart;
3183            inActivity = true;
3184            inService = true;
3185        } else  {
3186            // Process not otherwise of interest, it goes to the top of the non-service area.
3187            addIndex = mLruProcessServiceStart;
3188            if (client != null) {
3189                int clientIndex = mLruProcesses.lastIndexOf(client);
3190                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3191                        + app);
3192                if (clientIndex >= 0 && addIndex > clientIndex) {
3193                    addIndex = clientIndex;
3194                }
3195            }
3196            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3197        }
3198
3199        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3200                + mLruProcessActivityStart + "): " + app);
3201        */
3202
3203        if (lrui >= 0) {
3204            if (lrui < mLruProcessActivityStart) {
3205                mLruProcessActivityStart--;
3206            }
3207            if (lrui < mLruProcessServiceStart) {
3208                mLruProcessServiceStart--;
3209            }
3210            /*
3211            if (addIndex > lrui) {
3212                addIndex--;
3213            }
3214            if (nextIndex > lrui) {
3215                nextIndex--;
3216            }
3217            */
3218            mLruProcesses.remove(lrui);
3219        }
3220
3221        /*
3222        mLruProcesses.add(addIndex, app);
3223        if (inActivity) {
3224            mLruProcessActivityStart++;
3225        }
3226        if (inService) {
3227            mLruProcessActivityStart++;
3228        }
3229        */
3230
3231        int nextIndex;
3232        if (hasActivity) {
3233            final int N = mLruProcesses.size();
3234            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3235                // Process doesn't have activities, but has clients with
3236                // activities...  move it up, but one below the top (the top
3237                // should always have a real activity).
3238                if (DEBUG_LRU) Slog.d(TAG_LRU,
3239                        "Adding to second-top of LRU activity list: " + app);
3240                mLruProcesses.add(N - 1, app);
3241                // To keep it from spamming the LRU list (by making a bunch of clients),
3242                // we will push down any other entries owned by the app.
3243                final int uid = app.info.uid;
3244                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3245                    ProcessRecord subProc = mLruProcesses.get(i);
3246                    if (subProc.info.uid == uid) {
3247                        // We want to push this one down the list.  If the process after
3248                        // it is for the same uid, however, don't do so, because we don't
3249                        // want them internally to be re-ordered.
3250                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3251                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3252                                    "Pushing uid " + uid + " swapping at " + i + ": "
3253                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3254                            ProcessRecord tmp = mLruProcesses.get(i);
3255                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3256                            mLruProcesses.set(i - 1, tmp);
3257                            i--;
3258                        }
3259                    } else {
3260                        // A gap, we can stop here.
3261                        break;
3262                    }
3263                }
3264            } else {
3265                // Process has activities, put it at the very tipsy-top.
3266                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3267                mLruProcesses.add(app);
3268            }
3269            nextIndex = mLruProcessServiceStart;
3270        } else if (hasService) {
3271            // Process has services, put it at the top of the service list.
3272            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3273            mLruProcesses.add(mLruProcessActivityStart, app);
3274            nextIndex = mLruProcessServiceStart;
3275            mLruProcessActivityStart++;
3276        } else  {
3277            // Process not otherwise of interest, it goes to the top of the non-service area.
3278            int index = mLruProcessServiceStart;
3279            if (client != null) {
3280                // If there is a client, don't allow the process to be moved up higher
3281                // in the list than that client.
3282                int clientIndex = mLruProcesses.lastIndexOf(client);
3283                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3284                        + " when updating " + app);
3285                if (clientIndex <= lrui) {
3286                    // Don't allow the client index restriction to push it down farther in the
3287                    // list than it already is.
3288                    clientIndex = lrui;
3289                }
3290                if (clientIndex >= 0 && index > clientIndex) {
3291                    index = clientIndex;
3292                }
3293            }
3294            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3295            mLruProcesses.add(index, app);
3296            nextIndex = index-1;
3297            mLruProcessActivityStart++;
3298            mLruProcessServiceStart++;
3299        }
3300
3301        // If the app is currently using a content provider or service,
3302        // bump those processes as well.
3303        for (int j=app.connections.size()-1; j>=0; j--) {
3304            ConnectionRecord cr = app.connections.valueAt(j);
3305            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3306                    && cr.binding.service.app != null
3307                    && cr.binding.service.app.lruSeq != mLruSeq
3308                    && !cr.binding.service.app.persistent) {
3309                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3310                        "service connection", cr, app);
3311            }
3312        }
3313        for (int j=app.conProviders.size()-1; j>=0; j--) {
3314            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3315            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3316                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3317                        "provider reference", cpr, app);
3318            }
3319        }
3320    }
3321
3322    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3323        if (uid == Process.SYSTEM_UID) {
3324            // The system gets to run in any process.  If there are multiple
3325            // processes with the same uid, just pick the first (this
3326            // should never happen).
3327            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3328            if (procs == null) return null;
3329            final int procCount = procs.size();
3330            for (int i = 0; i < procCount; i++) {
3331                final int procUid = procs.keyAt(i);
3332                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3333                    // Don't use an app process or different user process for system component.
3334                    continue;
3335                }
3336                return procs.valueAt(i);
3337            }
3338        }
3339        ProcessRecord proc = mProcessNames.get(processName, uid);
3340        if (false && proc != null && !keepIfLarge
3341                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3342                && proc.lastCachedPss >= 4000) {
3343            // Turn this condition on to cause killing to happen regularly, for testing.
3344            if (proc.baseProcessTracker != null) {
3345                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3346            }
3347            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3348        } else if (proc != null && !keepIfLarge
3349                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3350                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3351            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3352            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3353                if (proc.baseProcessTracker != null) {
3354                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3355                }
3356                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3357            }
3358        }
3359        return proc;
3360    }
3361
3362    void notifyPackageUse(String packageName, int reason) {
3363        IPackageManager pm = AppGlobals.getPackageManager();
3364        try {
3365            pm.notifyPackageUse(packageName, reason);
3366        } catch (RemoteException e) {
3367        }
3368    }
3369
3370    boolean isNextTransitionForward() {
3371        int transit = mWindowManager.getPendingAppTransition();
3372        return transit == TRANSIT_ACTIVITY_OPEN
3373                || transit == TRANSIT_TASK_OPEN
3374                || transit == TRANSIT_TASK_TO_FRONT;
3375    }
3376
3377    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3378            String processName, String abiOverride, int uid, Runnable crashHandler) {
3379        synchronized(this) {
3380            ApplicationInfo info = new ApplicationInfo();
3381            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3382            // For isolated processes, the former contains the parent's uid and the latter the
3383            // actual uid of the isolated process.
3384            // In the special case introduced by this method (which is, starting an isolated
3385            // process directly from the SystemServer without an actual parent app process) the
3386            // closest thing to a parent's uid is SYSTEM_UID.
3387            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3388            // the |isolated| logic in the ProcessRecord constructor.
3389            info.uid = Process.SYSTEM_UID;
3390            info.processName = processName;
3391            info.className = entryPoint;
3392            info.packageName = "android";
3393            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3394                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3395                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3396                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3397                    crashHandler);
3398            return proc != null ? proc.pid : 0;
3399        }
3400    }
3401
3402    final ProcessRecord startProcessLocked(String processName,
3403            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3404            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3405            boolean isolated, boolean keepIfLarge) {
3406        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3407                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3408                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3409                null /* crashHandler */);
3410    }
3411
3412    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3413            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3414            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3415            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3416        long startTime = SystemClock.elapsedRealtime();
3417        ProcessRecord app;
3418        if (!isolated) {
3419            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3420            checkTime(startTime, "startProcess: after getProcessRecord");
3421
3422            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3423                // If we are in the background, then check to see if this process
3424                // is bad.  If so, we will just silently fail.
3425                if (mAppErrors.isBadProcessLocked(info)) {
3426                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3427                            + "/" + info.processName);
3428                    return null;
3429                }
3430            } else {
3431                // When the user is explicitly starting a process, then clear its
3432                // crash count so that we won't make it bad until they see at
3433                // least one crash dialog again, and make the process good again
3434                // if it had been bad.
3435                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3436                        + "/" + info.processName);
3437                mAppErrors.resetProcessCrashTimeLocked(info);
3438                if (mAppErrors.isBadProcessLocked(info)) {
3439                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3440                            UserHandle.getUserId(info.uid), info.uid,
3441                            info.processName);
3442                    mAppErrors.clearBadProcessLocked(info);
3443                    if (app != null) {
3444                        app.bad = false;
3445                    }
3446                }
3447            }
3448        } else {
3449            // If this is an isolated process, it can't re-use an existing process.
3450            app = null;
3451        }
3452
3453        // app launch boost for big.little configurations
3454        // use cpusets to migrate freshly launched tasks to big cores
3455        synchronized(ActivityManagerService.this) {
3456            nativeMigrateToBoost();
3457            mIsBoosted = true;
3458            mBoostStartTime = SystemClock.uptimeMillis();
3459            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3460            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3461        }
3462
3463        // We don't have to do anything more if:
3464        // (1) There is an existing application record; and
3465        // (2) The caller doesn't think it is dead, OR there is no thread
3466        //     object attached to it so we know it couldn't have crashed; and
3467        // (3) There is a pid assigned to it, so it is either starting or
3468        //     already running.
3469        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3470                + " app=" + app + " knownToBeDead=" + knownToBeDead
3471                + " thread=" + (app != null ? app.thread : null)
3472                + " pid=" + (app != null ? app.pid : -1));
3473        if (app != null && app.pid > 0) {
3474            if (!knownToBeDead || app.thread == null) {
3475                // We already have the app running, or are waiting for it to
3476                // come up (we have a pid but not yet its thread), so keep it.
3477                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3478                // If this is a new package in the process, add the package to the list
3479                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3480                checkTime(startTime, "startProcess: done, added package to proc");
3481                return app;
3482            }
3483
3484            // An application record is attached to a previous process,
3485            // clean it up now.
3486            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3487            checkTime(startTime, "startProcess: bad proc running, killing");
3488            killProcessGroup(app.uid, app.pid);
3489            handleAppDiedLocked(app, true, true);
3490            checkTime(startTime, "startProcess: done killing old proc");
3491        }
3492
3493        String hostingNameStr = hostingName != null
3494                ? hostingName.flattenToShortString() : null;
3495
3496        if (app == null) {
3497            checkTime(startTime, "startProcess: creating new process record");
3498            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3499            if (app == null) {
3500                Slog.w(TAG, "Failed making new process record for "
3501                        + processName + "/" + info.uid + " isolated=" + isolated);
3502                return null;
3503            }
3504            app.crashHandler = crashHandler;
3505            checkTime(startTime, "startProcess: done creating new process record");
3506        } else {
3507            // If this is a new package in the process, add the package to the list
3508            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3509            checkTime(startTime, "startProcess: added package to existing proc");
3510        }
3511
3512        // If the system is not ready yet, then hold off on starting this
3513        // process until it is.
3514        if (!mProcessesReady
3515                && !isAllowedWhileBooting(info)
3516                && !allowWhileBooting) {
3517            if (!mProcessesOnHold.contains(app)) {
3518                mProcessesOnHold.add(app);
3519            }
3520            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3521                    "System not ready, putting on hold: " + app);
3522            checkTime(startTime, "startProcess: returning with proc on hold");
3523            return app;
3524        }
3525
3526        checkTime(startTime, "startProcess: stepping in to startProcess");
3527        startProcessLocked(
3528                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3529        checkTime(startTime, "startProcess: done starting proc!");
3530        return (app.pid != 0) ? app : null;
3531    }
3532
3533    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3534        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3535    }
3536
3537    private final void startProcessLocked(ProcessRecord app,
3538            String hostingType, String hostingNameStr) {
3539        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3540                null /* entryPoint */, null /* entryPointArgs */);
3541    }
3542
3543    private final void startProcessLocked(ProcessRecord app, String hostingType,
3544            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3545        long startTime = SystemClock.elapsedRealtime();
3546        if (app.pid > 0 && app.pid != MY_PID) {
3547            checkTime(startTime, "startProcess: removing from pids map");
3548            synchronized (mPidsSelfLocked) {
3549                mPidsSelfLocked.remove(app.pid);
3550                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3551            }
3552            checkTime(startTime, "startProcess: done removing from pids map");
3553            app.setPid(0);
3554        }
3555
3556        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3557                "startProcessLocked removing on hold: " + app);
3558        mProcessesOnHold.remove(app);
3559
3560        checkTime(startTime, "startProcess: starting to update cpu stats");
3561        updateCpuStats();
3562        checkTime(startTime, "startProcess: done updating cpu stats");
3563
3564        try {
3565            try {
3566                final int userId = UserHandle.getUserId(app.uid);
3567                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3568            } catch (RemoteException e) {
3569                throw e.rethrowAsRuntimeException();
3570            }
3571
3572            int uid = app.uid;
3573            int[] gids = null;
3574            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3575            if (!app.isolated) {
3576                int[] permGids = null;
3577                try {
3578                    checkTime(startTime, "startProcess: getting gids from package manager");
3579                    final IPackageManager pm = AppGlobals.getPackageManager();
3580                    permGids = pm.getPackageGids(app.info.packageName,
3581                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3582                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3583                            MountServiceInternal.class);
3584                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3585                            app.info.packageName);
3586                } catch (RemoteException e) {
3587                    throw e.rethrowAsRuntimeException();
3588                }
3589
3590                /*
3591                 * Add shared application and profile GIDs so applications can share some
3592                 * resources like shared libraries and access user-wide resources
3593                 */
3594                if (ArrayUtils.isEmpty(permGids)) {
3595                    gids = new int[2];
3596                } else {
3597                    gids = new int[permGids.length + 2];
3598                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3599                }
3600                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3601                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3602            }
3603            checkTime(startTime, "startProcess: building args");
3604            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3605                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3606                        && mTopComponent != null
3607                        && app.processName.equals(mTopComponent.getPackageName())) {
3608                    uid = 0;
3609                }
3610                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3611                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3612                    uid = 0;
3613                }
3614            }
3615            int debugFlags = 0;
3616            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3617                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3618                // Also turn on CheckJNI for debuggable apps. It's quite
3619                // awkward to turn on otherwise.
3620                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3621            }
3622            // Run the app in safe mode if its manifest requests so or the
3623            // system is booted in safe mode.
3624            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3625                mSafeMode == true) {
3626                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3627            }
3628            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3629                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3630            }
3631            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3632            if ("true".equals(genDebugInfoProperty)) {
3633                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3634            }
3635            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3636                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3637            }
3638            if ("1".equals(SystemProperties.get("debug.assert"))) {
3639                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3640            }
3641            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3642                // Enable all debug flags required by the native debugger.
3643                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3644                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3645                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3646                mNativeDebuggingApp = null;
3647            }
3648
3649            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3650            if (requiredAbi == null) {
3651                requiredAbi = Build.SUPPORTED_ABIS[0];
3652            }
3653
3654            String instructionSet = null;
3655            if (app.info.primaryCpuAbi != null) {
3656                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3657            }
3658
3659            app.gids = gids;
3660            app.requiredAbi = requiredAbi;
3661            app.instructionSet = instructionSet;
3662
3663            // Start the process.  It will either succeed and return a result containing
3664            // the PID of the new process, or else throw a RuntimeException.
3665            boolean isActivityProcess = (entryPoint == null);
3666            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3667            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3668                    app.processName);
3669            checkTime(startTime, "startProcess: asking zygote to start proc");
3670            Process.ProcessStartResult startResult = Process.start(entryPoint,
3671                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3672                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3673                    app.info.dataDir, entryPointArgs);
3674            checkTime(startTime, "startProcess: returned from zygote!");
3675            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3676
3677            if (app.isolated) {
3678                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3679            }
3680            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3681            checkTime(startTime, "startProcess: done updating battery stats");
3682
3683            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3684                    UserHandle.getUserId(uid), startResult.pid, uid,
3685                    app.processName, hostingType,
3686                    hostingNameStr != null ? hostingNameStr : "");
3687
3688            try {
3689                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3690                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3691            } catch (RemoteException ex) {
3692                // Ignore
3693            }
3694
3695            if (app.persistent) {
3696                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3697            }
3698
3699            checkTime(startTime, "startProcess: building log message");
3700            StringBuilder buf = mStringBuilder;
3701            buf.setLength(0);
3702            buf.append("Start proc ");
3703            buf.append(startResult.pid);
3704            buf.append(':');
3705            buf.append(app.processName);
3706            buf.append('/');
3707            UserHandle.formatUid(buf, uid);
3708            if (!isActivityProcess) {
3709                buf.append(" [");
3710                buf.append(entryPoint);
3711                buf.append("]");
3712            }
3713            buf.append(" for ");
3714            buf.append(hostingType);
3715            if (hostingNameStr != null) {
3716                buf.append(" ");
3717                buf.append(hostingNameStr);
3718            }
3719            Slog.i(TAG, buf.toString());
3720            app.setPid(startResult.pid);
3721            app.usingWrapper = startResult.usingWrapper;
3722            app.removed = false;
3723            app.killed = false;
3724            app.killedByAm = false;
3725            checkTime(startTime, "startProcess: starting to update pids map");
3726            synchronized (mPidsSelfLocked) {
3727                this.mPidsSelfLocked.put(startResult.pid, app);
3728                if (isActivityProcess) {
3729                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3730                    msg.obj = app;
3731                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3732                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3733                }
3734            }
3735            checkTime(startTime, "startProcess: done updating pids map");
3736        } catch (RuntimeException e) {
3737            Slog.e(TAG, "Failure starting process " + app.processName, e);
3738
3739            // Something went very wrong while trying to start this process; one
3740            // common case is when the package is frozen due to an active
3741            // upgrade. To recover, clean up any active bookkeeping related to
3742            // starting this process. (We already invoked this method once when
3743            // the package was initially frozen through KILL_APPLICATION_MSG, so
3744            // it doesn't hurt to use it again.)
3745            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3746                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3747        }
3748    }
3749
3750    void updateUsageStats(ActivityRecord component, boolean resumed) {
3751        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3752                "updateUsageStats: comp=" + component + "res=" + resumed);
3753        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3754        if (resumed) {
3755            if (mUsageStatsService != null) {
3756                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3757                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3758            }
3759            synchronized (stats) {
3760                stats.noteActivityResumedLocked(component.app.uid);
3761            }
3762        } else {
3763            if (mUsageStatsService != null) {
3764                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3765                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3766            }
3767            synchronized (stats) {
3768                stats.noteActivityPausedLocked(component.app.uid);
3769            }
3770        }
3771    }
3772
3773    Intent getHomeIntent() {
3774        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3775        intent.setComponent(mTopComponent);
3776        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3777        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3778            intent.addCategory(Intent.CATEGORY_HOME);
3779        }
3780        return intent;
3781    }
3782
3783    boolean startHomeActivityLocked(int userId, String reason) {
3784        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3785                && mTopAction == null) {
3786            // We are running in factory test mode, but unable to find
3787            // the factory test app, so just sit around displaying the
3788            // error message and don't try to start anything.
3789            return false;
3790        }
3791        Intent intent = getHomeIntent();
3792        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3793        if (aInfo != null) {
3794            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3795            // Don't do this if the home app is currently being
3796            // instrumented.
3797            aInfo = new ActivityInfo(aInfo);
3798            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3799            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3800                    aInfo.applicationInfo.uid, true);
3801            if (app == null || app.instrumentationClass == null) {
3802                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3803                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3804            }
3805        } else {
3806            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3807        }
3808
3809        return true;
3810    }
3811
3812    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3813        ActivityInfo ai = null;
3814        ComponentName comp = intent.getComponent();
3815        try {
3816            if (comp != null) {
3817                // Factory test.
3818                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3819            } else {
3820                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3821                        intent,
3822                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3823                        flags, userId);
3824
3825                if (info != null) {
3826                    ai = info.activityInfo;
3827                }
3828            }
3829        } catch (RemoteException e) {
3830            // ignore
3831        }
3832
3833        return ai;
3834    }
3835
3836    /**
3837     * Starts the "new version setup screen" if appropriate.
3838     */
3839    void startSetupActivityLocked() {
3840        // Only do this once per boot.
3841        if (mCheckedForSetup) {
3842            return;
3843        }
3844
3845        // We will show this screen if the current one is a different
3846        // version than the last one shown, and we are not running in
3847        // low-level factory test mode.
3848        final ContentResolver resolver = mContext.getContentResolver();
3849        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3850                Settings.Global.getInt(resolver,
3851                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3852            mCheckedForSetup = true;
3853
3854            // See if we should be showing the platform update setup UI.
3855            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3856            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3857                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3858            if (!ris.isEmpty()) {
3859                final ResolveInfo ri = ris.get(0);
3860                String vers = ri.activityInfo.metaData != null
3861                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3862                        : null;
3863                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3864                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3865                            Intent.METADATA_SETUP_VERSION);
3866                }
3867                String lastVers = Settings.Secure.getString(
3868                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3869                if (vers != null && !vers.equals(lastVers)) {
3870                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3871                    intent.setComponent(new ComponentName(
3872                            ri.activityInfo.packageName, ri.activityInfo.name));
3873                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3874                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3875                            null, 0, 0, 0, null, false, false, null, null, null);
3876                }
3877            }
3878        }
3879    }
3880
3881    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3882        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3883    }
3884
3885    void enforceNotIsolatedCaller(String caller) {
3886        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3887            throw new SecurityException("Isolated process not allowed to call " + caller);
3888        }
3889    }
3890
3891    void enforceShellRestriction(String restriction, int userHandle) {
3892        if (Binder.getCallingUid() == Process.SHELL_UID) {
3893            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3894                throw new SecurityException("Shell does not have permission to access user "
3895                        + userHandle);
3896            }
3897        }
3898    }
3899
3900    @Override
3901    public int getFrontActivityScreenCompatMode() {
3902        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3903        synchronized (this) {
3904            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3905        }
3906    }
3907
3908    @Override
3909    public void setFrontActivityScreenCompatMode(int mode) {
3910        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3911                "setFrontActivityScreenCompatMode");
3912        synchronized (this) {
3913            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3914        }
3915    }
3916
3917    @Override
3918    public int getPackageScreenCompatMode(String packageName) {
3919        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3920        synchronized (this) {
3921            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3922        }
3923    }
3924
3925    @Override
3926    public void setPackageScreenCompatMode(String packageName, int mode) {
3927        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3928                "setPackageScreenCompatMode");
3929        synchronized (this) {
3930            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3931        }
3932    }
3933
3934    @Override
3935    public boolean getPackageAskScreenCompat(String packageName) {
3936        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3937        synchronized (this) {
3938            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3939        }
3940    }
3941
3942    @Override
3943    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3944        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3945                "setPackageAskScreenCompat");
3946        synchronized (this) {
3947            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3948        }
3949    }
3950
3951    private boolean hasUsageStatsPermission(String callingPackage) {
3952        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3953                Binder.getCallingUid(), callingPackage);
3954        if (mode == AppOpsManager.MODE_DEFAULT) {
3955            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3956                    == PackageManager.PERMISSION_GRANTED;
3957        }
3958        return mode == AppOpsManager.MODE_ALLOWED;
3959    }
3960
3961    @Override
3962    public int getPackageProcessState(String packageName, String callingPackage) {
3963        if (!hasUsageStatsPermission(callingPackage)) {
3964            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3965                    "getPackageProcessState");
3966        }
3967
3968        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3969        synchronized (this) {
3970            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3971                final ProcessRecord proc = mLruProcesses.get(i);
3972                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3973                        || procState > proc.setProcState) {
3974                    boolean found = false;
3975                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3976                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3977                            procState = proc.setProcState;
3978                            found = true;
3979                        }
3980                    }
3981                    if (proc.pkgDeps != null && !found) {
3982                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3983                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3984                                procState = proc.setProcState;
3985                                break;
3986                            }
3987                        }
3988                    }
3989                }
3990            }
3991        }
3992        return procState;
3993    }
3994
3995    @Override
3996    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3997        synchronized (this) {
3998            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3999            if (app == null) {
4000                return false;
4001            }
4002            if (app.trimMemoryLevel < level && app.thread != null &&
4003                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4004                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4005                try {
4006                    app.thread.scheduleTrimMemory(level);
4007                    app.trimMemoryLevel = level;
4008                    return true;
4009                } catch (RemoteException e) {
4010                    // Fallthrough to failure case.
4011                }
4012            }
4013        }
4014        return false;
4015    }
4016
4017    private void dispatchProcessesChanged() {
4018        int N;
4019        synchronized (this) {
4020            N = mPendingProcessChanges.size();
4021            if (mActiveProcessChanges.length < N) {
4022                mActiveProcessChanges = new ProcessChangeItem[N];
4023            }
4024            mPendingProcessChanges.toArray(mActiveProcessChanges);
4025            mPendingProcessChanges.clear();
4026            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4027                    "*** Delivering " + N + " process changes");
4028        }
4029
4030        int i = mProcessObservers.beginBroadcast();
4031        while (i > 0) {
4032            i--;
4033            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4034            if (observer != null) {
4035                try {
4036                    for (int j=0; j<N; j++) {
4037                        ProcessChangeItem item = mActiveProcessChanges[j];
4038                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4039                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4040                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4041                                    + item.uid + ": " + item.foregroundActivities);
4042                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4043                                    item.foregroundActivities);
4044                        }
4045                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4046                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4047                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4048                                    + ": " + item.processState);
4049                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4050                        }
4051                    }
4052                } catch (RemoteException e) {
4053                }
4054            }
4055        }
4056        mProcessObservers.finishBroadcast();
4057
4058        synchronized (this) {
4059            for (int j=0; j<N; j++) {
4060                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4061            }
4062        }
4063    }
4064
4065    private void dispatchProcessDied(int pid, int uid) {
4066        int i = mProcessObservers.beginBroadcast();
4067        while (i > 0) {
4068            i--;
4069            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4070            if (observer != null) {
4071                try {
4072                    observer.onProcessDied(pid, uid);
4073                } catch (RemoteException e) {
4074                }
4075            }
4076        }
4077        mProcessObservers.finishBroadcast();
4078    }
4079
4080    private void dispatchUidsChanged() {
4081        int N;
4082        synchronized (this) {
4083            N = mPendingUidChanges.size();
4084            if (mActiveUidChanges.length < N) {
4085                mActiveUidChanges = new UidRecord.ChangeItem[N];
4086            }
4087            for (int i=0; i<N; i++) {
4088                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4089                mActiveUidChanges[i] = change;
4090                if (change.uidRecord != null) {
4091                    change.uidRecord.pendingChange = null;
4092                    change.uidRecord = null;
4093                }
4094            }
4095            mPendingUidChanges.clear();
4096            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4097                    "*** Delivering " + N + " uid changes");
4098        }
4099
4100        if (mLocalPowerManager != null) {
4101            for (int j=0; j<N; j++) {
4102                UidRecord.ChangeItem item = mActiveUidChanges[j];
4103                if (item.change == UidRecord.CHANGE_GONE
4104                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4105                    mLocalPowerManager.uidGone(item.uid);
4106                } else {
4107                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4108                }
4109            }
4110        }
4111
4112        int i = mUidObservers.beginBroadcast();
4113        while (i > 0) {
4114            i--;
4115            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4116            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4117            if (observer != null) {
4118                try {
4119                    for (int j=0; j<N; j++) {
4120                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4121                        final int change = item.change;
4122                        UidRecord validateUid = null;
4123                        if (VALIDATE_UID_STATES && i == 0) {
4124                            validateUid = mValidateUids.get(item.uid);
4125                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4126                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4127                                validateUid = new UidRecord(item.uid);
4128                                mValidateUids.put(item.uid, validateUid);
4129                            }
4130                        }
4131                        if (change == UidRecord.CHANGE_IDLE
4132                                || change == UidRecord.CHANGE_GONE_IDLE) {
4133                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4134                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4135                                        "UID idle uid=" + item.uid);
4136                                observer.onUidIdle(item.uid);
4137                            }
4138                            if (VALIDATE_UID_STATES && i == 0) {
4139                                if (validateUid != null) {
4140                                    validateUid.idle = true;
4141                                }
4142                            }
4143                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4144                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4145                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4146                                        "UID active uid=" + item.uid);
4147                                observer.onUidActive(item.uid);
4148                            }
4149                            if (VALIDATE_UID_STATES && i == 0) {
4150                                validateUid.idle = false;
4151                            }
4152                        }
4153                        if (change == UidRecord.CHANGE_GONE
4154                                || change == UidRecord.CHANGE_GONE_IDLE) {
4155                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4156                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4157                                        "UID gone uid=" + item.uid);
4158                                observer.onUidGone(item.uid);
4159                            }
4160                            if (VALIDATE_UID_STATES && i == 0) {
4161                                if (validateUid != null) {
4162                                    mValidateUids.remove(item.uid);
4163                                }
4164                            }
4165                        } else {
4166                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4167                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4168                                        "UID CHANGED uid=" + item.uid
4169                                                + ": " + item.processState);
4170                                observer.onUidStateChanged(item.uid, item.processState);
4171                            }
4172                            if (VALIDATE_UID_STATES && i == 0) {
4173                                validateUid.curProcState = validateUid.setProcState
4174                                        = item.processState;
4175                            }
4176                        }
4177                    }
4178                } catch (RemoteException e) {
4179                }
4180            }
4181        }
4182        mUidObservers.finishBroadcast();
4183
4184        synchronized (this) {
4185            for (int j=0; j<N; j++) {
4186                mAvailUidChanges.add(mActiveUidChanges[j]);
4187            }
4188        }
4189    }
4190
4191    @Override
4192    public final int startActivity(IApplicationThread caller, String callingPackage,
4193            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4194            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4195        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4196                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4197                UserHandle.getCallingUserId());
4198    }
4199
4200    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4201        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4202        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4203                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4204                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4205
4206        // TODO: Switch to user app stacks here.
4207        String mimeType = intent.getType();
4208        final Uri data = intent.getData();
4209        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4210            mimeType = getProviderMimeType(data, userId);
4211        }
4212        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4213
4214        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4215        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4216                null, 0, 0, null, null, null, null, false, userId, container, null);
4217    }
4218
4219    @Override
4220    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4221            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4222            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4223        enforceNotIsolatedCaller("startActivity");
4224        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4225                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4226        // TODO: Switch to user app stacks here.
4227        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4228                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4229                profilerInfo, null, null, bOptions, false, userId, null, null);
4230    }
4231
4232    @Override
4233    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4234            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4235            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4236            int userId) {
4237
4238        // This is very dangerous -- it allows you to perform a start activity (including
4239        // permission grants) as any app that may launch one of your own activities.  So
4240        // we will only allow this to be done from activities that are part of the core framework,
4241        // and then only when they are running as the system.
4242        final ActivityRecord sourceRecord;
4243        final int targetUid;
4244        final String targetPackage;
4245        synchronized (this) {
4246            if (resultTo == null) {
4247                throw new SecurityException("Must be called from an activity");
4248            }
4249            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4250            if (sourceRecord == null) {
4251                throw new SecurityException("Called with bad activity token: " + resultTo);
4252            }
4253            if (!sourceRecord.info.packageName.equals("android")) {
4254                throw new SecurityException(
4255                        "Must be called from an activity that is declared in the android package");
4256            }
4257            if (sourceRecord.app == null) {
4258                throw new SecurityException("Called without a process attached to activity");
4259            }
4260            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4261                // This is still okay, as long as this activity is running under the
4262                // uid of the original calling activity.
4263                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4264                    throw new SecurityException(
4265                            "Calling activity in uid " + sourceRecord.app.uid
4266                                    + " must be system uid or original calling uid "
4267                                    + sourceRecord.launchedFromUid);
4268                }
4269            }
4270            if (ignoreTargetSecurity) {
4271                if (intent.getComponent() == null) {
4272                    throw new SecurityException(
4273                            "Component must be specified with ignoreTargetSecurity");
4274                }
4275                if (intent.getSelector() != null) {
4276                    throw new SecurityException(
4277                            "Selector not allowed with ignoreTargetSecurity");
4278                }
4279            }
4280            targetUid = sourceRecord.launchedFromUid;
4281            targetPackage = sourceRecord.launchedFromPackage;
4282        }
4283
4284        if (userId == UserHandle.USER_NULL) {
4285            userId = UserHandle.getUserId(sourceRecord.app.uid);
4286        }
4287
4288        // TODO: Switch to user app stacks here.
4289        try {
4290            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4291                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4292                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4293            return ret;
4294        } catch (SecurityException e) {
4295            // XXX need to figure out how to propagate to original app.
4296            // A SecurityException here is generally actually a fault of the original
4297            // calling activity (such as a fairly granting permissions), so propagate it
4298            // back to them.
4299            /*
4300            StringBuilder msg = new StringBuilder();
4301            msg.append("While launching");
4302            msg.append(intent.toString());
4303            msg.append(": ");
4304            msg.append(e.getMessage());
4305            */
4306            throw e;
4307        }
4308    }
4309
4310    @Override
4311    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4312            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4313            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4314        enforceNotIsolatedCaller("startActivityAndWait");
4315        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4316                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4317        WaitResult res = new WaitResult();
4318        // TODO: Switch to user app stacks here.
4319        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4320                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4321                bOptions, false, userId, null, null);
4322        return res;
4323    }
4324
4325    @Override
4326    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4327            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4328            int startFlags, Configuration config, Bundle bOptions, int userId) {
4329        enforceNotIsolatedCaller("startActivityWithConfig");
4330        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4331                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4332        // TODO: Switch to user app stacks here.
4333        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4334                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4335                null, null, config, bOptions, false, userId, null, null);
4336        return ret;
4337    }
4338
4339    @Override
4340    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4341            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4342            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4343            throws TransactionTooLargeException {
4344        enforceNotIsolatedCaller("startActivityIntentSender");
4345        // Refuse possible leaked file descriptors
4346        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4347            throw new IllegalArgumentException("File descriptors passed in Intent");
4348        }
4349
4350        IIntentSender sender = intent.getTarget();
4351        if (!(sender instanceof PendingIntentRecord)) {
4352            throw new IllegalArgumentException("Bad PendingIntent object");
4353        }
4354
4355        PendingIntentRecord pir = (PendingIntentRecord)sender;
4356
4357        synchronized (this) {
4358            // If this is coming from the currently resumed activity, it is
4359            // effectively saying that app switches are allowed at this point.
4360            final ActivityStack stack = getFocusedStack();
4361            if (stack.mResumedActivity != null &&
4362                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4363                mAppSwitchesAllowedTime = 0;
4364            }
4365        }
4366        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4367                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4368        return ret;
4369    }
4370
4371    @Override
4372    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4373            Intent intent, String resolvedType, IVoiceInteractionSession session,
4374            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4375            Bundle bOptions, int userId) {
4376        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4377                != PackageManager.PERMISSION_GRANTED) {
4378            String msg = "Permission Denial: startVoiceActivity() from pid="
4379                    + Binder.getCallingPid()
4380                    + ", uid=" + Binder.getCallingUid()
4381                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4382            Slog.w(TAG, msg);
4383            throw new SecurityException(msg);
4384        }
4385        if (session == null || interactor == null) {
4386            throw new NullPointerException("null session or interactor");
4387        }
4388        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4389                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4390        // TODO: Switch to user app stacks here.
4391        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4392                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4393                null, bOptions, false, userId, null, null);
4394    }
4395
4396    @Override
4397    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4398            throws RemoteException {
4399        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4400        synchronized (this) {
4401            ActivityRecord activity = getFocusedStack().topActivity();
4402            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4403                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4404            }
4405            if (mRunningVoice != null || activity.task.voiceSession != null
4406                    || activity.voiceSession != null) {
4407                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4408                return;
4409            }
4410            if (activity.pendingVoiceInteractionStart) {
4411                Slog.w(TAG, "Pending start of voice interaction already.");
4412                return;
4413            }
4414            activity.pendingVoiceInteractionStart = true;
4415        }
4416        LocalServices.getService(VoiceInteractionManagerInternal.class)
4417                .startLocalVoiceInteraction(callingActivity, options);
4418    }
4419
4420    @Override
4421    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4422        LocalServices.getService(VoiceInteractionManagerInternal.class)
4423                .stopLocalVoiceInteraction(callingActivity);
4424    }
4425
4426    @Override
4427    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4428        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4429                .supportsLocalVoiceInteraction();
4430    }
4431
4432    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4433            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4434        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4435        if (activityToCallback == null) return;
4436        activityToCallback.setVoiceSessionLocked(voiceSession);
4437
4438        // Inform the activity
4439        try {
4440            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4441                    voiceInteractor);
4442            long token = Binder.clearCallingIdentity();
4443            try {
4444                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4445            } finally {
4446                Binder.restoreCallingIdentity(token);
4447            }
4448            // TODO: VI Should we cache the activity so that it's easier to find later
4449            // rather than scan through all the stacks and activities?
4450        } catch (RemoteException re) {
4451            activityToCallback.clearVoiceSessionLocked();
4452            // TODO: VI Should this terminate the voice session?
4453        }
4454    }
4455
4456    @Override
4457    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4458        synchronized (this) {
4459            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4460                if (keepAwake) {
4461                    mVoiceWakeLock.acquire();
4462                } else {
4463                    mVoiceWakeLock.release();
4464                }
4465            }
4466        }
4467    }
4468
4469    @Override
4470    public boolean startNextMatchingActivity(IBinder callingActivity,
4471            Intent intent, Bundle bOptions) {
4472        // Refuse possible leaked file descriptors
4473        if (intent != null && intent.hasFileDescriptors() == true) {
4474            throw new IllegalArgumentException("File descriptors passed in Intent");
4475        }
4476        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4477
4478        synchronized (this) {
4479            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4480            if (r == null) {
4481                ActivityOptions.abort(options);
4482                return false;
4483            }
4484            if (r.app == null || r.app.thread == null) {
4485                // The caller is not running...  d'oh!
4486                ActivityOptions.abort(options);
4487                return false;
4488            }
4489            intent = new Intent(intent);
4490            // The caller is not allowed to change the data.
4491            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4492            // And we are resetting to find the next component...
4493            intent.setComponent(null);
4494
4495            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4496
4497            ActivityInfo aInfo = null;
4498            try {
4499                List<ResolveInfo> resolves =
4500                    AppGlobals.getPackageManager().queryIntentActivities(
4501                            intent, r.resolvedType,
4502                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4503                            UserHandle.getCallingUserId()).getList();
4504
4505                // Look for the original activity in the list...
4506                final int N = resolves != null ? resolves.size() : 0;
4507                for (int i=0; i<N; i++) {
4508                    ResolveInfo rInfo = resolves.get(i);
4509                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4510                            && rInfo.activityInfo.name.equals(r.info.name)) {
4511                        // We found the current one...  the next matching is
4512                        // after it.
4513                        i++;
4514                        if (i<N) {
4515                            aInfo = resolves.get(i).activityInfo;
4516                        }
4517                        if (debug) {
4518                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4519                                    + "/" + r.info.name);
4520                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4521                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4522                        }
4523                        break;
4524                    }
4525                }
4526            } catch (RemoteException e) {
4527            }
4528
4529            if (aInfo == null) {
4530                // Nobody who is next!
4531                ActivityOptions.abort(options);
4532                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4533                return false;
4534            }
4535
4536            intent.setComponent(new ComponentName(
4537                    aInfo.applicationInfo.packageName, aInfo.name));
4538            intent.setFlags(intent.getFlags()&~(
4539                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4540                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4541                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4542                    Intent.FLAG_ACTIVITY_NEW_TASK));
4543
4544            // Okay now we need to start the new activity, replacing the
4545            // currently running activity.  This is a little tricky because
4546            // we want to start the new one as if the current one is finished,
4547            // but not finish the current one first so that there is no flicker.
4548            // And thus...
4549            final boolean wasFinishing = r.finishing;
4550            r.finishing = true;
4551
4552            // Propagate reply information over to the new activity.
4553            final ActivityRecord resultTo = r.resultTo;
4554            final String resultWho = r.resultWho;
4555            final int requestCode = r.requestCode;
4556            r.resultTo = null;
4557            if (resultTo != null) {
4558                resultTo.removeResultsLocked(r, resultWho, requestCode);
4559            }
4560
4561            final long origId = Binder.clearCallingIdentity();
4562            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4563                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4564                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4565                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4566                    false, false, null, null, null);
4567            Binder.restoreCallingIdentity(origId);
4568
4569            r.finishing = wasFinishing;
4570            if (res != ActivityManager.START_SUCCESS) {
4571                return false;
4572            }
4573            return true;
4574        }
4575    }
4576
4577    @Override
4578    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4579        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4580            String msg = "Permission Denial: startActivityFromRecents called without " +
4581                    START_TASKS_FROM_RECENTS;
4582            Slog.w(TAG, msg);
4583            throw new SecurityException(msg);
4584        }
4585        final long origId = Binder.clearCallingIdentity();
4586        try {
4587            synchronized (this) {
4588                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4589            }
4590        } finally {
4591            Binder.restoreCallingIdentity(origId);
4592        }
4593    }
4594
4595    final int startActivityInPackage(int uid, String callingPackage,
4596            Intent intent, String resolvedType, IBinder resultTo,
4597            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4598            IActivityContainer container, TaskRecord inTask) {
4599
4600        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4601                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4602
4603        // TODO: Switch to user app stacks here.
4604        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4605                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4606                null, null, null, bOptions, false, userId, container, inTask);
4607        return ret;
4608    }
4609
4610    @Override
4611    public final int startActivities(IApplicationThread caller, String callingPackage,
4612            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4613            int userId) {
4614        enforceNotIsolatedCaller("startActivities");
4615        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4616                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4617        // TODO: Switch to user app stacks here.
4618        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4619                resolvedTypes, resultTo, bOptions, userId);
4620        return ret;
4621    }
4622
4623    final int startActivitiesInPackage(int uid, String callingPackage,
4624            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4625            Bundle bOptions, int userId) {
4626
4627        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4628                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4629        // TODO: Switch to user app stacks here.
4630        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4631                resultTo, bOptions, userId);
4632        return ret;
4633    }
4634
4635    @Override
4636    public void reportActivityFullyDrawn(IBinder token) {
4637        synchronized (this) {
4638            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4639            if (r == null) {
4640                return;
4641            }
4642            r.reportFullyDrawnLocked();
4643        }
4644    }
4645
4646    @Override
4647    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4648        synchronized (this) {
4649            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4650            if (r == null) {
4651                return;
4652            }
4653            TaskRecord task = r.task;
4654            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4655                // Fixed screen orientation isn't supported when activities aren't in full screen
4656                // mode.
4657                return;
4658            }
4659            final long origId = Binder.clearCallingIdentity();
4660            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4661            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4662                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4663            if (config != null) {
4664                r.frozenBeforeDestroy = true;
4665                if (!updateConfigurationLocked(config, r, false)) {
4666                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4667                }
4668            }
4669            Binder.restoreCallingIdentity(origId);
4670        }
4671    }
4672
4673    @Override
4674    public int getRequestedOrientation(IBinder token) {
4675        synchronized (this) {
4676            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4677            if (r == null) {
4678                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4679            }
4680            return mWindowManager.getAppOrientation(r.appToken);
4681        }
4682    }
4683
4684    /**
4685     * This is the internal entry point for handling Activity.finish().
4686     *
4687     * @param token The Binder token referencing the Activity we want to finish.
4688     * @param resultCode Result code, if any, from this Activity.
4689     * @param resultData Result data (Intent), if any, from this Activity.
4690     * @param finishTask Whether to finish the task associated with this Activity.
4691     *
4692     * @return Returns true if the activity successfully finished, or false if it is still running.
4693     */
4694    @Override
4695    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4696            int finishTask) {
4697        // Refuse possible leaked file descriptors
4698        if (resultData != null && resultData.hasFileDescriptors() == true) {
4699            throw new IllegalArgumentException("File descriptors passed in Intent");
4700        }
4701
4702        synchronized(this) {
4703            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4704            if (r == null) {
4705                return true;
4706            }
4707            // Keep track of the root activity of the task before we finish it
4708            TaskRecord tr = r.task;
4709            ActivityRecord rootR = tr.getRootActivity();
4710            if (rootR == null) {
4711                Slog.w(TAG, "Finishing task with all activities already finished");
4712            }
4713            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4714            // finish.
4715            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4716                    mStackSupervisor.isLastLockedTask(tr)) {
4717                Slog.i(TAG, "Not finishing task in lock task mode");
4718                mStackSupervisor.showLockTaskToast();
4719                return false;
4720            }
4721            if (mController != null) {
4722                // Find the first activity that is not finishing.
4723                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4724                if (next != null) {
4725                    // ask watcher if this is allowed
4726                    boolean resumeOK = true;
4727                    try {
4728                        resumeOK = mController.activityResuming(next.packageName);
4729                    } catch (RemoteException e) {
4730                        mController = null;
4731                        Watchdog.getInstance().setActivityController(null);
4732                    }
4733
4734                    if (!resumeOK) {
4735                        Slog.i(TAG, "Not finishing activity because controller resumed");
4736                        return false;
4737                    }
4738                }
4739            }
4740            final long origId = Binder.clearCallingIdentity();
4741            try {
4742                boolean res;
4743                final boolean finishWithRootActivity =
4744                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4745                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4746                        || (finishWithRootActivity && r == rootR)) {
4747                    // If requested, remove the task that is associated to this activity only if it
4748                    // was the root activity in the task. The result code and data is ignored
4749                    // because we don't support returning them across task boundaries. Also, to
4750                    // keep backwards compatibility we remove the task from recents when finishing
4751                    // task with root activity.
4752                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4753                    if (!res) {
4754                        Slog.i(TAG, "Removing task failed to finish activity");
4755                    }
4756                } else {
4757                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4758                            resultData, "app-request", true);
4759                    if (!res) {
4760                        Slog.i(TAG, "Failed to finish by app-request");
4761                    }
4762                }
4763                return res;
4764            } finally {
4765                Binder.restoreCallingIdentity(origId);
4766            }
4767        }
4768    }
4769
4770    @Override
4771    public final void finishHeavyWeightApp() {
4772        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4773                != PackageManager.PERMISSION_GRANTED) {
4774            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4775                    + Binder.getCallingPid()
4776                    + ", uid=" + Binder.getCallingUid()
4777                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4778            Slog.w(TAG, msg);
4779            throw new SecurityException(msg);
4780        }
4781
4782        synchronized(this) {
4783            if (mHeavyWeightProcess == null) {
4784                return;
4785            }
4786
4787            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4788            for (int i = 0; i < activities.size(); i++) {
4789                ActivityRecord r = activities.get(i);
4790                if (!r.finishing && r.isInStackLocked()) {
4791                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4792                            null, "finish-heavy", true);
4793                }
4794            }
4795
4796            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4797                    mHeavyWeightProcess.userId, 0));
4798            mHeavyWeightProcess = null;
4799        }
4800    }
4801
4802    @Override
4803    public void crashApplication(int uid, int initialPid, String packageName,
4804            String message) {
4805        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4806                != PackageManager.PERMISSION_GRANTED) {
4807            String msg = "Permission Denial: crashApplication() from pid="
4808                    + Binder.getCallingPid()
4809                    + ", uid=" + Binder.getCallingUid()
4810                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4811            Slog.w(TAG, msg);
4812            throw new SecurityException(msg);
4813        }
4814
4815        synchronized(this) {
4816            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4817        }
4818    }
4819
4820    @Override
4821    public final void finishSubActivity(IBinder token, String resultWho,
4822            int requestCode) {
4823        synchronized(this) {
4824            final long origId = Binder.clearCallingIdentity();
4825            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4826            if (r != null) {
4827                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4828            }
4829            Binder.restoreCallingIdentity(origId);
4830        }
4831    }
4832
4833    @Override
4834    public boolean finishActivityAffinity(IBinder token) {
4835        synchronized(this) {
4836            final long origId = Binder.clearCallingIdentity();
4837            try {
4838                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4839                if (r == null) {
4840                    return false;
4841                }
4842
4843                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4844                // can finish.
4845                final TaskRecord task = r.task;
4846                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4847                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4848                    mStackSupervisor.showLockTaskToast();
4849                    return false;
4850                }
4851                return task.stack.finishActivityAffinityLocked(r);
4852            } finally {
4853                Binder.restoreCallingIdentity(origId);
4854            }
4855        }
4856    }
4857
4858    @Override
4859    public void finishVoiceTask(IVoiceInteractionSession session) {
4860        synchronized (this) {
4861            final long origId = Binder.clearCallingIdentity();
4862            try {
4863                // TODO: VI Consider treating local voice interactions and voice tasks
4864                // differently here
4865                mStackSupervisor.finishVoiceTask(session);
4866            } finally {
4867                Binder.restoreCallingIdentity(origId);
4868            }
4869        }
4870
4871    }
4872
4873    @Override
4874    public boolean releaseActivityInstance(IBinder token) {
4875        synchronized(this) {
4876            final long origId = Binder.clearCallingIdentity();
4877            try {
4878                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4879                if (r == null) {
4880                    return false;
4881                }
4882                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4883            } finally {
4884                Binder.restoreCallingIdentity(origId);
4885            }
4886        }
4887    }
4888
4889    @Override
4890    public void releaseSomeActivities(IApplicationThread appInt) {
4891        synchronized(this) {
4892            final long origId = Binder.clearCallingIdentity();
4893            try {
4894                ProcessRecord app = getRecordForAppLocked(appInt);
4895                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4896            } finally {
4897                Binder.restoreCallingIdentity(origId);
4898            }
4899        }
4900    }
4901
4902    @Override
4903    public boolean willActivityBeVisible(IBinder token) {
4904        synchronized(this) {
4905            ActivityStack stack = ActivityRecord.getStackLocked(token);
4906            if (stack != null) {
4907                return stack.willActivityBeVisibleLocked(token);
4908            }
4909            return false;
4910        }
4911    }
4912
4913    @Override
4914    public void overridePendingTransition(IBinder token, String packageName,
4915            int enterAnim, int exitAnim) {
4916        synchronized(this) {
4917            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4918            if (self == null) {
4919                return;
4920            }
4921
4922            final long origId = Binder.clearCallingIdentity();
4923
4924            if (self.state == ActivityState.RESUMED
4925                    || self.state == ActivityState.PAUSING) {
4926                mWindowManager.overridePendingAppTransition(packageName,
4927                        enterAnim, exitAnim, null);
4928            }
4929
4930            Binder.restoreCallingIdentity(origId);
4931        }
4932    }
4933
4934    /**
4935     * Main function for removing an existing process from the activity manager
4936     * as a result of that process going away.  Clears out all connections
4937     * to the process.
4938     */
4939    private final void handleAppDiedLocked(ProcessRecord app,
4940            boolean restarting, boolean allowRestart) {
4941        int pid = app.pid;
4942        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4943        if (!kept && !restarting) {
4944            removeLruProcessLocked(app);
4945            if (pid > 0) {
4946                ProcessList.remove(pid);
4947            }
4948        }
4949
4950        if (mProfileProc == app) {
4951            clearProfilerLocked();
4952        }
4953
4954        // Remove this application's activities from active lists.
4955        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4956
4957        app.activities.clear();
4958
4959        if (app.instrumentationClass != null) {
4960            Slog.w(TAG, "Crash of app " + app.processName
4961                  + " running instrumentation " + app.instrumentationClass);
4962            Bundle info = new Bundle();
4963            info.putString("shortMsg", "Process crashed.");
4964            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4965        }
4966
4967        if (!restarting && hasVisibleActivities
4968                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4969            // If there was nothing to resume, and we are not already restarting this process, but
4970            // there is a visible activity that is hosted by the process...  then make sure all
4971            // visible activities are running, taking care of restarting this process.
4972            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4973        }
4974    }
4975
4976    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4977        IBinder threadBinder = thread.asBinder();
4978        // Find the application record.
4979        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4980            ProcessRecord rec = mLruProcesses.get(i);
4981            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4982                return i;
4983            }
4984        }
4985        return -1;
4986    }
4987
4988    final ProcessRecord getRecordForAppLocked(
4989            IApplicationThread thread) {
4990        if (thread == null) {
4991            return null;
4992        }
4993
4994        int appIndex = getLRURecordIndexForAppLocked(thread);
4995        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4996    }
4997
4998    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4999        // If there are no longer any background processes running,
5000        // and the app that died was not running instrumentation,
5001        // then tell everyone we are now low on memory.
5002        boolean haveBg = false;
5003        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5004            ProcessRecord rec = mLruProcesses.get(i);
5005            if (rec.thread != null
5006                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5007                haveBg = true;
5008                break;
5009            }
5010        }
5011
5012        if (!haveBg) {
5013            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5014            if (doReport) {
5015                long now = SystemClock.uptimeMillis();
5016                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5017                    doReport = false;
5018                } else {
5019                    mLastMemUsageReportTime = now;
5020                }
5021            }
5022            final ArrayList<ProcessMemInfo> memInfos
5023                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5024            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5025            long now = SystemClock.uptimeMillis();
5026            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5027                ProcessRecord rec = mLruProcesses.get(i);
5028                if (rec == dyingProc || rec.thread == null) {
5029                    continue;
5030                }
5031                if (doReport) {
5032                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5033                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5034                }
5035                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5036                    // The low memory report is overriding any current
5037                    // state for a GC request.  Make sure to do
5038                    // heavy/important/visible/foreground processes first.
5039                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5040                        rec.lastRequestedGc = 0;
5041                    } else {
5042                        rec.lastRequestedGc = rec.lastLowMemory;
5043                    }
5044                    rec.reportLowMemory = true;
5045                    rec.lastLowMemory = now;
5046                    mProcessesToGc.remove(rec);
5047                    addProcessToGcListLocked(rec);
5048                }
5049            }
5050            if (doReport) {
5051                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5052                mHandler.sendMessage(msg);
5053            }
5054            scheduleAppGcsLocked();
5055        }
5056    }
5057
5058    final void appDiedLocked(ProcessRecord app) {
5059       appDiedLocked(app, app.pid, app.thread, false);
5060    }
5061
5062    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5063            boolean fromBinderDied) {
5064        // First check if this ProcessRecord is actually active for the pid.
5065        synchronized (mPidsSelfLocked) {
5066            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5067            if (curProc != app) {
5068                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5069                return;
5070            }
5071        }
5072
5073        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5074        synchronized (stats) {
5075            stats.noteProcessDiedLocked(app.info.uid, pid);
5076        }
5077
5078        if (!app.killed) {
5079            if (!fromBinderDied) {
5080                Process.killProcessQuiet(pid);
5081            }
5082            killProcessGroup(app.uid, pid);
5083            app.killed = true;
5084        }
5085
5086        // Clean up already done if the process has been re-started.
5087        if (app.pid == pid && app.thread != null &&
5088                app.thread.asBinder() == thread.asBinder()) {
5089            boolean doLowMem = app.instrumentationClass == null;
5090            boolean doOomAdj = doLowMem;
5091            if (!app.killedByAm) {
5092                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5093                        + ") has died");
5094                mAllowLowerMemLevel = true;
5095            } else {
5096                // Note that we always want to do oom adj to update our state with the
5097                // new number of procs.
5098                mAllowLowerMemLevel = false;
5099                doLowMem = false;
5100            }
5101            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5102            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5103                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5104            handleAppDiedLocked(app, false, true);
5105
5106            if (doOomAdj) {
5107                updateOomAdjLocked();
5108            }
5109            if (doLowMem) {
5110                doLowMemReportIfNeededLocked(app);
5111            }
5112        } else if (app.pid != pid) {
5113            // A new process has already been started.
5114            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5115                    + ") has died and restarted (pid " + app.pid + ").");
5116            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5117        } else if (DEBUG_PROCESSES) {
5118            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5119                    + thread.asBinder());
5120        }
5121    }
5122
5123    /**
5124     * If a stack trace dump file is configured, dump process stack traces.
5125     * @param clearTraces causes the dump file to be erased prior to the new
5126     *    traces being written, if true; when false, the new traces will be
5127     *    appended to any existing file content.
5128     * @param firstPids of dalvik VM processes to dump stack traces for first
5129     * @param lastPids of dalvik VM processes to dump stack traces for last
5130     * @param nativeProcs optional list of native process names to dump stack crawls
5131     * @return file containing stack traces, or null if no dump file is configured
5132     */
5133    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5134            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5135        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5136        if (tracesPath == null || tracesPath.length() == 0) {
5137            return null;
5138        }
5139
5140        File tracesFile = new File(tracesPath);
5141        try {
5142            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5143            tracesFile.createNewFile();
5144            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5145        } catch (IOException e) {
5146            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5147            return null;
5148        }
5149
5150        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5151        return tracesFile;
5152    }
5153
5154    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5155            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5156        // Use a FileObserver to detect when traces finish writing.
5157        // The order of traces is considered important to maintain for legibility.
5158        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5159            @Override
5160            public synchronized void onEvent(int event, String path) { notify(); }
5161        };
5162
5163        try {
5164            observer.startWatching();
5165
5166            // First collect all of the stacks of the most important pids.
5167            if (firstPids != null) {
5168                try {
5169                    int num = firstPids.size();
5170                    for (int i = 0; i < num; i++) {
5171                        synchronized (observer) {
5172                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5173                                    + firstPids.get(i));
5174                            final long sime = SystemClock.elapsedRealtime();
5175                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5176                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5177                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5178                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5179                        }
5180                    }
5181                } catch (InterruptedException e) {
5182                    Slog.wtf(TAG, e);
5183                }
5184            }
5185
5186            // Next collect the stacks of the native pids
5187            if (nativeProcs != null) {
5188                int[] pids = Process.getPidsForCommands(nativeProcs);
5189                if (pids != null) {
5190                    for (int pid : pids) {
5191                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5192                        final long sime = SystemClock.elapsedRealtime();
5193                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5194                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5195                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5196                    }
5197                }
5198            }
5199
5200            // Lastly, measure CPU usage.
5201            if (processCpuTracker != null) {
5202                processCpuTracker.init();
5203                System.gc();
5204                processCpuTracker.update();
5205                try {
5206                    synchronized (processCpuTracker) {
5207                        processCpuTracker.wait(500); // measure over 1/2 second.
5208                    }
5209                } catch (InterruptedException e) {
5210                }
5211                processCpuTracker.update();
5212
5213                // We'll take the stack crawls of just the top apps using CPU.
5214                final int N = processCpuTracker.countWorkingStats();
5215                int numProcs = 0;
5216                for (int i=0; i<N && numProcs<5; i++) {
5217                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5218                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5219                        numProcs++;
5220                        try {
5221                            synchronized (observer) {
5222                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5223                                        + stats.pid);
5224                                final long stime = SystemClock.elapsedRealtime();
5225                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5226                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5227                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5228                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5229                            }
5230                        } catch (InterruptedException e) {
5231                            Slog.wtf(TAG, e);
5232                        }
5233                    } else if (DEBUG_ANR) {
5234                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5235                                + stats.pid);
5236                    }
5237                }
5238            }
5239        } finally {
5240            observer.stopWatching();
5241        }
5242    }
5243
5244    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5245        if (true || IS_USER_BUILD) {
5246            return;
5247        }
5248        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5249        if (tracesPath == null || tracesPath.length() == 0) {
5250            return;
5251        }
5252
5253        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5254        StrictMode.allowThreadDiskWrites();
5255        try {
5256            final File tracesFile = new File(tracesPath);
5257            final File tracesDir = tracesFile.getParentFile();
5258            final File tracesTmp = new File(tracesDir, "__tmp__");
5259            try {
5260                if (tracesFile.exists()) {
5261                    tracesTmp.delete();
5262                    tracesFile.renameTo(tracesTmp);
5263                }
5264                StringBuilder sb = new StringBuilder();
5265                Time tobj = new Time();
5266                tobj.set(System.currentTimeMillis());
5267                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5268                sb.append(": ");
5269                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5270                sb.append(" since ");
5271                sb.append(msg);
5272                FileOutputStream fos = new FileOutputStream(tracesFile);
5273                fos.write(sb.toString().getBytes());
5274                if (app == null) {
5275                    fos.write("\n*** No application process!".getBytes());
5276                }
5277                fos.close();
5278                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5279            } catch (IOException e) {
5280                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5281                return;
5282            }
5283
5284            if (app != null) {
5285                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5286                firstPids.add(app.pid);
5287                dumpStackTraces(tracesPath, firstPids, null, null, null);
5288            }
5289
5290            File lastTracesFile = null;
5291            File curTracesFile = null;
5292            for (int i=9; i>=0; i--) {
5293                String name = String.format(Locale.US, "slow%02d.txt", i);
5294                curTracesFile = new File(tracesDir, name);
5295                if (curTracesFile.exists()) {
5296                    if (lastTracesFile != null) {
5297                        curTracesFile.renameTo(lastTracesFile);
5298                    } else {
5299                        curTracesFile.delete();
5300                    }
5301                }
5302                lastTracesFile = curTracesFile;
5303            }
5304            tracesFile.renameTo(curTracesFile);
5305            if (tracesTmp.exists()) {
5306                tracesTmp.renameTo(tracesFile);
5307            }
5308        } finally {
5309            StrictMode.setThreadPolicy(oldPolicy);
5310        }
5311    }
5312
5313    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5314        if (!mLaunchWarningShown) {
5315            mLaunchWarningShown = true;
5316            mUiHandler.post(new Runnable() {
5317                @Override
5318                public void run() {
5319                    synchronized (ActivityManagerService.this) {
5320                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5321                        d.show();
5322                        mUiHandler.postDelayed(new Runnable() {
5323                            @Override
5324                            public void run() {
5325                                synchronized (ActivityManagerService.this) {
5326                                    d.dismiss();
5327                                    mLaunchWarningShown = false;
5328                                }
5329                            }
5330                        }, 4000);
5331                    }
5332                }
5333            });
5334        }
5335    }
5336
5337    @Override
5338    public boolean clearApplicationUserData(final String packageName,
5339            final IPackageDataObserver observer, int userId) {
5340        enforceNotIsolatedCaller("clearApplicationUserData");
5341        int uid = Binder.getCallingUid();
5342        int pid = Binder.getCallingPid();
5343        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5344                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5345
5346        final DevicePolicyManagerInternal dpmi = LocalServices
5347                .getService(DevicePolicyManagerInternal.class);
5348        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5349            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5350        }
5351
5352        long callingId = Binder.clearCallingIdentity();
5353        try {
5354            IPackageManager pm = AppGlobals.getPackageManager();
5355            int pkgUid = -1;
5356            synchronized(this) {
5357                try {
5358                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5359                } catch (RemoteException e) {
5360                }
5361                if (pkgUid == -1) {
5362                    Slog.w(TAG, "Invalid packageName: " + packageName);
5363                    if (observer != null) {
5364                        try {
5365                            observer.onRemoveCompleted(packageName, false);
5366                        } catch (RemoteException e) {
5367                            Slog.i(TAG, "Observer no longer exists.");
5368                        }
5369                    }
5370                    return false;
5371                }
5372                if (uid == pkgUid || checkComponentPermission(
5373                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5374                        pid, uid, -1, true)
5375                        == PackageManager.PERMISSION_GRANTED) {
5376                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5377                } else {
5378                    throw new SecurityException("PID " + pid + " does not have permission "
5379                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5380                                    + " of package " + packageName);
5381                }
5382
5383                // Remove all tasks match the cleared application package and user
5384                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5385                    final TaskRecord tr = mRecentTasks.get(i);
5386                    final String taskPackageName =
5387                            tr.getBaseIntent().getComponent().getPackageName();
5388                    if (tr.userId != userId) continue;
5389                    if (!taskPackageName.equals(packageName)) continue;
5390                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5391                }
5392            }
5393
5394            try {
5395                // Clear application user data
5396                pm.clearApplicationUserData(packageName, observer, userId);
5397
5398                synchronized(this) {
5399                    // Remove all permissions granted from/to this package
5400                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5401                }
5402
5403                // Remove all zen rules created by this package; revoke it's zen access.
5404                INotificationManager inm = NotificationManager.getService();
5405                inm.removeAutomaticZenRules(packageName);
5406                inm.setNotificationPolicyAccessGranted(packageName, false);
5407
5408                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5409                        Uri.fromParts("package", packageName, null));
5410                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5411                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5412                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5413                        null, null, 0, null, null, null, null, false, false, userId);
5414            } catch (RemoteException e) {
5415            }
5416        } finally {
5417            Binder.restoreCallingIdentity(callingId);
5418        }
5419        return true;
5420    }
5421
5422    @Override
5423    public void killBackgroundProcesses(final String packageName, int userId) {
5424        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5425                != PackageManager.PERMISSION_GRANTED &&
5426                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5427                        != PackageManager.PERMISSION_GRANTED) {
5428            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5429                    + Binder.getCallingPid()
5430                    + ", uid=" + Binder.getCallingUid()
5431                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5432            Slog.w(TAG, msg);
5433            throw new SecurityException(msg);
5434        }
5435
5436        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5437                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5438        long callingId = Binder.clearCallingIdentity();
5439        try {
5440            IPackageManager pm = AppGlobals.getPackageManager();
5441            synchronized(this) {
5442                int appId = -1;
5443                try {
5444                    appId = UserHandle.getAppId(
5445                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5446                } catch (RemoteException e) {
5447                }
5448                if (appId == -1) {
5449                    Slog.w(TAG, "Invalid packageName: " + packageName);
5450                    return;
5451                }
5452                killPackageProcessesLocked(packageName, appId, userId,
5453                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5454            }
5455        } finally {
5456            Binder.restoreCallingIdentity(callingId);
5457        }
5458    }
5459
5460    @Override
5461    public void killAllBackgroundProcesses() {
5462        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5463                != PackageManager.PERMISSION_GRANTED) {
5464            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5465                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5466                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5467            Slog.w(TAG, msg);
5468            throw new SecurityException(msg);
5469        }
5470
5471        final long callingId = Binder.clearCallingIdentity();
5472        try {
5473            synchronized (this) {
5474                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5475                final int NP = mProcessNames.getMap().size();
5476                for (int ip = 0; ip < NP; ip++) {
5477                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5478                    final int NA = apps.size();
5479                    for (int ia = 0; ia < NA; ia++) {
5480                        final ProcessRecord app = apps.valueAt(ia);
5481                        if (app.persistent) {
5482                            // We don't kill persistent processes.
5483                            continue;
5484                        }
5485                        if (app.removed) {
5486                            procs.add(app);
5487                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5488                            app.removed = true;
5489                            procs.add(app);
5490                        }
5491                    }
5492                }
5493
5494                final int N = procs.size();
5495                for (int i = 0; i < N; i++) {
5496                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5497                }
5498
5499                mAllowLowerMemLevel = true;
5500
5501                updateOomAdjLocked();
5502                doLowMemReportIfNeededLocked(null);
5503            }
5504        } finally {
5505            Binder.restoreCallingIdentity(callingId);
5506        }
5507    }
5508
5509    /**
5510     * Kills all background processes, except those matching any of the
5511     * specified properties.
5512     *
5513     * @param minTargetSdk the target SDK version at or above which to preserve
5514     *                     processes, or {@code -1} to ignore the target SDK
5515     * @param maxProcState the process state at or below which to preserve
5516     *                     processes, or {@code -1} to ignore the process state
5517     */
5518    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5519        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5520                != PackageManager.PERMISSION_GRANTED) {
5521            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5522                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5523                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5524            Slog.w(TAG, msg);
5525            throw new SecurityException(msg);
5526        }
5527
5528        final long callingId = Binder.clearCallingIdentity();
5529        try {
5530            synchronized (this) {
5531                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5532                final int NP = mProcessNames.getMap().size();
5533                for (int ip = 0; ip < NP; ip++) {
5534                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5535                    final int NA = apps.size();
5536                    for (int ia = 0; ia < NA; ia++) {
5537                        final ProcessRecord app = apps.valueAt(ia);
5538                        if (app.removed) {
5539                            procs.add(app);
5540                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5541                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5542                            app.removed = true;
5543                            procs.add(app);
5544                        }
5545                    }
5546                }
5547
5548                final int N = procs.size();
5549                for (int i = 0; i < N; i++) {
5550                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5551                }
5552            }
5553        } finally {
5554            Binder.restoreCallingIdentity(callingId);
5555        }
5556    }
5557
5558    @Override
5559    public void forceStopPackage(final String packageName, int userId) {
5560        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5561                != PackageManager.PERMISSION_GRANTED) {
5562            String msg = "Permission Denial: forceStopPackage() from pid="
5563                    + Binder.getCallingPid()
5564                    + ", uid=" + Binder.getCallingUid()
5565                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5566            Slog.w(TAG, msg);
5567            throw new SecurityException(msg);
5568        }
5569        final int callingPid = Binder.getCallingPid();
5570        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5571                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5572        long callingId = Binder.clearCallingIdentity();
5573        try {
5574            IPackageManager pm = AppGlobals.getPackageManager();
5575            synchronized(this) {
5576                int[] users = userId == UserHandle.USER_ALL
5577                        ? mUserController.getUsers() : new int[] { userId };
5578                for (int user : users) {
5579                    int pkgUid = -1;
5580                    try {
5581                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5582                                user);
5583                    } catch (RemoteException e) {
5584                    }
5585                    if (pkgUid == -1) {
5586                        Slog.w(TAG, "Invalid packageName: " + packageName);
5587                        continue;
5588                    }
5589                    try {
5590                        pm.setPackageStoppedState(packageName, true, user);
5591                    } catch (RemoteException e) {
5592                    } catch (IllegalArgumentException e) {
5593                        Slog.w(TAG, "Failed trying to unstop package "
5594                                + packageName + ": " + e);
5595                    }
5596                    if (mUserController.isUserRunningLocked(user, 0)) {
5597                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5598                    }
5599                }
5600            }
5601        } finally {
5602            Binder.restoreCallingIdentity(callingId);
5603        }
5604    }
5605
5606    @Override
5607    public void addPackageDependency(String packageName) {
5608        synchronized (this) {
5609            int callingPid = Binder.getCallingPid();
5610            if (callingPid == Process.myPid()) {
5611                //  Yeah, um, no.
5612                return;
5613            }
5614            ProcessRecord proc;
5615            synchronized (mPidsSelfLocked) {
5616                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5617            }
5618            if (proc != null) {
5619                if (proc.pkgDeps == null) {
5620                    proc.pkgDeps = new ArraySet<String>(1);
5621                }
5622                proc.pkgDeps.add(packageName);
5623            }
5624        }
5625    }
5626
5627    /*
5628     * The pkg name and app id have to be specified.
5629     */
5630    @Override
5631    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5632        if (pkg == null) {
5633            return;
5634        }
5635        // Make sure the uid is valid.
5636        if (appid < 0) {
5637            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5638            return;
5639        }
5640        int callerUid = Binder.getCallingUid();
5641        // Only the system server can kill an application
5642        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5643            // Post an aysnc message to kill the application
5644            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5645            msg.arg1 = appid;
5646            msg.arg2 = 0;
5647            Bundle bundle = new Bundle();
5648            bundle.putString("pkg", pkg);
5649            bundle.putString("reason", reason);
5650            msg.obj = bundle;
5651            mHandler.sendMessage(msg);
5652        } else {
5653            throw new SecurityException(callerUid + " cannot kill pkg: " +
5654                    pkg);
5655        }
5656    }
5657
5658    @Override
5659    public void closeSystemDialogs(String reason) {
5660        enforceNotIsolatedCaller("closeSystemDialogs");
5661
5662        final int pid = Binder.getCallingPid();
5663        final int uid = Binder.getCallingUid();
5664        final long origId = Binder.clearCallingIdentity();
5665        try {
5666            synchronized (this) {
5667                // Only allow this from foreground processes, so that background
5668                // applications can't abuse it to prevent system UI from being shown.
5669                if (uid >= Process.FIRST_APPLICATION_UID) {
5670                    ProcessRecord proc;
5671                    synchronized (mPidsSelfLocked) {
5672                        proc = mPidsSelfLocked.get(pid);
5673                    }
5674                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5675                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5676                                + " from background process " + proc);
5677                        return;
5678                    }
5679                }
5680                closeSystemDialogsLocked(reason);
5681            }
5682        } finally {
5683            Binder.restoreCallingIdentity(origId);
5684        }
5685    }
5686
5687    void closeSystemDialogsLocked(String reason) {
5688        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5689        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5690                | Intent.FLAG_RECEIVER_FOREGROUND);
5691        if (reason != null) {
5692            intent.putExtra("reason", reason);
5693        }
5694        mWindowManager.closeSystemDialogs(reason);
5695
5696        mStackSupervisor.closeSystemDialogsLocked();
5697
5698        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5699                AppOpsManager.OP_NONE, null, false, false,
5700                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5701    }
5702
5703    @Override
5704    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5705        enforceNotIsolatedCaller("getProcessMemoryInfo");
5706        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5707        for (int i=pids.length-1; i>=0; i--) {
5708            ProcessRecord proc;
5709            int oomAdj;
5710            synchronized (this) {
5711                synchronized (mPidsSelfLocked) {
5712                    proc = mPidsSelfLocked.get(pids[i]);
5713                    oomAdj = proc != null ? proc.setAdj : 0;
5714                }
5715            }
5716            infos[i] = new Debug.MemoryInfo();
5717            Debug.getMemoryInfo(pids[i], infos[i]);
5718            if (proc != null) {
5719                synchronized (this) {
5720                    if (proc.thread != null && proc.setAdj == oomAdj) {
5721                        // Record this for posterity if the process has been stable.
5722                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5723                                infos[i].getTotalUss(), false, proc.pkgList);
5724                    }
5725                }
5726            }
5727        }
5728        return infos;
5729    }
5730
5731    @Override
5732    public long[] getProcessPss(int[] pids) {
5733        enforceNotIsolatedCaller("getProcessPss");
5734        long[] pss = new long[pids.length];
5735        for (int i=pids.length-1; i>=0; i--) {
5736            ProcessRecord proc;
5737            int oomAdj;
5738            synchronized (this) {
5739                synchronized (mPidsSelfLocked) {
5740                    proc = mPidsSelfLocked.get(pids[i]);
5741                    oomAdj = proc != null ? proc.setAdj : 0;
5742                }
5743            }
5744            long[] tmpUss = new long[1];
5745            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5746            if (proc != null) {
5747                synchronized (this) {
5748                    if (proc.thread != null && proc.setAdj == oomAdj) {
5749                        // Record this for posterity if the process has been stable.
5750                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5751                    }
5752                }
5753            }
5754        }
5755        return pss;
5756    }
5757
5758    @Override
5759    public void killApplicationProcess(String processName, int uid) {
5760        if (processName == null) {
5761            return;
5762        }
5763
5764        int callerUid = Binder.getCallingUid();
5765        // Only the system server can kill an application
5766        if (callerUid == Process.SYSTEM_UID) {
5767            synchronized (this) {
5768                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5769                if (app != null && app.thread != null) {
5770                    try {
5771                        app.thread.scheduleSuicide();
5772                    } catch (RemoteException e) {
5773                        // If the other end already died, then our work here is done.
5774                    }
5775                } else {
5776                    Slog.w(TAG, "Process/uid not found attempting kill of "
5777                            + processName + " / " + uid);
5778                }
5779            }
5780        } else {
5781            throw new SecurityException(callerUid + " cannot kill app process: " +
5782                    processName);
5783        }
5784    }
5785
5786    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5787        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5788                false, true, false, false, UserHandle.getUserId(uid), reason);
5789        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5790                Uri.fromParts("package", packageName, null));
5791        if (!mProcessesReady) {
5792            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5793                    | Intent.FLAG_RECEIVER_FOREGROUND);
5794        }
5795        intent.putExtra(Intent.EXTRA_UID, uid);
5796        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5797        broadcastIntentLocked(null, null, intent,
5798                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5799                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5800    }
5801
5802
5803    private final boolean killPackageProcessesLocked(String packageName, int appId,
5804            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5805            boolean doit, boolean evenPersistent, String reason) {
5806        ArrayList<ProcessRecord> procs = new ArrayList<>();
5807
5808        // Remove all processes this package may have touched: all with the
5809        // same UID (except for the system or root user), and all whose name
5810        // matches the package name.
5811        final int NP = mProcessNames.getMap().size();
5812        for (int ip=0; ip<NP; ip++) {
5813            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5814            final int NA = apps.size();
5815            for (int ia=0; ia<NA; ia++) {
5816                ProcessRecord app = apps.valueAt(ia);
5817                if (app.persistent && !evenPersistent) {
5818                    // we don't kill persistent processes
5819                    continue;
5820                }
5821                if (app.removed) {
5822                    if (doit) {
5823                        procs.add(app);
5824                    }
5825                    continue;
5826                }
5827
5828                // Skip process if it doesn't meet our oom adj requirement.
5829                if (app.setAdj < minOomAdj) {
5830                    continue;
5831                }
5832
5833                // If no package is specified, we call all processes under the
5834                // give user id.
5835                if (packageName == null) {
5836                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5837                        continue;
5838                    }
5839                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5840                        continue;
5841                    }
5842                // Package has been specified, we want to hit all processes
5843                // that match it.  We need to qualify this by the processes
5844                // that are running under the specified app and user ID.
5845                } else {
5846                    final boolean isDep = app.pkgDeps != null
5847                            && app.pkgDeps.contains(packageName);
5848                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5849                        continue;
5850                    }
5851                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5852                        continue;
5853                    }
5854                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5855                        continue;
5856                    }
5857                }
5858
5859                // Process has passed all conditions, kill it!
5860                if (!doit) {
5861                    return true;
5862                }
5863                app.removed = true;
5864                procs.add(app);
5865            }
5866        }
5867
5868        int N = procs.size();
5869        for (int i=0; i<N; i++) {
5870            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5871        }
5872        updateOomAdjLocked();
5873        return N > 0;
5874    }
5875
5876    private void cleanupDisabledPackageComponentsLocked(
5877            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5878
5879        Set<String> disabledClasses = null;
5880        boolean packageDisabled = false;
5881        IPackageManager pm = AppGlobals.getPackageManager();
5882
5883        if (changedClasses == null) {
5884            // Nothing changed...
5885            return;
5886        }
5887
5888        // Determine enable/disable state of the package and its components.
5889        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5890        for (int i = changedClasses.length - 1; i >= 0; i--) {
5891            final String changedClass = changedClasses[i];
5892
5893            if (changedClass.equals(packageName)) {
5894                try {
5895                    // Entire package setting changed
5896                    enabled = pm.getApplicationEnabledSetting(packageName,
5897                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5898                } catch (Exception e) {
5899                    // No such package/component; probably racing with uninstall.  In any
5900                    // event it means we have nothing further to do here.
5901                    return;
5902                }
5903                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5904                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5905                if (packageDisabled) {
5906                    // Entire package is disabled.
5907                    // No need to continue to check component states.
5908                    disabledClasses = null;
5909                    break;
5910                }
5911            } else {
5912                try {
5913                    enabled = pm.getComponentEnabledSetting(
5914                            new ComponentName(packageName, changedClass),
5915                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5916                } catch (Exception e) {
5917                    // As above, probably racing with uninstall.
5918                    return;
5919                }
5920                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5921                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5922                    if (disabledClasses == null) {
5923                        disabledClasses = new ArraySet<>(changedClasses.length);
5924                    }
5925                    disabledClasses.add(changedClass);
5926                }
5927            }
5928        }
5929
5930        if (!packageDisabled && disabledClasses == null) {
5931            // Nothing to do here...
5932            return;
5933        }
5934
5935        // Clean-up disabled activities.
5936        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5937                packageName, disabledClasses, true, false, userId) && mBooted) {
5938            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5939            mStackSupervisor.scheduleIdleLocked();
5940        }
5941
5942        // Clean-up disabled tasks
5943        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5944
5945        // Clean-up disabled services.
5946        mServices.bringDownDisabledPackageServicesLocked(
5947                packageName, disabledClasses, userId, false, killProcess, true);
5948
5949        // Clean-up disabled providers.
5950        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5951        mProviderMap.collectPackageProvidersLocked(
5952                packageName, disabledClasses, true, false, userId, providers);
5953        for (int i = providers.size() - 1; i >= 0; i--) {
5954            removeDyingProviderLocked(null, providers.get(i), true);
5955        }
5956
5957        // Clean-up disabled broadcast receivers.
5958        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5959            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5960                    packageName, disabledClasses, userId, true);
5961        }
5962
5963    }
5964
5965    final boolean clearBroadcastQueueForUserLocked(int userId) {
5966        boolean didSomething = false;
5967        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5968            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5969                    null, null, userId, true);
5970        }
5971        return didSomething;
5972    }
5973
5974    final boolean forceStopPackageLocked(String packageName, int appId,
5975            boolean callerWillRestart, boolean purgeCache, boolean doit,
5976            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5977        int i;
5978
5979        if (userId == UserHandle.USER_ALL && packageName == null) {
5980            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5981        }
5982
5983        if (appId < 0 && packageName != null) {
5984            try {
5985                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5986                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5987            } catch (RemoteException e) {
5988            }
5989        }
5990
5991        if (doit) {
5992            if (packageName != null) {
5993                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5994                        + " user=" + userId + ": " + reason);
5995            } else {
5996                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5997            }
5998
5999            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6000        }
6001
6002        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6003                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6004                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6005
6006        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6007                packageName, null, doit, evenPersistent, userId)) {
6008            if (!doit) {
6009                return true;
6010            }
6011            didSomething = true;
6012        }
6013
6014        if (mServices.bringDownDisabledPackageServicesLocked(
6015                packageName, null, userId, evenPersistent, true, doit)) {
6016            if (!doit) {
6017                return true;
6018            }
6019            didSomething = true;
6020        }
6021
6022        if (packageName == null) {
6023            // Remove all sticky broadcasts from this user.
6024            mStickyBroadcasts.remove(userId);
6025        }
6026
6027        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6028        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6029                userId, providers)) {
6030            if (!doit) {
6031                return true;
6032            }
6033            didSomething = true;
6034        }
6035        for (i = providers.size() - 1; i >= 0; i--) {
6036            removeDyingProviderLocked(null, providers.get(i), true);
6037        }
6038
6039        // Remove transient permissions granted from/to this package/user
6040        removeUriPermissionsForPackageLocked(packageName, userId, false);
6041
6042        if (doit) {
6043            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6044                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6045                        packageName, null, userId, doit);
6046            }
6047        }
6048
6049        if (packageName == null || uninstalling) {
6050            // Remove pending intents.  For now we only do this when force
6051            // stopping users, because we have some problems when doing this
6052            // for packages -- app widgets are not currently cleaned up for
6053            // such packages, so they can be left with bad pending intents.
6054            if (mIntentSenderRecords.size() > 0) {
6055                Iterator<WeakReference<PendingIntentRecord>> it
6056                        = mIntentSenderRecords.values().iterator();
6057                while (it.hasNext()) {
6058                    WeakReference<PendingIntentRecord> wpir = it.next();
6059                    if (wpir == null) {
6060                        it.remove();
6061                        continue;
6062                    }
6063                    PendingIntentRecord pir = wpir.get();
6064                    if (pir == null) {
6065                        it.remove();
6066                        continue;
6067                    }
6068                    if (packageName == null) {
6069                        // Stopping user, remove all objects for the user.
6070                        if (pir.key.userId != userId) {
6071                            // Not the same user, skip it.
6072                            continue;
6073                        }
6074                    } else {
6075                        if (UserHandle.getAppId(pir.uid) != appId) {
6076                            // Different app id, skip it.
6077                            continue;
6078                        }
6079                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6080                            // Different user, skip it.
6081                            continue;
6082                        }
6083                        if (!pir.key.packageName.equals(packageName)) {
6084                            // Different package, skip it.
6085                            continue;
6086                        }
6087                    }
6088                    if (!doit) {
6089                        return true;
6090                    }
6091                    didSomething = true;
6092                    it.remove();
6093                    pir.canceled = true;
6094                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6095                        pir.key.activity.pendingResults.remove(pir.ref);
6096                    }
6097                }
6098            }
6099        }
6100
6101        if (doit) {
6102            if (purgeCache && packageName != null) {
6103                AttributeCache ac = AttributeCache.instance();
6104                if (ac != null) {
6105                    ac.removePackage(packageName);
6106                }
6107            }
6108            if (mBooted) {
6109                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6110                mStackSupervisor.scheduleIdleLocked();
6111            }
6112        }
6113
6114        return didSomething;
6115    }
6116
6117    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6118        ProcessRecord old = mProcessNames.remove(name, uid);
6119        if (old != null) {
6120            old.uidRecord.numProcs--;
6121            if (old.uidRecord.numProcs == 0) {
6122                // No more processes using this uid, tell clients it is gone.
6123                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6124                        "No more processes in " + old.uidRecord);
6125                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6126                mActiveUids.remove(uid);
6127                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6128            }
6129            old.uidRecord = null;
6130        }
6131        mIsolatedProcesses.remove(uid);
6132        return old;
6133    }
6134
6135    private final void addProcessNameLocked(ProcessRecord proc) {
6136        // We shouldn't already have a process under this name, but just in case we
6137        // need to clean up whatever may be there now.
6138        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6139        if (old == proc && proc.persistent) {
6140            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6141            Slog.w(TAG, "Re-adding persistent process " + proc);
6142        } else if (old != null) {
6143            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6144        }
6145        UidRecord uidRec = mActiveUids.get(proc.uid);
6146        if (uidRec == null) {
6147            uidRec = new UidRecord(proc.uid);
6148            // This is the first appearance of the uid, report it now!
6149            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6150                    "Creating new process uid: " + uidRec);
6151            mActiveUids.put(proc.uid, uidRec);
6152            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6153            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6154        }
6155        proc.uidRecord = uidRec;
6156        uidRec.numProcs++;
6157        mProcessNames.put(proc.processName, proc.uid, proc);
6158        if (proc.isolated) {
6159            mIsolatedProcesses.put(proc.uid, proc);
6160        }
6161    }
6162
6163    boolean removeProcessLocked(ProcessRecord app,
6164            boolean callerWillRestart, boolean allowRestart, String reason) {
6165        final String name = app.processName;
6166        final int uid = app.uid;
6167        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6168            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6169
6170        ProcessRecord old = mProcessNames.get(name, uid);
6171        if (old != app) {
6172            // This process is no longer active, so nothing to do.
6173            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6174            return false;
6175        }
6176        removeProcessNameLocked(name, uid);
6177        if (mHeavyWeightProcess == app) {
6178            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6179                    mHeavyWeightProcess.userId, 0));
6180            mHeavyWeightProcess = null;
6181        }
6182        boolean needRestart = false;
6183        if (app.pid > 0 && app.pid != MY_PID) {
6184            int pid = app.pid;
6185            synchronized (mPidsSelfLocked) {
6186                mPidsSelfLocked.remove(pid);
6187                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6188            }
6189            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6190            if (app.isolated) {
6191                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6192            }
6193            boolean willRestart = false;
6194            if (app.persistent && !app.isolated) {
6195                if (!callerWillRestart) {
6196                    willRestart = true;
6197                } else {
6198                    needRestart = true;
6199                }
6200            }
6201            app.kill(reason, true);
6202            handleAppDiedLocked(app, willRestart, allowRestart);
6203            if (willRestart) {
6204                removeLruProcessLocked(app);
6205                addAppLocked(app.info, false, null /* ABI override */);
6206            }
6207        } else {
6208            mRemovedProcesses.add(app);
6209        }
6210
6211        return needRestart;
6212    }
6213
6214    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6215        cleanupAppInLaunchingProvidersLocked(app, true);
6216        removeProcessLocked(app, false, true, "timeout publishing content providers");
6217    }
6218
6219    private final void processStartTimedOutLocked(ProcessRecord app) {
6220        final int pid = app.pid;
6221        boolean gone = false;
6222        synchronized (mPidsSelfLocked) {
6223            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6224            if (knownApp != null && knownApp.thread == null) {
6225                mPidsSelfLocked.remove(pid);
6226                gone = true;
6227            }
6228        }
6229
6230        if (gone) {
6231            Slog.w(TAG, "Process " + app + " failed to attach");
6232            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6233                    pid, app.uid, app.processName);
6234            removeProcessNameLocked(app.processName, app.uid);
6235            if (mHeavyWeightProcess == app) {
6236                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6237                        mHeavyWeightProcess.userId, 0));
6238                mHeavyWeightProcess = null;
6239            }
6240            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6241            if (app.isolated) {
6242                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6243            }
6244            // Take care of any launching providers waiting for this process.
6245            cleanupAppInLaunchingProvidersLocked(app, true);
6246            // Take care of any services that are waiting for the process.
6247            mServices.processStartTimedOutLocked(app);
6248            app.kill("start timeout", true);
6249            removeLruProcessLocked(app);
6250            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6251                Slog.w(TAG, "Unattached app died before backup, skipping");
6252                try {
6253                    IBackupManager bm = IBackupManager.Stub.asInterface(
6254                            ServiceManager.getService(Context.BACKUP_SERVICE));
6255                    bm.agentDisconnected(app.info.packageName);
6256                } catch (RemoteException e) {
6257                    // Can't happen; the backup manager is local
6258                }
6259            }
6260            if (isPendingBroadcastProcessLocked(pid)) {
6261                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6262                skipPendingBroadcastLocked(pid);
6263            }
6264        } else {
6265            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6266        }
6267    }
6268
6269    private final boolean attachApplicationLocked(IApplicationThread thread,
6270            int pid) {
6271
6272        // Find the application record that is being attached...  either via
6273        // the pid if we are running in multiple processes, or just pull the
6274        // next app record if we are emulating process with anonymous threads.
6275        ProcessRecord app;
6276        if (pid != MY_PID && pid >= 0) {
6277            synchronized (mPidsSelfLocked) {
6278                app = mPidsSelfLocked.get(pid);
6279            }
6280        } else {
6281            app = null;
6282        }
6283
6284        if (app == null) {
6285            Slog.w(TAG, "No pending application record for pid " + pid
6286                    + " (IApplicationThread " + thread + "); dropping process");
6287            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6288            if (pid > 0 && pid != MY_PID) {
6289                Process.killProcessQuiet(pid);
6290                //TODO: killProcessGroup(app.info.uid, pid);
6291            } else {
6292                try {
6293                    thread.scheduleExit();
6294                } catch (Exception e) {
6295                    // Ignore exceptions.
6296                }
6297            }
6298            return false;
6299        }
6300
6301        // If this application record is still attached to a previous
6302        // process, clean it up now.
6303        if (app.thread != null) {
6304            handleAppDiedLocked(app, true, true);
6305        }
6306
6307        // Tell the process all about itself.
6308
6309        if (DEBUG_ALL) Slog.v(
6310                TAG, "Binding process pid " + pid + " to record " + app);
6311
6312        final String processName = app.processName;
6313        try {
6314            AppDeathRecipient adr = new AppDeathRecipient(
6315                    app, pid, thread);
6316            thread.asBinder().linkToDeath(adr, 0);
6317            app.deathRecipient = adr;
6318        } catch (RemoteException e) {
6319            app.resetPackageList(mProcessStats);
6320            startProcessLocked(app, "link fail", processName);
6321            return false;
6322        }
6323
6324        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6325
6326        app.makeActive(thread, mProcessStats);
6327        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6328        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6329        app.forcingToForeground = null;
6330        updateProcessForegroundLocked(app, false, false);
6331        app.hasShownUi = false;
6332        app.debugging = false;
6333        app.cached = false;
6334        app.killedByAm = false;
6335
6336        // We carefully use the same state that PackageManager uses for
6337        // filtering, since we use this flag to decide if we need to install
6338        // providers when user is unlocked later
6339        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6340
6341        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6342
6343        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6344        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6345
6346        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6347            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6348            msg.obj = app;
6349            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6350        }
6351
6352        if (!normalMode) {
6353            Slog.i(TAG, "Launching preboot mode app: " + app);
6354        }
6355
6356        if (DEBUG_ALL) Slog.v(
6357            TAG, "New app record " + app
6358            + " thread=" + thread.asBinder() + " pid=" + pid);
6359        try {
6360            int testMode = IApplicationThread.DEBUG_OFF;
6361            if (mDebugApp != null && mDebugApp.equals(processName)) {
6362                testMode = mWaitForDebugger
6363                    ? IApplicationThread.DEBUG_WAIT
6364                    : IApplicationThread.DEBUG_ON;
6365                app.debugging = true;
6366                if (mDebugTransient) {
6367                    mDebugApp = mOrigDebugApp;
6368                    mWaitForDebugger = mOrigWaitForDebugger;
6369                }
6370            }
6371            String profileFile = app.instrumentationProfileFile;
6372            ParcelFileDescriptor profileFd = null;
6373            int samplingInterval = 0;
6374            boolean profileAutoStop = false;
6375            if (mProfileApp != null && mProfileApp.equals(processName)) {
6376                mProfileProc = app;
6377                profileFile = mProfileFile;
6378                profileFd = mProfileFd;
6379                samplingInterval = mSamplingInterval;
6380                profileAutoStop = mAutoStopProfiler;
6381            }
6382            boolean enableTrackAllocation = false;
6383            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6384                enableTrackAllocation = true;
6385                mTrackAllocationApp = null;
6386            }
6387
6388            // If the app is being launched for restore or full backup, set it up specially
6389            boolean isRestrictedBackupMode = false;
6390            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6391                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6392                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6393                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6394                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6395            }
6396
6397            if (app.instrumentationClass != null) {
6398                notifyPackageUse(app.instrumentationClass.getPackageName(),
6399                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6400            }
6401            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6402                    + processName + " with config " + mConfiguration);
6403            ApplicationInfo appInfo = app.instrumentationInfo != null
6404                    ? app.instrumentationInfo : app.info;
6405            app.compat = compatibilityInfoForPackageLocked(appInfo);
6406            if (profileFd != null) {
6407                profileFd = profileFd.dup();
6408            }
6409            ProfilerInfo profilerInfo = profileFile == null ? null
6410                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6411            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6412                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6413                    app.instrumentationUiAutomationConnection, testMode,
6414                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6415                    isRestrictedBackupMode || !normalMode, app.persistent,
6416                    new Configuration(mConfiguration), app.compat,
6417                    getCommonServicesLocked(app.isolated),
6418                    mCoreSettingsObserver.getCoreSettingsLocked());
6419            updateLruProcessLocked(app, false, null);
6420            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6421        } catch (Exception e) {
6422            // todo: Yikes!  What should we do?  For now we will try to
6423            // start another process, but that could easily get us in
6424            // an infinite loop of restarting processes...
6425            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6426
6427            app.resetPackageList(mProcessStats);
6428            app.unlinkDeathRecipient();
6429            startProcessLocked(app, "bind fail", processName);
6430            return false;
6431        }
6432
6433        // Remove this record from the list of starting applications.
6434        mPersistentStartingProcesses.remove(app);
6435        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6436                "Attach application locked removing on hold: " + app);
6437        mProcessesOnHold.remove(app);
6438
6439        boolean badApp = false;
6440        boolean didSomething = false;
6441
6442        // See if the top visible activity is waiting to run in this process...
6443        if (normalMode) {
6444            try {
6445                if (mStackSupervisor.attachApplicationLocked(app)) {
6446                    didSomething = true;
6447                }
6448            } catch (Exception e) {
6449                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6450                badApp = true;
6451            }
6452        }
6453
6454        // Find any services that should be running in this process...
6455        if (!badApp) {
6456            try {
6457                didSomething |= mServices.attachApplicationLocked(app, processName);
6458            } catch (Exception e) {
6459                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6460                badApp = true;
6461            }
6462        }
6463
6464        // Check if a next-broadcast receiver is in this process...
6465        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6466            try {
6467                didSomething |= sendPendingBroadcastsLocked(app);
6468            } catch (Exception e) {
6469                // If the app died trying to launch the receiver we declare it 'bad'
6470                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6471                badApp = true;
6472            }
6473        }
6474
6475        // Check whether the next backup agent is in this process...
6476        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6477            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6478                    "New app is backup target, launching agent for " + app);
6479            notifyPackageUse(mBackupTarget.appInfo.packageName,
6480                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6481            try {
6482                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6483                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6484                        mBackupTarget.backupMode);
6485            } catch (Exception e) {
6486                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6487                badApp = true;
6488            }
6489        }
6490
6491        if (badApp) {
6492            app.kill("error during init", true);
6493            handleAppDiedLocked(app, false, true);
6494            return false;
6495        }
6496
6497        if (!didSomething) {
6498            updateOomAdjLocked();
6499        }
6500
6501        return true;
6502    }
6503
6504    @Override
6505    public final void attachApplication(IApplicationThread thread) {
6506        synchronized (this) {
6507            int callingPid = Binder.getCallingPid();
6508            final long origId = Binder.clearCallingIdentity();
6509            attachApplicationLocked(thread, callingPid);
6510            Binder.restoreCallingIdentity(origId);
6511        }
6512    }
6513
6514    @Override
6515    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6516        final long origId = Binder.clearCallingIdentity();
6517        synchronized (this) {
6518            ActivityStack stack = ActivityRecord.getStackLocked(token);
6519            if (stack != null) {
6520                ActivityRecord r =
6521                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6522                if (stopProfiling) {
6523                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6524                        try {
6525                            mProfileFd.close();
6526                        } catch (IOException e) {
6527                        }
6528                        clearProfilerLocked();
6529                    }
6530                }
6531            }
6532        }
6533        Binder.restoreCallingIdentity(origId);
6534    }
6535
6536    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6537        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6538                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6539    }
6540
6541    void enableScreenAfterBoot() {
6542        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6543                SystemClock.uptimeMillis());
6544        mWindowManager.enableScreenAfterBoot();
6545
6546        synchronized (this) {
6547            updateEventDispatchingLocked();
6548        }
6549    }
6550
6551    @Override
6552    public void showBootMessage(final CharSequence msg, final boolean always) {
6553        if (Binder.getCallingUid() != Process.myUid()) {
6554            // These days only the core system can call this, so apps can't get in
6555            // the way of what we show about running them.
6556        }
6557        mWindowManager.showBootMessage(msg, always);
6558    }
6559
6560    @Override
6561    public void keyguardWaitingForActivityDrawn() {
6562        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6563        final long token = Binder.clearCallingIdentity();
6564        try {
6565            synchronized (this) {
6566                if (DEBUG_LOCKSCREEN) logLockScreen("");
6567                mWindowManager.keyguardWaitingForActivityDrawn();
6568                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6569                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6570                    updateSleepIfNeededLocked();
6571                }
6572            }
6573        } finally {
6574            Binder.restoreCallingIdentity(token);
6575        }
6576    }
6577
6578    @Override
6579    public void keyguardGoingAway(int flags) {
6580        enforceNotIsolatedCaller("keyguardGoingAway");
6581        final long token = Binder.clearCallingIdentity();
6582        try {
6583            synchronized (this) {
6584                if (DEBUG_LOCKSCREEN) logLockScreen("");
6585                mWindowManager.keyguardGoingAway(flags);
6586                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6587                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6588                    updateSleepIfNeededLocked();
6589
6590                    // Some stack visibility might change (e.g. docked stack)
6591                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6592                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6593                }
6594            }
6595        } finally {
6596            Binder.restoreCallingIdentity(token);
6597        }
6598    }
6599
6600    final void finishBooting() {
6601        synchronized (this) {
6602            if (!mBootAnimationComplete) {
6603                mCallFinishBooting = true;
6604                return;
6605            }
6606            mCallFinishBooting = false;
6607        }
6608
6609        ArraySet<String> completedIsas = new ArraySet<String>();
6610        for (String abi : Build.SUPPORTED_ABIS) {
6611            Process.establishZygoteConnectionForAbi(abi);
6612            final String instructionSet = VMRuntime.getInstructionSet(abi);
6613            if (!completedIsas.contains(instructionSet)) {
6614                try {
6615                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6616                } catch (InstallerException e) {
6617                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6618                            e.getMessage() +")");
6619                }
6620                completedIsas.add(instructionSet);
6621            }
6622        }
6623
6624        IntentFilter pkgFilter = new IntentFilter();
6625        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6626        pkgFilter.addDataScheme("package");
6627        mContext.registerReceiver(new BroadcastReceiver() {
6628            @Override
6629            public void onReceive(Context context, Intent intent) {
6630                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6631                if (pkgs != null) {
6632                    for (String pkg : pkgs) {
6633                        synchronized (ActivityManagerService.this) {
6634                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6635                                    0, "query restart")) {
6636                                setResultCode(Activity.RESULT_OK);
6637                                return;
6638                            }
6639                        }
6640                    }
6641                }
6642            }
6643        }, pkgFilter);
6644
6645        IntentFilter dumpheapFilter = new IntentFilter();
6646        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6647        mContext.registerReceiver(new BroadcastReceiver() {
6648            @Override
6649            public void onReceive(Context context, Intent intent) {
6650                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6651                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6652                } else {
6653                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6654                }
6655            }
6656        }, dumpheapFilter);
6657
6658        // Let system services know.
6659        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6660
6661        synchronized (this) {
6662            // Ensure that any processes we had put on hold are now started
6663            // up.
6664            final int NP = mProcessesOnHold.size();
6665            if (NP > 0) {
6666                ArrayList<ProcessRecord> procs =
6667                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6668                for (int ip=0; ip<NP; ip++) {
6669                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6670                            + procs.get(ip));
6671                    startProcessLocked(procs.get(ip), "on-hold", null);
6672                }
6673            }
6674
6675            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6676                // Start looking for apps that are abusing wake locks.
6677                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6678                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6679                // Tell anyone interested that we are done booting!
6680                SystemProperties.set("sys.boot_completed", "1");
6681
6682                // And trigger dev.bootcomplete if we are not showing encryption progress
6683                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6684                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6685                    SystemProperties.set("dev.bootcomplete", "1");
6686                }
6687                mUserController.sendBootCompletedLocked(
6688                        new IIntentReceiver.Stub() {
6689                            @Override
6690                            public void performReceive(Intent intent, int resultCode,
6691                                    String data, Bundle extras, boolean ordered,
6692                                    boolean sticky, int sendingUser) {
6693                                synchronized (ActivityManagerService.this) {
6694                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6695                                            true, false);
6696                                }
6697                            }
6698                        });
6699                scheduleStartProfilesLocked();
6700            }
6701        }
6702    }
6703
6704    @Override
6705    public void bootAnimationComplete() {
6706        final boolean callFinishBooting;
6707        synchronized (this) {
6708            callFinishBooting = mCallFinishBooting;
6709            mBootAnimationComplete = true;
6710        }
6711        if (callFinishBooting) {
6712            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6713            finishBooting();
6714            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6715        }
6716    }
6717
6718    final void ensureBootCompleted() {
6719        boolean booting;
6720        boolean enableScreen;
6721        synchronized (this) {
6722            booting = mBooting;
6723            mBooting = false;
6724            enableScreen = !mBooted;
6725            mBooted = true;
6726        }
6727
6728        if (booting) {
6729            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6730            finishBooting();
6731            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6732        }
6733
6734        if (enableScreen) {
6735            enableScreenAfterBoot();
6736        }
6737    }
6738
6739    @Override
6740    public final void activityResumed(IBinder token) {
6741        final long origId = Binder.clearCallingIdentity();
6742        synchronized(this) {
6743            ActivityStack stack = ActivityRecord.getStackLocked(token);
6744            if (stack != null) {
6745                stack.activityResumedLocked(token);
6746            }
6747        }
6748        Binder.restoreCallingIdentity(origId);
6749    }
6750
6751    @Override
6752    public final void activityPaused(IBinder token) {
6753        final long origId = Binder.clearCallingIdentity();
6754        synchronized(this) {
6755            ActivityStack stack = ActivityRecord.getStackLocked(token);
6756            if (stack != null) {
6757                stack.activityPausedLocked(token, false);
6758            }
6759        }
6760        Binder.restoreCallingIdentity(origId);
6761    }
6762
6763    @Override
6764    public final void activityStopped(IBinder token, Bundle icicle,
6765            PersistableBundle persistentState, CharSequence description) {
6766        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6767
6768        // Refuse possible leaked file descriptors
6769        if (icicle != null && icicle.hasFileDescriptors()) {
6770            throw new IllegalArgumentException("File descriptors passed in Bundle");
6771        }
6772
6773        final long origId = Binder.clearCallingIdentity();
6774
6775        synchronized (this) {
6776            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6777            if (r != null) {
6778                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6779            }
6780        }
6781
6782        trimApplications();
6783
6784        Binder.restoreCallingIdentity(origId);
6785    }
6786
6787    @Override
6788    public final void activityDestroyed(IBinder token) {
6789        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6790        synchronized (this) {
6791            ActivityStack stack = ActivityRecord.getStackLocked(token);
6792            if (stack != null) {
6793                stack.activityDestroyedLocked(token, "activityDestroyed");
6794            }
6795        }
6796    }
6797
6798    @Override
6799    public final void activityRelaunched(IBinder token) {
6800        final long origId = Binder.clearCallingIdentity();
6801        synchronized (this) {
6802            mStackSupervisor.activityRelaunchedLocked(token);
6803        }
6804        Binder.restoreCallingIdentity(origId);
6805    }
6806
6807    @Override
6808    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6809            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6810        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6811                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6812        synchronized (this) {
6813            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6814            if (record == null) {
6815                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6816                        + "found for: " + token);
6817            }
6818            record.setSizeConfigurations(horizontalSizeConfiguration,
6819                    verticalSizeConfigurations, smallestSizeConfigurations);
6820        }
6821    }
6822
6823    @Override
6824    public final void backgroundResourcesReleased(IBinder token) {
6825        final long origId = Binder.clearCallingIdentity();
6826        try {
6827            synchronized (this) {
6828                ActivityStack stack = ActivityRecord.getStackLocked(token);
6829                if (stack != null) {
6830                    stack.backgroundResourcesReleased();
6831                }
6832            }
6833        } finally {
6834            Binder.restoreCallingIdentity(origId);
6835        }
6836    }
6837
6838    @Override
6839    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6840        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6841    }
6842
6843    @Override
6844    public final void notifyEnterAnimationComplete(IBinder token) {
6845        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6846    }
6847
6848    @Override
6849    public String getCallingPackage(IBinder token) {
6850        synchronized (this) {
6851            ActivityRecord r = getCallingRecordLocked(token);
6852            return r != null ? r.info.packageName : null;
6853        }
6854    }
6855
6856    @Override
6857    public ComponentName getCallingActivity(IBinder token) {
6858        synchronized (this) {
6859            ActivityRecord r = getCallingRecordLocked(token);
6860            return r != null ? r.intent.getComponent() : null;
6861        }
6862    }
6863
6864    private ActivityRecord getCallingRecordLocked(IBinder token) {
6865        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6866        if (r == null) {
6867            return null;
6868        }
6869        return r.resultTo;
6870    }
6871
6872    @Override
6873    public ComponentName getActivityClassForToken(IBinder token) {
6874        synchronized(this) {
6875            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6876            if (r == null) {
6877                return null;
6878            }
6879            return r.intent.getComponent();
6880        }
6881    }
6882
6883    @Override
6884    public String getPackageForToken(IBinder token) {
6885        synchronized(this) {
6886            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6887            if (r == null) {
6888                return null;
6889            }
6890            return r.packageName;
6891        }
6892    }
6893
6894    @Override
6895    public boolean isRootVoiceInteraction(IBinder token) {
6896        synchronized(this) {
6897            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6898            if (r == null) {
6899                return false;
6900            }
6901            return r.rootVoiceInteraction;
6902        }
6903    }
6904
6905    @Override
6906    public IIntentSender getIntentSender(int type,
6907            String packageName, IBinder token, String resultWho,
6908            int requestCode, Intent[] intents, String[] resolvedTypes,
6909            int flags, Bundle bOptions, int userId) {
6910        enforceNotIsolatedCaller("getIntentSender");
6911        // Refuse possible leaked file descriptors
6912        if (intents != null) {
6913            if (intents.length < 1) {
6914                throw new IllegalArgumentException("Intents array length must be >= 1");
6915            }
6916            for (int i=0; i<intents.length; i++) {
6917                Intent intent = intents[i];
6918                if (intent != null) {
6919                    if (intent.hasFileDescriptors()) {
6920                        throw new IllegalArgumentException("File descriptors passed in Intent");
6921                    }
6922                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6923                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6924                        throw new IllegalArgumentException(
6925                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6926                    }
6927                    intents[i] = new Intent(intent);
6928                }
6929            }
6930            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6931                throw new IllegalArgumentException(
6932                        "Intent array length does not match resolvedTypes length");
6933            }
6934        }
6935        if (bOptions != null) {
6936            if (bOptions.hasFileDescriptors()) {
6937                throw new IllegalArgumentException("File descriptors passed in options");
6938            }
6939        }
6940
6941        synchronized(this) {
6942            int callingUid = Binder.getCallingUid();
6943            int origUserId = userId;
6944            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6945                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6946                    ALLOW_NON_FULL, "getIntentSender", null);
6947            if (origUserId == UserHandle.USER_CURRENT) {
6948                // We don't want to evaluate this until the pending intent is
6949                // actually executed.  However, we do want to always do the
6950                // security checking for it above.
6951                userId = UserHandle.USER_CURRENT;
6952            }
6953            try {
6954                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6955                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6956                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6957                    if (!UserHandle.isSameApp(callingUid, uid)) {
6958                        String msg = "Permission Denial: getIntentSender() from pid="
6959                            + Binder.getCallingPid()
6960                            + ", uid=" + Binder.getCallingUid()
6961                            + ", (need uid=" + uid + ")"
6962                            + " is not allowed to send as package " + packageName;
6963                        Slog.w(TAG, msg);
6964                        throw new SecurityException(msg);
6965                    }
6966                }
6967
6968                return getIntentSenderLocked(type, packageName, callingUid, userId,
6969                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6970
6971            } catch (RemoteException e) {
6972                throw new SecurityException(e);
6973            }
6974        }
6975    }
6976
6977    IIntentSender getIntentSenderLocked(int type, String packageName,
6978            int callingUid, int userId, IBinder token, String resultWho,
6979            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6980            Bundle bOptions) {
6981        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6982        ActivityRecord activity = null;
6983        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6984            activity = ActivityRecord.isInStackLocked(token);
6985            if (activity == null) {
6986                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6987                return null;
6988            }
6989            if (activity.finishing) {
6990                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6991                return null;
6992            }
6993        }
6994
6995        // We're going to be splicing together extras before sending, so we're
6996        // okay poking into any contained extras.
6997        if (intents != null) {
6998            for (int i = 0; i < intents.length; i++) {
6999                intents[i].setDefusable(true);
7000            }
7001        }
7002        Bundle.setDefusable(bOptions, true);
7003
7004        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7005        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7006        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7007        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7008                |PendingIntent.FLAG_UPDATE_CURRENT);
7009
7010        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7011                type, packageName, activity, resultWho,
7012                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7013        WeakReference<PendingIntentRecord> ref;
7014        ref = mIntentSenderRecords.get(key);
7015        PendingIntentRecord rec = ref != null ? ref.get() : null;
7016        if (rec != null) {
7017            if (!cancelCurrent) {
7018                if (updateCurrent) {
7019                    if (rec.key.requestIntent != null) {
7020                        rec.key.requestIntent.replaceExtras(intents != null ?
7021                                intents[intents.length - 1] : null);
7022                    }
7023                    if (intents != null) {
7024                        intents[intents.length-1] = rec.key.requestIntent;
7025                        rec.key.allIntents = intents;
7026                        rec.key.allResolvedTypes = resolvedTypes;
7027                    } else {
7028                        rec.key.allIntents = null;
7029                        rec.key.allResolvedTypes = null;
7030                    }
7031                }
7032                return rec;
7033            }
7034            rec.canceled = true;
7035            mIntentSenderRecords.remove(key);
7036        }
7037        if (noCreate) {
7038            return rec;
7039        }
7040        rec = new PendingIntentRecord(this, key, callingUid);
7041        mIntentSenderRecords.put(key, rec.ref);
7042        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7043            if (activity.pendingResults == null) {
7044                activity.pendingResults
7045                        = new HashSet<WeakReference<PendingIntentRecord>>();
7046            }
7047            activity.pendingResults.add(rec.ref);
7048        }
7049        return rec;
7050    }
7051
7052    @Override
7053    public void cancelIntentSender(IIntentSender sender) {
7054        if (!(sender instanceof PendingIntentRecord)) {
7055            return;
7056        }
7057        synchronized(this) {
7058            PendingIntentRecord rec = (PendingIntentRecord)sender;
7059            try {
7060                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7061                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7062                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7063                    String msg = "Permission Denial: cancelIntentSender() from pid="
7064                        + Binder.getCallingPid()
7065                        + ", uid=" + Binder.getCallingUid()
7066                        + " is not allowed to cancel packges "
7067                        + rec.key.packageName;
7068                    Slog.w(TAG, msg);
7069                    throw new SecurityException(msg);
7070                }
7071            } catch (RemoteException e) {
7072                throw new SecurityException(e);
7073            }
7074            cancelIntentSenderLocked(rec, true);
7075        }
7076    }
7077
7078    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7079        rec.canceled = true;
7080        mIntentSenderRecords.remove(rec.key);
7081        if (cleanActivity && rec.key.activity != null) {
7082            rec.key.activity.pendingResults.remove(rec.ref);
7083        }
7084    }
7085
7086    @Override
7087    public String getPackageForIntentSender(IIntentSender pendingResult) {
7088        if (!(pendingResult instanceof PendingIntentRecord)) {
7089            return null;
7090        }
7091        try {
7092            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7093            return res.key.packageName;
7094        } catch (ClassCastException e) {
7095        }
7096        return null;
7097    }
7098
7099    @Override
7100    public int getUidForIntentSender(IIntentSender sender) {
7101        if (sender instanceof PendingIntentRecord) {
7102            try {
7103                PendingIntentRecord res = (PendingIntentRecord)sender;
7104                return res.uid;
7105            } catch (ClassCastException e) {
7106            }
7107        }
7108        return -1;
7109    }
7110
7111    @Override
7112    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7113        if (!(pendingResult instanceof PendingIntentRecord)) {
7114            return false;
7115        }
7116        try {
7117            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7118            if (res.key.allIntents == null) {
7119                return false;
7120            }
7121            for (int i=0; i<res.key.allIntents.length; i++) {
7122                Intent intent = res.key.allIntents[i];
7123                if (intent.getPackage() != null && intent.getComponent() != null) {
7124                    return false;
7125                }
7126            }
7127            return true;
7128        } catch (ClassCastException e) {
7129        }
7130        return false;
7131    }
7132
7133    @Override
7134    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7135        if (!(pendingResult instanceof PendingIntentRecord)) {
7136            return false;
7137        }
7138        try {
7139            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7140            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7141                return true;
7142            }
7143            return false;
7144        } catch (ClassCastException e) {
7145        }
7146        return false;
7147    }
7148
7149    @Override
7150    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7151        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7152                "getIntentForIntentSender()");
7153        if (!(pendingResult instanceof PendingIntentRecord)) {
7154            return null;
7155        }
7156        try {
7157            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7158            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7159        } catch (ClassCastException e) {
7160        }
7161        return null;
7162    }
7163
7164    @Override
7165    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7166        if (!(pendingResult instanceof PendingIntentRecord)) {
7167            return null;
7168        }
7169        try {
7170            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7171            synchronized (this) {
7172                return getTagForIntentSenderLocked(res, prefix);
7173            }
7174        } catch (ClassCastException e) {
7175        }
7176        return null;
7177    }
7178
7179    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7180        final Intent intent = res.key.requestIntent;
7181        if (intent != null) {
7182            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7183                    || res.lastTagPrefix.equals(prefix))) {
7184                return res.lastTag;
7185            }
7186            res.lastTagPrefix = prefix;
7187            final StringBuilder sb = new StringBuilder(128);
7188            if (prefix != null) {
7189                sb.append(prefix);
7190            }
7191            if (intent.getAction() != null) {
7192                sb.append(intent.getAction());
7193            } else if (intent.getComponent() != null) {
7194                intent.getComponent().appendShortString(sb);
7195            } else {
7196                sb.append("?");
7197            }
7198            return res.lastTag = sb.toString();
7199        }
7200        return null;
7201    }
7202
7203    @Override
7204    public void setProcessLimit(int max) {
7205        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7206                "setProcessLimit()");
7207        synchronized (this) {
7208            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7209            mProcessLimitOverride = max;
7210        }
7211        trimApplications();
7212    }
7213
7214    @Override
7215    public int getProcessLimit() {
7216        synchronized (this) {
7217            return mProcessLimitOverride;
7218        }
7219    }
7220
7221    void foregroundTokenDied(ForegroundToken token) {
7222        synchronized (ActivityManagerService.this) {
7223            synchronized (mPidsSelfLocked) {
7224                ForegroundToken cur
7225                    = mForegroundProcesses.get(token.pid);
7226                if (cur != token) {
7227                    return;
7228                }
7229                mForegroundProcesses.remove(token.pid);
7230                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7231                if (pr == null) {
7232                    return;
7233                }
7234                pr.forcingToForeground = null;
7235                updateProcessForegroundLocked(pr, false, false);
7236            }
7237            updateOomAdjLocked();
7238        }
7239    }
7240
7241    @Override
7242    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7243        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7244                "setProcessForeground()");
7245        synchronized(this) {
7246            boolean changed = false;
7247
7248            synchronized (mPidsSelfLocked) {
7249                ProcessRecord pr = mPidsSelfLocked.get(pid);
7250                if (pr == null && isForeground) {
7251                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7252                    return;
7253                }
7254                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7255                if (oldToken != null) {
7256                    oldToken.token.unlinkToDeath(oldToken, 0);
7257                    mForegroundProcesses.remove(pid);
7258                    if (pr != null) {
7259                        pr.forcingToForeground = null;
7260                    }
7261                    changed = true;
7262                }
7263                if (isForeground && token != null) {
7264                    ForegroundToken newToken = new ForegroundToken() {
7265                        @Override
7266                        public void binderDied() {
7267                            foregroundTokenDied(this);
7268                        }
7269                    };
7270                    newToken.pid = pid;
7271                    newToken.token = token;
7272                    try {
7273                        token.linkToDeath(newToken, 0);
7274                        mForegroundProcesses.put(pid, newToken);
7275                        pr.forcingToForeground = token;
7276                        changed = true;
7277                    } catch (RemoteException e) {
7278                        // If the process died while doing this, we will later
7279                        // do the cleanup with the process death link.
7280                    }
7281                }
7282            }
7283
7284            if (changed) {
7285                updateOomAdjLocked();
7286            }
7287        }
7288    }
7289
7290    @Override
7291    public boolean isAppForeground(int uid) throws RemoteException {
7292        synchronized (this) {
7293            UidRecord uidRec = mActiveUids.get(uid);
7294            if (uidRec == null || uidRec.idle) {
7295                return false;
7296            }
7297            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7298        }
7299    }
7300
7301    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7302    // be guarded by permission checking.
7303    int getUidState(int uid) {
7304        synchronized (this) {
7305            UidRecord uidRec = mActiveUids.get(uid);
7306            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7307        }
7308    }
7309
7310    @Override
7311    public boolean isInMultiWindowMode(IBinder token) {
7312        final long origId = Binder.clearCallingIdentity();
7313        try {
7314            synchronized(this) {
7315                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7316                if (r == null) {
7317                    return false;
7318                }
7319                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7320                return !r.task.mFullscreen;
7321            }
7322        } finally {
7323            Binder.restoreCallingIdentity(origId);
7324        }
7325    }
7326
7327    @Override
7328    public boolean isInPictureInPictureMode(IBinder token) {
7329        final long origId = Binder.clearCallingIdentity();
7330        try {
7331            synchronized(this) {
7332                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7333                if (stack == null) {
7334                    return false;
7335                }
7336                return stack.mStackId == PINNED_STACK_ID;
7337            }
7338        } finally {
7339            Binder.restoreCallingIdentity(origId);
7340        }
7341    }
7342
7343    @Override
7344    public void enterPictureInPictureMode(IBinder token) {
7345        final long origId = Binder.clearCallingIdentity();
7346        try {
7347            synchronized(this) {
7348                if (!mSupportsPictureInPicture) {
7349                    throw new IllegalStateException("enterPictureInPictureMode: "
7350                            + "Device doesn't support picture-in-picture mode.");
7351                }
7352
7353                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7354
7355                if (r == null) {
7356                    throw new IllegalStateException("enterPictureInPictureMode: "
7357                            + "Can't find activity for token=" + token);
7358                }
7359
7360                if (!r.supportsPictureInPicture()) {
7361                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7362                            + "Picture-In-Picture not supported for r=" + r);
7363                }
7364
7365                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7366                // current bounds.
7367                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7368                final Rect bounds = (pinnedStack != null)
7369                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7370
7371                mStackSupervisor.moveActivityToPinnedStackLocked(
7372                        r, "enterPictureInPictureMode", bounds);
7373            }
7374        } finally {
7375            Binder.restoreCallingIdentity(origId);
7376        }
7377    }
7378
7379    // =========================================================
7380    // PROCESS INFO
7381    // =========================================================
7382
7383    static class ProcessInfoService extends IProcessInfoService.Stub {
7384        final ActivityManagerService mActivityManagerService;
7385        ProcessInfoService(ActivityManagerService activityManagerService) {
7386            mActivityManagerService = activityManagerService;
7387        }
7388
7389        @Override
7390        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7391            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7392                    /*in*/ pids, /*out*/ states, null);
7393        }
7394
7395        @Override
7396        public void getProcessStatesAndOomScoresFromPids(
7397                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7398            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7399                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7400        }
7401    }
7402
7403    /**
7404     * For each PID in the given input array, write the current process state
7405     * for that process into the states array, or -1 to indicate that no
7406     * process with the given PID exists. If scores array is provided, write
7407     * the oom score for the process into the scores array, with INVALID_ADJ
7408     * indicating the PID doesn't exist.
7409     */
7410    public void getProcessStatesAndOomScoresForPIDs(
7411            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7412        if (scores != null) {
7413            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7414                    "getProcessStatesAndOomScoresForPIDs()");
7415        }
7416
7417        if (pids == null) {
7418            throw new NullPointerException("pids");
7419        } else if (states == null) {
7420            throw new NullPointerException("states");
7421        } else if (pids.length != states.length) {
7422            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7423        } else if (scores != null && pids.length != scores.length) {
7424            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7425        }
7426
7427        synchronized (mPidsSelfLocked) {
7428            for (int i = 0; i < pids.length; i++) {
7429                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7430                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7431                        pr.curProcState;
7432                if (scores != null) {
7433                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7434                }
7435            }
7436        }
7437    }
7438
7439    // =========================================================
7440    // PERMISSIONS
7441    // =========================================================
7442
7443    static class PermissionController extends IPermissionController.Stub {
7444        ActivityManagerService mActivityManagerService;
7445        PermissionController(ActivityManagerService activityManagerService) {
7446            mActivityManagerService = activityManagerService;
7447        }
7448
7449        @Override
7450        public boolean checkPermission(String permission, int pid, int uid) {
7451            return mActivityManagerService.checkPermission(permission, pid,
7452                    uid) == PackageManager.PERMISSION_GRANTED;
7453        }
7454
7455        @Override
7456        public String[] getPackagesForUid(int uid) {
7457            return mActivityManagerService.mContext.getPackageManager()
7458                    .getPackagesForUid(uid);
7459        }
7460
7461        @Override
7462        public boolean isRuntimePermission(String permission) {
7463            try {
7464                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7465                        .getPermissionInfo(permission, 0);
7466                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7467            } catch (NameNotFoundException nnfe) {
7468                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7469            }
7470            return false;
7471        }
7472    }
7473
7474    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7475        @Override
7476        public int checkComponentPermission(String permission, int pid, int uid,
7477                int owningUid, boolean exported) {
7478            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7479                    owningUid, exported);
7480        }
7481
7482        @Override
7483        public Object getAMSLock() {
7484            return ActivityManagerService.this;
7485        }
7486    }
7487
7488    /**
7489     * This can be called with or without the global lock held.
7490     */
7491    int checkComponentPermission(String permission, int pid, int uid,
7492            int owningUid, boolean exported) {
7493        if (pid == MY_PID) {
7494            return PackageManager.PERMISSION_GRANTED;
7495        }
7496        return ActivityManager.checkComponentPermission(permission, uid,
7497                owningUid, exported);
7498    }
7499
7500    /**
7501     * As the only public entry point for permissions checking, this method
7502     * can enforce the semantic that requesting a check on a null global
7503     * permission is automatically denied.  (Internally a null permission
7504     * string is used when calling {@link #checkComponentPermission} in cases
7505     * when only uid-based security is needed.)
7506     *
7507     * This can be called with or without the global lock held.
7508     */
7509    @Override
7510    public int checkPermission(String permission, int pid, int uid) {
7511        if (permission == null) {
7512            return PackageManager.PERMISSION_DENIED;
7513        }
7514        return checkComponentPermission(permission, pid, uid, -1, true);
7515    }
7516
7517    @Override
7518    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7519        if (permission == null) {
7520            return PackageManager.PERMISSION_DENIED;
7521        }
7522
7523        // We might be performing an operation on behalf of an indirect binder
7524        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7525        // client identity accordingly before proceeding.
7526        Identity tlsIdentity = sCallerIdentity.get();
7527        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7528            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7529                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7530            uid = tlsIdentity.uid;
7531            pid = tlsIdentity.pid;
7532        }
7533
7534        return checkComponentPermission(permission, pid, uid, -1, true);
7535    }
7536
7537    /**
7538     * Binder IPC calls go through the public entry point.
7539     * This can be called with or without the global lock held.
7540     */
7541    int checkCallingPermission(String permission) {
7542        return checkPermission(permission,
7543                Binder.getCallingPid(),
7544                UserHandle.getAppId(Binder.getCallingUid()));
7545    }
7546
7547    /**
7548     * This can be called with or without the global lock held.
7549     */
7550    void enforceCallingPermission(String permission, String func) {
7551        if (checkCallingPermission(permission)
7552                == PackageManager.PERMISSION_GRANTED) {
7553            return;
7554        }
7555
7556        String msg = "Permission Denial: " + func + " from pid="
7557                + Binder.getCallingPid()
7558                + ", uid=" + Binder.getCallingUid()
7559                + " requires " + permission;
7560        Slog.w(TAG, msg);
7561        throw new SecurityException(msg);
7562    }
7563
7564    /**
7565     * Determine if UID is holding permissions required to access {@link Uri} in
7566     * the given {@link ProviderInfo}. Final permission checking is always done
7567     * in {@link ContentProvider}.
7568     */
7569    private final boolean checkHoldingPermissionsLocked(
7570            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7571        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7572                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7573        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7574            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7575                    != PERMISSION_GRANTED) {
7576                return false;
7577            }
7578        }
7579        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7580    }
7581
7582    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7583            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7584        if (pi.applicationInfo.uid == uid) {
7585            return true;
7586        } else if (!pi.exported) {
7587            return false;
7588        }
7589
7590        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7591        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7592        try {
7593            // check if target holds top-level <provider> permissions
7594            if (!readMet && pi.readPermission != null && considerUidPermissions
7595                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7596                readMet = true;
7597            }
7598            if (!writeMet && pi.writePermission != null && considerUidPermissions
7599                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7600                writeMet = true;
7601            }
7602
7603            // track if unprotected read/write is allowed; any denied
7604            // <path-permission> below removes this ability
7605            boolean allowDefaultRead = pi.readPermission == null;
7606            boolean allowDefaultWrite = pi.writePermission == null;
7607
7608            // check if target holds any <path-permission> that match uri
7609            final PathPermission[] pps = pi.pathPermissions;
7610            if (pps != null) {
7611                final String path = grantUri.uri.getPath();
7612                int i = pps.length;
7613                while (i > 0 && (!readMet || !writeMet)) {
7614                    i--;
7615                    PathPermission pp = pps[i];
7616                    if (pp.match(path)) {
7617                        if (!readMet) {
7618                            final String pprperm = pp.getReadPermission();
7619                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7620                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7621                                    + ": match=" + pp.match(path)
7622                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7623                            if (pprperm != null) {
7624                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7625                                        == PERMISSION_GRANTED) {
7626                                    readMet = true;
7627                                } else {
7628                                    allowDefaultRead = false;
7629                                }
7630                            }
7631                        }
7632                        if (!writeMet) {
7633                            final String ppwperm = pp.getWritePermission();
7634                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7635                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7636                                    + ": match=" + pp.match(path)
7637                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7638                            if (ppwperm != null) {
7639                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7640                                        == PERMISSION_GRANTED) {
7641                                    writeMet = true;
7642                                } else {
7643                                    allowDefaultWrite = false;
7644                                }
7645                            }
7646                        }
7647                    }
7648                }
7649            }
7650
7651            // grant unprotected <provider> read/write, if not blocked by
7652            // <path-permission> above
7653            if (allowDefaultRead) readMet = true;
7654            if (allowDefaultWrite) writeMet = true;
7655
7656        } catch (RemoteException e) {
7657            return false;
7658        }
7659
7660        return readMet && writeMet;
7661    }
7662
7663    public int getAppStartMode(int uid, String packageName) {
7664        synchronized (this) {
7665            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7666        }
7667    }
7668
7669    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7670            boolean allowWhenForeground) {
7671        UidRecord uidRec = mActiveUids.get(uid);
7672        if (!mLenientBackgroundCheck) {
7673            if (!allowWhenForeground || uidRec == null
7674                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7675                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7676                        packageName) != AppOpsManager.MODE_ALLOWED) {
7677                    return ActivityManager.APP_START_MODE_DELAYED;
7678                }
7679            }
7680
7681        } else if (uidRec == null || uidRec.idle) {
7682            if (callingPid >= 0) {
7683                ProcessRecord proc;
7684                synchronized (mPidsSelfLocked) {
7685                    proc = mPidsSelfLocked.get(callingPid);
7686                }
7687                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7688                    // Whoever is instigating this is in the foreground, so we will allow it
7689                    // to go through.
7690                    return ActivityManager.APP_START_MODE_NORMAL;
7691                }
7692            }
7693            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7694                    != AppOpsManager.MODE_ALLOWED) {
7695                return ActivityManager.APP_START_MODE_DELAYED;
7696            }
7697        }
7698        return ActivityManager.APP_START_MODE_NORMAL;
7699    }
7700
7701    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7702        ProviderInfo pi = null;
7703        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7704        if (cpr != null) {
7705            pi = cpr.info;
7706        } else {
7707            try {
7708                pi = AppGlobals.getPackageManager().resolveContentProvider(
7709                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7710            } catch (RemoteException ex) {
7711            }
7712        }
7713        return pi;
7714    }
7715
7716    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7717        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7718        if (targetUris != null) {
7719            return targetUris.get(grantUri);
7720        }
7721        return null;
7722    }
7723
7724    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7725            String targetPkg, int targetUid, GrantUri grantUri) {
7726        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7727        if (targetUris == null) {
7728            targetUris = Maps.newArrayMap();
7729            mGrantedUriPermissions.put(targetUid, targetUris);
7730        }
7731
7732        UriPermission perm = targetUris.get(grantUri);
7733        if (perm == null) {
7734            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7735            targetUris.put(grantUri, perm);
7736        }
7737
7738        return perm;
7739    }
7740
7741    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7742            final int modeFlags) {
7743        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7744        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7745                : UriPermission.STRENGTH_OWNED;
7746
7747        // Root gets to do everything.
7748        if (uid == 0) {
7749            return true;
7750        }
7751
7752        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7753        if (perms == null) return false;
7754
7755        // First look for exact match
7756        final UriPermission exactPerm = perms.get(grantUri);
7757        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7758            return true;
7759        }
7760
7761        // No exact match, look for prefixes
7762        final int N = perms.size();
7763        for (int i = 0; i < N; i++) {
7764            final UriPermission perm = perms.valueAt(i);
7765            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7766                    && perm.getStrength(modeFlags) >= minStrength) {
7767                return true;
7768            }
7769        }
7770
7771        return false;
7772    }
7773
7774    /**
7775     * @param uri This uri must NOT contain an embedded userId.
7776     * @param userId The userId in which the uri is to be resolved.
7777     */
7778    @Override
7779    public int checkUriPermission(Uri uri, int pid, int uid,
7780            final int modeFlags, int userId, IBinder callerToken) {
7781        enforceNotIsolatedCaller("checkUriPermission");
7782
7783        // Another redirected-binder-call permissions check as in
7784        // {@link checkPermissionWithToken}.
7785        Identity tlsIdentity = sCallerIdentity.get();
7786        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7787            uid = tlsIdentity.uid;
7788            pid = tlsIdentity.pid;
7789        }
7790
7791        // Our own process gets to do everything.
7792        if (pid == MY_PID) {
7793            return PackageManager.PERMISSION_GRANTED;
7794        }
7795        synchronized (this) {
7796            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7797                    ? PackageManager.PERMISSION_GRANTED
7798                    : PackageManager.PERMISSION_DENIED;
7799        }
7800    }
7801
7802    /**
7803     * Check if the targetPkg can be granted permission to access uri by
7804     * the callingUid using the given modeFlags.  Throws a security exception
7805     * if callingUid is not allowed to do this.  Returns the uid of the target
7806     * if the URI permission grant should be performed; returns -1 if it is not
7807     * needed (for example targetPkg already has permission to access the URI).
7808     * If you already know the uid of the target, you can supply it in
7809     * lastTargetUid else set that to -1.
7810     */
7811    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7812            final int modeFlags, int lastTargetUid) {
7813        if (!Intent.isAccessUriMode(modeFlags)) {
7814            return -1;
7815        }
7816
7817        if (targetPkg != null) {
7818            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7819                    "Checking grant " + targetPkg + " permission to " + grantUri);
7820        }
7821
7822        final IPackageManager pm = AppGlobals.getPackageManager();
7823
7824        // If this is not a content: uri, we can't do anything with it.
7825        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7826            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7827                    "Can't grant URI permission for non-content URI: " + grantUri);
7828            return -1;
7829        }
7830
7831        final String authority = grantUri.uri.getAuthority();
7832        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7833        if (pi == null) {
7834            Slog.w(TAG, "No content provider found for permission check: " +
7835                    grantUri.uri.toSafeString());
7836            return -1;
7837        }
7838
7839        int targetUid = lastTargetUid;
7840        if (targetUid < 0 && targetPkg != null) {
7841            try {
7842                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7843                        UserHandle.getUserId(callingUid));
7844                if (targetUid < 0) {
7845                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7846                            "Can't grant URI permission no uid for: " + targetPkg);
7847                    return -1;
7848                }
7849            } catch (RemoteException ex) {
7850                return -1;
7851            }
7852        }
7853
7854        if (targetUid >= 0) {
7855            // First...  does the target actually need this permission?
7856            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7857                // No need to grant the target this permission.
7858                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7859                        "Target " + targetPkg + " already has full permission to " + grantUri);
7860                return -1;
7861            }
7862        } else {
7863            // First...  there is no target package, so can anyone access it?
7864            boolean allowed = pi.exported;
7865            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7866                if (pi.readPermission != null) {
7867                    allowed = false;
7868                }
7869            }
7870            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7871                if (pi.writePermission != null) {
7872                    allowed = false;
7873                }
7874            }
7875            if (allowed) {
7876                return -1;
7877            }
7878        }
7879
7880        /* There is a special cross user grant if:
7881         * - The target is on another user.
7882         * - Apps on the current user can access the uri without any uid permissions.
7883         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7884         * grant uri permissions.
7885         */
7886        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7887                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7888                modeFlags, false /*without considering the uid permissions*/);
7889
7890        // Second...  is the provider allowing granting of URI permissions?
7891        if (!specialCrossUserGrant) {
7892            if (!pi.grantUriPermissions) {
7893                throw new SecurityException("Provider " + pi.packageName
7894                        + "/" + pi.name
7895                        + " does not allow granting of Uri permissions (uri "
7896                        + grantUri + ")");
7897            }
7898            if (pi.uriPermissionPatterns != null) {
7899                final int N = pi.uriPermissionPatterns.length;
7900                boolean allowed = false;
7901                for (int i=0; i<N; i++) {
7902                    if (pi.uriPermissionPatterns[i] != null
7903                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7904                        allowed = true;
7905                        break;
7906                    }
7907                }
7908                if (!allowed) {
7909                    throw new SecurityException("Provider " + pi.packageName
7910                            + "/" + pi.name
7911                            + " does not allow granting of permission to path of Uri "
7912                            + grantUri);
7913                }
7914            }
7915        }
7916
7917        // Third...  does the caller itself have permission to access
7918        // this uri?
7919        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7920            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7921                // Require they hold a strong enough Uri permission
7922                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7923                    throw new SecurityException("Uid " + callingUid
7924                            + " does not have permission to uri " + grantUri);
7925                }
7926            }
7927        }
7928        return targetUid;
7929    }
7930
7931    /**
7932     * @param uri This uri must NOT contain an embedded userId.
7933     * @param userId The userId in which the uri is to be resolved.
7934     */
7935    @Override
7936    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7937            final int modeFlags, int userId) {
7938        enforceNotIsolatedCaller("checkGrantUriPermission");
7939        synchronized(this) {
7940            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7941                    new GrantUri(userId, uri, false), modeFlags, -1);
7942        }
7943    }
7944
7945    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7946            final int modeFlags, UriPermissionOwner owner) {
7947        if (!Intent.isAccessUriMode(modeFlags)) {
7948            return;
7949        }
7950
7951        // So here we are: the caller has the assumed permission
7952        // to the uri, and the target doesn't.  Let's now give this to
7953        // the target.
7954
7955        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7956                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7957
7958        final String authority = grantUri.uri.getAuthority();
7959        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7960        if (pi == null) {
7961            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7962            return;
7963        }
7964
7965        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7966            grantUri.prefix = true;
7967        }
7968        final UriPermission perm = findOrCreateUriPermissionLocked(
7969                pi.packageName, targetPkg, targetUid, grantUri);
7970        perm.grantModes(modeFlags, owner);
7971    }
7972
7973    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7974            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7975        if (targetPkg == null) {
7976            throw new NullPointerException("targetPkg");
7977        }
7978        int targetUid;
7979        final IPackageManager pm = AppGlobals.getPackageManager();
7980        try {
7981            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7982        } catch (RemoteException ex) {
7983            return;
7984        }
7985
7986        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7987                targetUid);
7988        if (targetUid < 0) {
7989            return;
7990        }
7991
7992        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7993                owner);
7994    }
7995
7996    static class NeededUriGrants extends ArrayList<GrantUri> {
7997        final String targetPkg;
7998        final int targetUid;
7999        final int flags;
8000
8001        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8002            this.targetPkg = targetPkg;
8003            this.targetUid = targetUid;
8004            this.flags = flags;
8005        }
8006    }
8007
8008    /**
8009     * Like checkGrantUriPermissionLocked, but takes an Intent.
8010     */
8011    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8012            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8013        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8014                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8015                + " clip=" + (intent != null ? intent.getClipData() : null)
8016                + " from " + intent + "; flags=0x"
8017                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8018
8019        if (targetPkg == null) {
8020            throw new NullPointerException("targetPkg");
8021        }
8022
8023        if (intent == null) {
8024            return null;
8025        }
8026        Uri data = intent.getData();
8027        ClipData clip = intent.getClipData();
8028        if (data == null && clip == null) {
8029            return null;
8030        }
8031        // Default userId for uris in the intent (if they don't specify it themselves)
8032        int contentUserHint = intent.getContentUserHint();
8033        if (contentUserHint == UserHandle.USER_CURRENT) {
8034            contentUserHint = UserHandle.getUserId(callingUid);
8035        }
8036        final IPackageManager pm = AppGlobals.getPackageManager();
8037        int targetUid;
8038        if (needed != null) {
8039            targetUid = needed.targetUid;
8040        } else {
8041            try {
8042                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8043                        targetUserId);
8044            } catch (RemoteException ex) {
8045                return null;
8046            }
8047            if (targetUid < 0) {
8048                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8049                        "Can't grant URI permission no uid for: " + targetPkg
8050                        + " on user " + targetUserId);
8051                return null;
8052            }
8053        }
8054        if (data != null) {
8055            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8056            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8057                    targetUid);
8058            if (targetUid > 0) {
8059                if (needed == null) {
8060                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8061                }
8062                needed.add(grantUri);
8063            }
8064        }
8065        if (clip != null) {
8066            for (int i=0; i<clip.getItemCount(); i++) {
8067                Uri uri = clip.getItemAt(i).getUri();
8068                if (uri != null) {
8069                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8070                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8071                            targetUid);
8072                    if (targetUid > 0) {
8073                        if (needed == null) {
8074                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8075                        }
8076                        needed.add(grantUri);
8077                    }
8078                } else {
8079                    Intent clipIntent = clip.getItemAt(i).getIntent();
8080                    if (clipIntent != null) {
8081                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8082                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8083                        if (newNeeded != null) {
8084                            needed = newNeeded;
8085                        }
8086                    }
8087                }
8088            }
8089        }
8090
8091        return needed;
8092    }
8093
8094    /**
8095     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8096     */
8097    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8098            UriPermissionOwner owner) {
8099        if (needed != null) {
8100            for (int i=0; i<needed.size(); i++) {
8101                GrantUri grantUri = needed.get(i);
8102                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8103                        grantUri, needed.flags, owner);
8104            }
8105        }
8106    }
8107
8108    void grantUriPermissionFromIntentLocked(int callingUid,
8109            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8110        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8111                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8112        if (needed == null) {
8113            return;
8114        }
8115
8116        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8117    }
8118
8119    /**
8120     * @param uri This uri must NOT contain an embedded userId.
8121     * @param userId The userId in which the uri is to be resolved.
8122     */
8123    @Override
8124    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8125            final int modeFlags, int userId) {
8126        enforceNotIsolatedCaller("grantUriPermission");
8127        GrantUri grantUri = new GrantUri(userId, uri, false);
8128        synchronized(this) {
8129            final ProcessRecord r = getRecordForAppLocked(caller);
8130            if (r == null) {
8131                throw new SecurityException("Unable to find app for caller "
8132                        + caller
8133                        + " when granting permission to uri " + grantUri);
8134            }
8135            if (targetPkg == null) {
8136                throw new IllegalArgumentException("null target");
8137            }
8138            if (grantUri == null) {
8139                throw new IllegalArgumentException("null uri");
8140            }
8141
8142            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8143                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8144                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8145                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8146
8147            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8148                    UserHandle.getUserId(r.uid));
8149        }
8150    }
8151
8152    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8153        if (perm.modeFlags == 0) {
8154            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8155                    perm.targetUid);
8156            if (perms != null) {
8157                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8158                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8159
8160                perms.remove(perm.uri);
8161                if (perms.isEmpty()) {
8162                    mGrantedUriPermissions.remove(perm.targetUid);
8163                }
8164            }
8165        }
8166    }
8167
8168    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8169        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8170                "Revoking all granted permissions to " + grantUri);
8171
8172        final IPackageManager pm = AppGlobals.getPackageManager();
8173        final String authority = grantUri.uri.getAuthority();
8174        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8175        if (pi == null) {
8176            Slog.w(TAG, "No content provider found for permission revoke: "
8177                    + grantUri.toSafeString());
8178            return;
8179        }
8180
8181        // Does the caller have this permission on the URI?
8182        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8183            // If they don't have direct access to the URI, then revoke any
8184            // ownerless URI permissions that have been granted to them.
8185            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8186            if (perms != null) {
8187                boolean persistChanged = false;
8188                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8189                    final UriPermission perm = it.next();
8190                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8191                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8192                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8193                                "Revoking non-owned " + perm.targetUid
8194                                + " permission to " + perm.uri);
8195                        persistChanged |= perm.revokeModes(
8196                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8197                        if (perm.modeFlags == 0) {
8198                            it.remove();
8199                        }
8200                    }
8201                }
8202                if (perms.isEmpty()) {
8203                    mGrantedUriPermissions.remove(callingUid);
8204                }
8205                if (persistChanged) {
8206                    schedulePersistUriGrants();
8207                }
8208            }
8209            return;
8210        }
8211
8212        boolean persistChanged = false;
8213
8214        // Go through all of the permissions and remove any that match.
8215        int N = mGrantedUriPermissions.size();
8216        for (int i = 0; i < N; i++) {
8217            final int targetUid = mGrantedUriPermissions.keyAt(i);
8218            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8219
8220            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8221                final UriPermission perm = it.next();
8222                if (perm.uri.sourceUserId == grantUri.sourceUserId
8223                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8224                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8225                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8226                    persistChanged |= perm.revokeModes(
8227                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8228                    if (perm.modeFlags == 0) {
8229                        it.remove();
8230                    }
8231                }
8232            }
8233
8234            if (perms.isEmpty()) {
8235                mGrantedUriPermissions.remove(targetUid);
8236                N--;
8237                i--;
8238            }
8239        }
8240
8241        if (persistChanged) {
8242            schedulePersistUriGrants();
8243        }
8244    }
8245
8246    /**
8247     * @param uri This uri must NOT contain an embedded userId.
8248     * @param userId The userId in which the uri is to be resolved.
8249     */
8250    @Override
8251    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8252            int userId) {
8253        enforceNotIsolatedCaller("revokeUriPermission");
8254        synchronized(this) {
8255            final ProcessRecord r = getRecordForAppLocked(caller);
8256            if (r == null) {
8257                throw new SecurityException("Unable to find app for caller "
8258                        + caller
8259                        + " when revoking permission to uri " + uri);
8260            }
8261            if (uri == null) {
8262                Slog.w(TAG, "revokeUriPermission: null uri");
8263                return;
8264            }
8265
8266            if (!Intent.isAccessUriMode(modeFlags)) {
8267                return;
8268            }
8269
8270            final String authority = uri.getAuthority();
8271            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8272            if (pi == null) {
8273                Slog.w(TAG, "No content provider found for permission revoke: "
8274                        + uri.toSafeString());
8275                return;
8276            }
8277
8278            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8279        }
8280    }
8281
8282    /**
8283     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8284     * given package.
8285     *
8286     * @param packageName Package name to match, or {@code null} to apply to all
8287     *            packages.
8288     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8289     *            to all users.
8290     * @param persistable If persistable grants should be removed.
8291     */
8292    private void removeUriPermissionsForPackageLocked(
8293            String packageName, int userHandle, boolean persistable) {
8294        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8295            throw new IllegalArgumentException("Must narrow by either package or user");
8296        }
8297
8298        boolean persistChanged = false;
8299
8300        int N = mGrantedUriPermissions.size();
8301        for (int i = 0; i < N; i++) {
8302            final int targetUid = mGrantedUriPermissions.keyAt(i);
8303            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8304
8305            // Only inspect grants matching user
8306            if (userHandle == UserHandle.USER_ALL
8307                    || userHandle == UserHandle.getUserId(targetUid)) {
8308                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8309                    final UriPermission perm = it.next();
8310
8311                    // Only inspect grants matching package
8312                    if (packageName == null || perm.sourcePkg.equals(packageName)
8313                            || perm.targetPkg.equals(packageName)) {
8314                        persistChanged |= perm.revokeModes(persistable
8315                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8316
8317                        // Only remove when no modes remain; any persisted grants
8318                        // will keep this alive.
8319                        if (perm.modeFlags == 0) {
8320                            it.remove();
8321                        }
8322                    }
8323                }
8324
8325                if (perms.isEmpty()) {
8326                    mGrantedUriPermissions.remove(targetUid);
8327                    N--;
8328                    i--;
8329                }
8330            }
8331        }
8332
8333        if (persistChanged) {
8334            schedulePersistUriGrants();
8335        }
8336    }
8337
8338    @Override
8339    public IBinder newUriPermissionOwner(String name) {
8340        enforceNotIsolatedCaller("newUriPermissionOwner");
8341        synchronized(this) {
8342            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8343            return owner.getExternalTokenLocked();
8344        }
8345    }
8346
8347    @Override
8348    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8349        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8350        synchronized(this) {
8351            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8352            if (r == null) {
8353                throw new IllegalArgumentException("Activity does not exist; token="
8354                        + activityToken);
8355            }
8356            return r.getUriPermissionsLocked().getExternalTokenLocked();
8357        }
8358    }
8359    /**
8360     * @param uri This uri must NOT contain an embedded userId.
8361     * @param sourceUserId The userId in which the uri is to be resolved.
8362     * @param targetUserId The userId of the app that receives the grant.
8363     */
8364    @Override
8365    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8366            final int modeFlags, int sourceUserId, int targetUserId) {
8367        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8368                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8369                "grantUriPermissionFromOwner", null);
8370        synchronized(this) {
8371            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8372            if (owner == null) {
8373                throw new IllegalArgumentException("Unknown owner: " + token);
8374            }
8375            if (fromUid != Binder.getCallingUid()) {
8376                if (Binder.getCallingUid() != Process.myUid()) {
8377                    // Only system code can grant URI permissions on behalf
8378                    // of other users.
8379                    throw new SecurityException("nice try");
8380                }
8381            }
8382            if (targetPkg == null) {
8383                throw new IllegalArgumentException("null target");
8384            }
8385            if (uri == null) {
8386                throw new IllegalArgumentException("null uri");
8387            }
8388
8389            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8390                    modeFlags, owner, targetUserId);
8391        }
8392    }
8393
8394    /**
8395     * @param uri This uri must NOT contain an embedded userId.
8396     * @param userId The userId in which the uri is to be resolved.
8397     */
8398    @Override
8399    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8400        synchronized(this) {
8401            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8402            if (owner == null) {
8403                throw new IllegalArgumentException("Unknown owner: " + token);
8404            }
8405
8406            if (uri == null) {
8407                owner.removeUriPermissionsLocked(mode);
8408            } else {
8409                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8410            }
8411        }
8412    }
8413
8414    private void schedulePersistUriGrants() {
8415        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8416            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8417                    10 * DateUtils.SECOND_IN_MILLIS);
8418        }
8419    }
8420
8421    private void writeGrantedUriPermissions() {
8422        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8423
8424        // Snapshot permissions so we can persist without lock
8425        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8426        synchronized (this) {
8427            final int size = mGrantedUriPermissions.size();
8428            for (int i = 0; i < size; i++) {
8429                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8430                for (UriPermission perm : perms.values()) {
8431                    if (perm.persistedModeFlags != 0) {
8432                        persist.add(perm.snapshot());
8433                    }
8434                }
8435            }
8436        }
8437
8438        FileOutputStream fos = null;
8439        try {
8440            fos = mGrantFile.startWrite();
8441
8442            XmlSerializer out = new FastXmlSerializer();
8443            out.setOutput(fos, StandardCharsets.UTF_8.name());
8444            out.startDocument(null, true);
8445            out.startTag(null, TAG_URI_GRANTS);
8446            for (UriPermission.Snapshot perm : persist) {
8447                out.startTag(null, TAG_URI_GRANT);
8448                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8449                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8450                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8451                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8452                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8453                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8454                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8455                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8456                out.endTag(null, TAG_URI_GRANT);
8457            }
8458            out.endTag(null, TAG_URI_GRANTS);
8459            out.endDocument();
8460
8461            mGrantFile.finishWrite(fos);
8462        } catch (IOException e) {
8463            if (fos != null) {
8464                mGrantFile.failWrite(fos);
8465            }
8466        }
8467    }
8468
8469    private void readGrantedUriPermissionsLocked() {
8470        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8471
8472        final long now = System.currentTimeMillis();
8473
8474        FileInputStream fis = null;
8475        try {
8476            fis = mGrantFile.openRead();
8477            final XmlPullParser in = Xml.newPullParser();
8478            in.setInput(fis, StandardCharsets.UTF_8.name());
8479
8480            int type;
8481            while ((type = in.next()) != END_DOCUMENT) {
8482                final String tag = in.getName();
8483                if (type == START_TAG) {
8484                    if (TAG_URI_GRANT.equals(tag)) {
8485                        final int sourceUserId;
8486                        final int targetUserId;
8487                        final int userHandle = readIntAttribute(in,
8488                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8489                        if (userHandle != UserHandle.USER_NULL) {
8490                            // For backwards compatibility.
8491                            sourceUserId = userHandle;
8492                            targetUserId = userHandle;
8493                        } else {
8494                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8495                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8496                        }
8497                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8498                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8499                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8500                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8501                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8502                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8503
8504                        // Sanity check that provider still belongs to source package
8505                        final ProviderInfo pi = getProviderInfoLocked(
8506                                uri.getAuthority(), sourceUserId);
8507                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8508                            int targetUid = -1;
8509                            try {
8510                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8511                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8512                            } catch (RemoteException e) {
8513                            }
8514                            if (targetUid != -1) {
8515                                final UriPermission perm = findOrCreateUriPermissionLocked(
8516                                        sourcePkg, targetPkg, targetUid,
8517                                        new GrantUri(sourceUserId, uri, prefix));
8518                                perm.initPersistedModes(modeFlags, createdTime);
8519                            }
8520                        } else {
8521                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8522                                    + " but instead found " + pi);
8523                        }
8524                    }
8525                }
8526            }
8527        } catch (FileNotFoundException e) {
8528            // Missing grants is okay
8529        } catch (IOException e) {
8530            Slog.wtf(TAG, "Failed reading Uri grants", e);
8531        } catch (XmlPullParserException e) {
8532            Slog.wtf(TAG, "Failed reading Uri grants", e);
8533        } finally {
8534            IoUtils.closeQuietly(fis);
8535        }
8536    }
8537
8538    /**
8539     * @param uri This uri must NOT contain an embedded userId.
8540     * @param userId The userId in which the uri is to be resolved.
8541     */
8542    @Override
8543    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8544        enforceNotIsolatedCaller("takePersistableUriPermission");
8545
8546        Preconditions.checkFlagsArgument(modeFlags,
8547                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8548
8549        synchronized (this) {
8550            final int callingUid = Binder.getCallingUid();
8551            boolean persistChanged = false;
8552            GrantUri grantUri = new GrantUri(userId, uri, false);
8553
8554            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8555                    new GrantUri(userId, uri, false));
8556            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8557                    new GrantUri(userId, uri, true));
8558
8559            final boolean exactValid = (exactPerm != null)
8560                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8561            final boolean prefixValid = (prefixPerm != null)
8562                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8563
8564            if (!(exactValid || prefixValid)) {
8565                throw new SecurityException("No persistable permission grants found for UID "
8566                        + callingUid + " and Uri " + grantUri.toSafeString());
8567            }
8568
8569            if (exactValid) {
8570                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8571            }
8572            if (prefixValid) {
8573                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8574            }
8575
8576            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8577
8578            if (persistChanged) {
8579                schedulePersistUriGrants();
8580            }
8581        }
8582    }
8583
8584    /**
8585     * @param uri This uri must NOT contain an embedded userId.
8586     * @param userId The userId in which the uri is to be resolved.
8587     */
8588    @Override
8589    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8590        enforceNotIsolatedCaller("releasePersistableUriPermission");
8591
8592        Preconditions.checkFlagsArgument(modeFlags,
8593                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8594
8595        synchronized (this) {
8596            final int callingUid = Binder.getCallingUid();
8597            boolean persistChanged = false;
8598
8599            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8600                    new GrantUri(userId, uri, false));
8601            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8602                    new GrantUri(userId, uri, true));
8603            if (exactPerm == null && prefixPerm == null) {
8604                throw new SecurityException("No permission grants found for UID " + callingUid
8605                        + " and Uri " + uri.toSafeString());
8606            }
8607
8608            if (exactPerm != null) {
8609                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8610                removeUriPermissionIfNeededLocked(exactPerm);
8611            }
8612            if (prefixPerm != null) {
8613                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8614                removeUriPermissionIfNeededLocked(prefixPerm);
8615            }
8616
8617            if (persistChanged) {
8618                schedulePersistUriGrants();
8619            }
8620        }
8621    }
8622
8623    /**
8624     * Prune any older {@link UriPermission} for the given UID until outstanding
8625     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8626     *
8627     * @return if any mutations occured that require persisting.
8628     */
8629    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8630        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8631        if (perms == null) return false;
8632        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8633
8634        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8635        for (UriPermission perm : perms.values()) {
8636            if (perm.persistedModeFlags != 0) {
8637                persisted.add(perm);
8638            }
8639        }
8640
8641        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8642        if (trimCount <= 0) return false;
8643
8644        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8645        for (int i = 0; i < trimCount; i++) {
8646            final UriPermission perm = persisted.get(i);
8647
8648            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8649                    "Trimming grant created at " + perm.persistedCreateTime);
8650
8651            perm.releasePersistableModes(~0);
8652            removeUriPermissionIfNeededLocked(perm);
8653        }
8654
8655        return true;
8656    }
8657
8658    @Override
8659    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8660            String packageName, boolean incoming) {
8661        enforceNotIsolatedCaller("getPersistedUriPermissions");
8662        Preconditions.checkNotNull(packageName, "packageName");
8663
8664        final int callingUid = Binder.getCallingUid();
8665        final IPackageManager pm = AppGlobals.getPackageManager();
8666        try {
8667            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8668                    UserHandle.getUserId(callingUid));
8669            if (packageUid != callingUid) {
8670                throw new SecurityException(
8671                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8672            }
8673        } catch (RemoteException e) {
8674            throw new SecurityException("Failed to verify package name ownership");
8675        }
8676
8677        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8678        synchronized (this) {
8679            if (incoming) {
8680                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8681                        callingUid);
8682                if (perms == null) {
8683                    Slog.w(TAG, "No permission grants found for " + packageName);
8684                } else {
8685                    for (UriPermission perm : perms.values()) {
8686                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8687                            result.add(perm.buildPersistedPublicApiObject());
8688                        }
8689                    }
8690                }
8691            } else {
8692                final int size = mGrantedUriPermissions.size();
8693                for (int i = 0; i < size; i++) {
8694                    final ArrayMap<GrantUri, UriPermission> perms =
8695                            mGrantedUriPermissions.valueAt(i);
8696                    for (UriPermission perm : perms.values()) {
8697                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8698                            result.add(perm.buildPersistedPublicApiObject());
8699                        }
8700                    }
8701                }
8702            }
8703        }
8704        return new ParceledListSlice<android.content.UriPermission>(result);
8705    }
8706
8707    @Override
8708    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8709            String packageName, int userId) {
8710        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8711                "getGrantedUriPermissions");
8712
8713        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8714        synchronized (this) {
8715            final int size = mGrantedUriPermissions.size();
8716            for (int i = 0; i < size; i++) {
8717                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8718                for (UriPermission perm : perms.values()) {
8719                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8720                            && perm.persistedModeFlags != 0) {
8721                        result.add(perm.buildPersistedPublicApiObject());
8722                    }
8723                }
8724            }
8725        }
8726        return new ParceledListSlice<android.content.UriPermission>(result);
8727    }
8728
8729    @Override
8730    public void clearGrantedUriPermissions(String packageName, int userId) {
8731        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8732                "clearGrantedUriPermissions");
8733        removeUriPermissionsForPackageLocked(packageName, userId, true);
8734    }
8735
8736    @Override
8737    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8738        synchronized (this) {
8739            ProcessRecord app =
8740                who != null ? getRecordForAppLocked(who) : null;
8741            if (app == null) return;
8742
8743            Message msg = Message.obtain();
8744            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8745            msg.obj = app;
8746            msg.arg1 = waiting ? 1 : 0;
8747            mUiHandler.sendMessage(msg);
8748        }
8749    }
8750
8751    @Override
8752    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8753        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8754        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8755        outInfo.availMem = Process.getFreeMemory();
8756        outInfo.totalMem = Process.getTotalMemory();
8757        outInfo.threshold = homeAppMem;
8758        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8759        outInfo.hiddenAppThreshold = cachedAppMem;
8760        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8761                ProcessList.SERVICE_ADJ);
8762        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8763                ProcessList.VISIBLE_APP_ADJ);
8764        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8765                ProcessList.FOREGROUND_APP_ADJ);
8766    }
8767
8768    // =========================================================
8769    // TASK MANAGEMENT
8770    // =========================================================
8771
8772    @Override
8773    public List<IAppTask> getAppTasks(String callingPackage) {
8774        int callingUid = Binder.getCallingUid();
8775        long ident = Binder.clearCallingIdentity();
8776
8777        synchronized(this) {
8778            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8779            try {
8780                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8781
8782                final int N = mRecentTasks.size();
8783                for (int i = 0; i < N; i++) {
8784                    TaskRecord tr = mRecentTasks.get(i);
8785                    // Skip tasks that do not match the caller.  We don't need to verify
8786                    // callingPackage, because we are also limiting to callingUid and know
8787                    // that will limit to the correct security sandbox.
8788                    if (tr.effectiveUid != callingUid) {
8789                        continue;
8790                    }
8791                    Intent intent = tr.getBaseIntent();
8792                    if (intent == null ||
8793                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8794                        continue;
8795                    }
8796                    ActivityManager.RecentTaskInfo taskInfo =
8797                            createRecentTaskInfoFromTaskRecord(tr);
8798                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8799                    list.add(taskImpl);
8800                }
8801            } finally {
8802                Binder.restoreCallingIdentity(ident);
8803            }
8804            return list;
8805        }
8806    }
8807
8808    @Override
8809    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8810        final int callingUid = Binder.getCallingUid();
8811        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8812
8813        synchronized(this) {
8814            if (DEBUG_ALL) Slog.v(
8815                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8816
8817            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8818                    callingUid);
8819
8820            // TODO: Improve with MRU list from all ActivityStacks.
8821            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8822        }
8823
8824        return list;
8825    }
8826
8827    /**
8828     * Creates a new RecentTaskInfo from a TaskRecord.
8829     */
8830    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8831        // Update the task description to reflect any changes in the task stack
8832        tr.updateTaskDescription();
8833
8834        // Compose the recent task info
8835        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8836        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8837        rti.persistentId = tr.taskId;
8838        rti.baseIntent = new Intent(tr.getBaseIntent());
8839        rti.origActivity = tr.origActivity;
8840        rti.realActivity = tr.realActivity;
8841        rti.description = tr.lastDescription;
8842        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8843        rti.userId = tr.userId;
8844        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8845        rti.firstActiveTime = tr.firstActiveTime;
8846        rti.lastActiveTime = tr.lastActiveTime;
8847        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8848        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8849        rti.numActivities = 0;
8850        if (tr.mBounds != null) {
8851            rti.bounds = new Rect(tr.mBounds);
8852        }
8853        rti.isDockable = tr.canGoInDockedStack();
8854        rti.resizeMode = tr.mResizeMode;
8855
8856        ActivityRecord base = null;
8857        ActivityRecord top = null;
8858        ActivityRecord tmp;
8859
8860        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8861            tmp = tr.mActivities.get(i);
8862            if (tmp.finishing) {
8863                continue;
8864            }
8865            base = tmp;
8866            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8867                top = base;
8868            }
8869            rti.numActivities++;
8870        }
8871
8872        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8873        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8874
8875        return rti;
8876    }
8877
8878    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8879        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8880                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8881        if (!allowed) {
8882            if (checkPermission(android.Manifest.permission.GET_TASKS,
8883                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8884                // Temporary compatibility: some existing apps on the system image may
8885                // still be requesting the old permission and not switched to the new
8886                // one; if so, we'll still allow them full access.  This means we need
8887                // to see if they are holding the old permission and are a system app.
8888                try {
8889                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8890                        allowed = true;
8891                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8892                                + " is using old GET_TASKS but privileged; allowing");
8893                    }
8894                } catch (RemoteException e) {
8895                }
8896            }
8897        }
8898        if (!allowed) {
8899            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8900                    + " does not hold REAL_GET_TASKS; limiting output");
8901        }
8902        return allowed;
8903    }
8904
8905    @Override
8906    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8907        final int callingUid = Binder.getCallingUid();
8908        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8909                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8910
8911        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8912        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8913        synchronized (this) {
8914            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8915                    callingUid);
8916            final boolean detailed = checkCallingPermission(
8917                    android.Manifest.permission.GET_DETAILED_TASKS)
8918                    == PackageManager.PERMISSION_GRANTED;
8919
8920            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8921                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8922                return Collections.emptyList();
8923            }
8924            mRecentTasks.loadUserRecentsLocked(userId);
8925
8926            final int recentsCount = mRecentTasks.size();
8927            ArrayList<ActivityManager.RecentTaskInfo> res =
8928                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8929
8930            final Set<Integer> includedUsers;
8931            if (includeProfiles) {
8932                includedUsers = mUserController.getProfileIds(userId);
8933            } else {
8934                includedUsers = new HashSet<>();
8935            }
8936            includedUsers.add(Integer.valueOf(userId));
8937
8938            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8939                TaskRecord tr = mRecentTasks.get(i);
8940                // Only add calling user or related users recent tasks
8941                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8942                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8943                    continue;
8944                }
8945
8946                if (tr.realActivitySuspended) {
8947                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8948                    continue;
8949                }
8950
8951                // Return the entry if desired by the caller.  We always return
8952                // the first entry, because callers always expect this to be the
8953                // foreground app.  We may filter others if the caller has
8954                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8955                // we should exclude the entry.
8956
8957                if (i == 0
8958                        || withExcluded
8959                        || (tr.intent == null)
8960                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8961                                == 0)) {
8962                    if (!allowed) {
8963                        // If the caller doesn't have the GET_TASKS permission, then only
8964                        // allow them to see a small subset of tasks -- their own and home.
8965                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8966                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8967                            continue;
8968                        }
8969                    }
8970                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8971                        if (tr.stack != null && tr.stack.isHomeStack()) {
8972                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8973                                    "Skipping, home stack task: " + tr);
8974                            continue;
8975                        }
8976                    }
8977                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8978                        final ActivityStack stack = tr.stack;
8979                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8980                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8981                                    "Skipping, top task in docked stack: " + tr);
8982                            continue;
8983                        }
8984                    }
8985                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8986                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8987                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8988                                    "Skipping, pinned stack task: " + tr);
8989                            continue;
8990                        }
8991                    }
8992                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8993                        // Don't include auto remove tasks that are finished or finishing.
8994                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8995                                "Skipping, auto-remove without activity: " + tr);
8996                        continue;
8997                    }
8998                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8999                            && !tr.isAvailable) {
9000                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9001                                "Skipping, unavail real act: " + tr);
9002                        continue;
9003                    }
9004
9005                    if (!tr.mUserSetupComplete) {
9006                        // Don't include task launched while user is not done setting-up.
9007                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9008                                "Skipping, user setup not complete: " + tr);
9009                        continue;
9010                    }
9011
9012                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9013                    if (!detailed) {
9014                        rti.baseIntent.replaceExtras((Bundle)null);
9015                    }
9016
9017                    res.add(rti);
9018                    maxNum--;
9019                }
9020            }
9021            return res;
9022        }
9023    }
9024
9025    @Override
9026    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9027        synchronized (this) {
9028            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9029                    "getTaskThumbnail()");
9030            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9031                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9032            if (tr != null) {
9033                return tr.getTaskThumbnailLocked();
9034            }
9035        }
9036        return null;
9037    }
9038
9039    @Override
9040    public int addAppTask(IBinder activityToken, Intent intent,
9041            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9042        final int callingUid = Binder.getCallingUid();
9043        final long callingIdent = Binder.clearCallingIdentity();
9044
9045        try {
9046            synchronized (this) {
9047                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9048                if (r == null) {
9049                    throw new IllegalArgumentException("Activity does not exist; token="
9050                            + activityToken);
9051                }
9052                ComponentName comp = intent.getComponent();
9053                if (comp == null) {
9054                    throw new IllegalArgumentException("Intent " + intent
9055                            + " must specify explicit component");
9056                }
9057                if (thumbnail.getWidth() != mThumbnailWidth
9058                        || thumbnail.getHeight() != mThumbnailHeight) {
9059                    throw new IllegalArgumentException("Bad thumbnail size: got "
9060                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9061                            + mThumbnailWidth + "x" + mThumbnailHeight);
9062                }
9063                if (intent.getSelector() != null) {
9064                    intent.setSelector(null);
9065                }
9066                if (intent.getSourceBounds() != null) {
9067                    intent.setSourceBounds(null);
9068                }
9069                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9070                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9071                        // The caller has added this as an auto-remove task...  that makes no
9072                        // sense, so turn off auto-remove.
9073                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9074                    }
9075                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9076                    // Must be a new task.
9077                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9078                }
9079                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9080                    mLastAddedTaskActivity = null;
9081                }
9082                ActivityInfo ainfo = mLastAddedTaskActivity;
9083                if (ainfo == null) {
9084                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9085                            comp, 0, UserHandle.getUserId(callingUid));
9086                    if (ainfo.applicationInfo.uid != callingUid) {
9087                        throw new SecurityException(
9088                                "Can't add task for another application: target uid="
9089                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9090                    }
9091                }
9092
9093                // Use the full screen as the context for the task thumbnail
9094                final Point displaySize = new Point();
9095                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9096                r.task.stack.getDisplaySize(displaySize);
9097                thumbnailInfo.taskWidth = displaySize.x;
9098                thumbnailInfo.taskHeight = displaySize.y;
9099                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9100
9101                TaskRecord task = new TaskRecord(this,
9102                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9103                        ainfo, intent, description, thumbnailInfo);
9104
9105                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9106                if (trimIdx >= 0) {
9107                    // If this would have caused a trim, then we'll abort because that
9108                    // means it would be added at the end of the list but then just removed.
9109                    return INVALID_TASK_ID;
9110                }
9111
9112                final int N = mRecentTasks.size();
9113                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9114                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9115                    tr.removedFromRecents();
9116                }
9117
9118                task.inRecents = true;
9119                mRecentTasks.add(task);
9120                r.task.stack.addTask(task, false, "addAppTask");
9121
9122                task.setLastThumbnailLocked(thumbnail);
9123                task.freeLastThumbnail();
9124
9125                return task.taskId;
9126            }
9127        } finally {
9128            Binder.restoreCallingIdentity(callingIdent);
9129        }
9130    }
9131
9132    @Override
9133    public Point getAppTaskThumbnailSize() {
9134        synchronized (this) {
9135            return new Point(mThumbnailWidth,  mThumbnailHeight);
9136        }
9137    }
9138
9139    @Override
9140    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9141        synchronized (this) {
9142            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9143            if (r != null) {
9144                r.setTaskDescription(td);
9145                r.task.updateTaskDescription();
9146            }
9147        }
9148    }
9149
9150    @Override
9151    public void setTaskResizeable(int taskId, int resizeableMode) {
9152        synchronized (this) {
9153            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9154                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9155            if (task == null) {
9156                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9157                return;
9158            }
9159            if (task.mResizeMode != resizeableMode) {
9160                task.mResizeMode = resizeableMode;
9161                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9162                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9163                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9164            }
9165        }
9166    }
9167
9168    @Override
9169    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9170        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9171        long ident = Binder.clearCallingIdentity();
9172        try {
9173            synchronized (this) {
9174                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9175                if (task == null) {
9176                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9177                    return;
9178                }
9179                int stackId = task.stack.mStackId;
9180                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9181                // in crop windows resize mode or if the task size is affected by the docked stack
9182                // changing size. No need to update configuration.
9183                if (bounds != null && task.inCropWindowsResizeMode()
9184                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9185                    mWindowManager.scrollTask(task.taskId, bounds);
9186                    return;
9187                }
9188
9189                // Place the task in the right stack if it isn't there already based on
9190                // the requested bounds.
9191                // The stack transition logic is:
9192                // - a null bounds on a freeform task moves that task to fullscreen
9193                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9194                //   that task to freeform
9195                // - otherwise the task is not moved
9196                if (!StackId.isTaskResizeAllowed(stackId)) {
9197                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9198                }
9199                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9200                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9201                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9202                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9203                }
9204                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9205                if (stackId != task.stack.mStackId) {
9206                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9207                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9208                    preserveWindow = false;
9209                }
9210
9211                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9212                        false /* deferResume */);
9213            }
9214        } finally {
9215            Binder.restoreCallingIdentity(ident);
9216        }
9217    }
9218
9219    @Override
9220    public Rect getTaskBounds(int taskId) {
9221        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9222        long ident = Binder.clearCallingIdentity();
9223        Rect rect = new Rect();
9224        try {
9225            synchronized (this) {
9226                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9227                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9228                if (task == null) {
9229                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9230                    return rect;
9231                }
9232                if (task.stack != null) {
9233                    // Return the bounds from window manager since it will be adjusted for various
9234                    // things like the presense of a docked stack for tasks that aren't resizeable.
9235                    mWindowManager.getTaskBounds(task.taskId, rect);
9236                } else {
9237                    // Task isn't in window manager yet since it isn't associated with a stack.
9238                    // Return the persist value from activity manager
9239                    if (task.mBounds != null) {
9240                        rect.set(task.mBounds);
9241                    } else if (task.mLastNonFullscreenBounds != null) {
9242                        rect.set(task.mLastNonFullscreenBounds);
9243                    }
9244                }
9245            }
9246        } finally {
9247            Binder.restoreCallingIdentity(ident);
9248        }
9249        return rect;
9250    }
9251
9252    @Override
9253    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9254        if (userId != UserHandle.getCallingUserId()) {
9255            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9256                    "getTaskDescriptionIcon");
9257        }
9258        final File passedIconFile = new File(filePath);
9259        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9260                passedIconFile.getName());
9261        if (!legitIconFile.getPath().equals(filePath)
9262                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9263            throw new IllegalArgumentException("Bad file path: " + filePath
9264                    + " passed for userId " + userId);
9265        }
9266        return mRecentTasks.getTaskDescriptionIcon(filePath);
9267    }
9268
9269    @Override
9270    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9271            throws RemoteException {
9272        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9273                opts.getCustomInPlaceResId() == 0) {
9274            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9275                    "with valid animation");
9276        }
9277        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9278        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9279                opts.getCustomInPlaceResId());
9280        mWindowManager.executeAppTransition();
9281    }
9282
9283    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9284            boolean removeFromRecents) {
9285        if (removeFromRecents) {
9286            mRecentTasks.remove(tr);
9287            tr.removedFromRecents();
9288        }
9289        ComponentName component = tr.getBaseIntent().getComponent();
9290        if (component == null) {
9291            Slog.w(TAG, "No component for base intent of task: " + tr);
9292            return;
9293        }
9294
9295        // Find any running services associated with this app and stop if needed.
9296        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9297
9298        if (!killProcess) {
9299            return;
9300        }
9301
9302        // Determine if the process(es) for this task should be killed.
9303        final String pkg = component.getPackageName();
9304        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9305        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9306        for (int i = 0; i < pmap.size(); i++) {
9307
9308            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9309            for (int j = 0; j < uids.size(); j++) {
9310                ProcessRecord proc = uids.valueAt(j);
9311                if (proc.userId != tr.userId) {
9312                    // Don't kill process for a different user.
9313                    continue;
9314                }
9315                if (proc == mHomeProcess) {
9316                    // Don't kill the home process along with tasks from the same package.
9317                    continue;
9318                }
9319                if (!proc.pkgList.containsKey(pkg)) {
9320                    // Don't kill process that is not associated with this task.
9321                    continue;
9322                }
9323
9324                for (int k = 0; k < proc.activities.size(); k++) {
9325                    TaskRecord otherTask = proc.activities.get(k).task;
9326                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9327                        // Don't kill process(es) that has an activity in a different task that is
9328                        // also in recents.
9329                        return;
9330                    }
9331                }
9332
9333                if (proc.foregroundServices) {
9334                    // Don't kill process(es) with foreground service.
9335                    return;
9336                }
9337
9338                // Add process to kill list.
9339                procsToKill.add(proc);
9340            }
9341        }
9342
9343        // Kill the running processes.
9344        for (int i = 0; i < procsToKill.size(); i++) {
9345            ProcessRecord pr = procsToKill.get(i);
9346            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9347                    && pr.curReceiver == null) {
9348                pr.kill("remove task", true);
9349            } else {
9350                // We delay killing processes that are not in the background or running a receiver.
9351                pr.waitingToKill = "remove task";
9352            }
9353        }
9354    }
9355
9356    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9357        // Remove all tasks with activities in the specified package from the list of recent tasks
9358        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9359            TaskRecord tr = mRecentTasks.get(i);
9360            if (tr.userId != userId) continue;
9361
9362            ComponentName cn = tr.intent.getComponent();
9363            if (cn != null && cn.getPackageName().equals(packageName)) {
9364                // If the package name matches, remove the task.
9365                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9366            }
9367        }
9368    }
9369
9370    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9371            int userId) {
9372
9373        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9374            TaskRecord tr = mRecentTasks.get(i);
9375            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9376                continue;
9377            }
9378
9379            ComponentName cn = tr.intent.getComponent();
9380            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9381                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9382            if (sameComponent) {
9383                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9384            }
9385        }
9386    }
9387
9388    /**
9389     * Removes the task with the specified task id.
9390     *
9391     * @param taskId Identifier of the task to be removed.
9392     * @param killProcess Kill any process associated with the task if possible.
9393     * @param removeFromRecents Whether to also remove the task from recents.
9394     * @return Returns true if the given task was found and removed.
9395     */
9396    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9397            boolean removeFromRecents) {
9398        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9399                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9400        if (tr != null) {
9401            tr.removeTaskActivitiesLocked();
9402            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9403            if (tr.isPersistable) {
9404                notifyTaskPersisterLocked(null, true);
9405            }
9406            return true;
9407        }
9408        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9409        return false;
9410    }
9411
9412    @Override
9413    public void removeStack(int stackId) {
9414        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9415        if (stackId == HOME_STACK_ID) {
9416            throw new IllegalArgumentException("Removing home stack is not allowed.");
9417        }
9418
9419        synchronized (this) {
9420            final long ident = Binder.clearCallingIdentity();
9421            try {
9422                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9423                if (stack == null) {
9424                    return;
9425                }
9426                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9427                for (int i = tasks.size() - 1; i >= 0; i--) {
9428                    removeTaskByIdLocked(
9429                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9430                }
9431            } finally {
9432                Binder.restoreCallingIdentity(ident);
9433            }
9434        }
9435    }
9436
9437    @Override
9438    public boolean removeTask(int taskId) {
9439        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9440        synchronized (this) {
9441            final long ident = Binder.clearCallingIdentity();
9442            try {
9443                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9444            } finally {
9445                Binder.restoreCallingIdentity(ident);
9446            }
9447        }
9448    }
9449
9450    /**
9451     * TODO: Add mController hook
9452     */
9453    @Override
9454    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9455        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9456
9457        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9458        synchronized(this) {
9459            moveTaskToFrontLocked(taskId, flags, bOptions);
9460        }
9461    }
9462
9463    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9464        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9465
9466        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9467                Binder.getCallingUid(), -1, -1, "Task to front")) {
9468            ActivityOptions.abort(options);
9469            return;
9470        }
9471        final long origId = Binder.clearCallingIdentity();
9472        try {
9473            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9474            if (task == null) {
9475                Slog.d(TAG, "Could not find task for id: "+ taskId);
9476                return;
9477            }
9478            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9479                mStackSupervisor.showLockTaskToast();
9480                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9481                return;
9482            }
9483            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9484            if (prev != null && prev.isRecentsActivity()) {
9485                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9486            }
9487            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9488                    false /* forceNonResizable */);
9489        } finally {
9490            Binder.restoreCallingIdentity(origId);
9491        }
9492        ActivityOptions.abort(options);
9493    }
9494
9495    /**
9496     * Moves an activity, and all of the other activities within the same task, to the bottom
9497     * of the history stack.  The activity's order within the task is unchanged.
9498     *
9499     * @param token A reference to the activity we wish to move
9500     * @param nonRoot If false then this only works if the activity is the root
9501     *                of a task; if true it will work for any activity in a task.
9502     * @return Returns true if the move completed, false if not.
9503     */
9504    @Override
9505    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9506        enforceNotIsolatedCaller("moveActivityTaskToBack");
9507        synchronized(this) {
9508            final long origId = Binder.clearCallingIdentity();
9509            try {
9510                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9511                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9512                if (task != null) {
9513                    if (mStackSupervisor.isLockedTask(task)) {
9514                        mStackSupervisor.showLockTaskToast();
9515                        return false;
9516                    }
9517                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9518                }
9519            } finally {
9520                Binder.restoreCallingIdentity(origId);
9521            }
9522        }
9523        return false;
9524    }
9525
9526    @Override
9527    public void moveTaskBackwards(int task) {
9528        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9529                "moveTaskBackwards()");
9530
9531        synchronized(this) {
9532            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9533                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9534                return;
9535            }
9536            final long origId = Binder.clearCallingIdentity();
9537            moveTaskBackwardsLocked(task);
9538            Binder.restoreCallingIdentity(origId);
9539        }
9540    }
9541
9542    private final void moveTaskBackwardsLocked(int task) {
9543        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9544    }
9545
9546    @Override
9547    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9548            IActivityContainerCallback callback) throws RemoteException {
9549        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9550        synchronized (this) {
9551            if (parentActivityToken == null) {
9552                throw new IllegalArgumentException("parent token must not be null");
9553            }
9554            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9555            if (r == null) {
9556                return null;
9557            }
9558            if (callback == null) {
9559                throw new IllegalArgumentException("callback must not be null");
9560            }
9561            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9562        }
9563    }
9564
9565    @Override
9566    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9567        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9568        synchronized (this) {
9569            mStackSupervisor.deleteActivityContainer(container);
9570        }
9571    }
9572
9573    @Override
9574    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9575        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9576        synchronized (this) {
9577            final int stackId = mStackSupervisor.getNextStackId();
9578            final ActivityStack stack =
9579                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9580            if (stack == null) {
9581                return null;
9582            }
9583            return stack.mActivityContainer;
9584        }
9585    }
9586
9587    @Override
9588    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9589        synchronized (this) {
9590            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9591            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9592                return stack.mActivityContainer.getDisplayId();
9593            }
9594            return Display.DEFAULT_DISPLAY;
9595        }
9596    }
9597
9598    @Override
9599    public int getActivityStackId(IBinder token) throws RemoteException {
9600        synchronized (this) {
9601            ActivityStack stack = ActivityRecord.getStackLocked(token);
9602            if (stack == null) {
9603                return INVALID_STACK_ID;
9604            }
9605            return stack.mStackId;
9606        }
9607    }
9608
9609    @Override
9610    public void exitFreeformMode(IBinder token) throws RemoteException {
9611        synchronized (this) {
9612            long ident = Binder.clearCallingIdentity();
9613            try {
9614                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9615                if (r == null) {
9616                    throw new IllegalArgumentException(
9617                            "exitFreeformMode: No activity record matching token=" + token);
9618                }
9619                final ActivityStack stack = r.getStackLocked(token);
9620                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9621                    throw new IllegalStateException(
9622                            "exitFreeformMode: You can only go fullscreen from freeform.");
9623                }
9624                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9625                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9626                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9627            } finally {
9628                Binder.restoreCallingIdentity(ident);
9629            }
9630        }
9631    }
9632
9633    @Override
9634    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9635        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9636        if (stackId == HOME_STACK_ID) {
9637            throw new IllegalArgumentException(
9638                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9639        }
9640        synchronized (this) {
9641            long ident = Binder.clearCallingIdentity();
9642            try {
9643                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9644                        + " to stackId=" + stackId + " toTop=" + toTop);
9645                if (stackId == DOCKED_STACK_ID) {
9646                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9647                            null /* initialBounds */);
9648                }
9649                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9650                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9651                if (result && stackId == DOCKED_STACK_ID) {
9652                    // If task moved to docked stack - show recents if needed.
9653                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9654                            "moveTaskToDockedStack");
9655                }
9656            } finally {
9657                Binder.restoreCallingIdentity(ident);
9658            }
9659        }
9660    }
9661
9662    @Override
9663    public void swapDockedAndFullscreenStack() throws RemoteException {
9664        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9665        synchronized (this) {
9666            long ident = Binder.clearCallingIdentity();
9667            try {
9668                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9669                        FULLSCREEN_WORKSPACE_STACK_ID);
9670                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9671                        : null;
9672                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9673                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9674                        : null;
9675                if (topTask == null || tasks == null || tasks.size() == 0) {
9676                    Slog.w(TAG,
9677                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9678                    return;
9679                }
9680
9681                // TODO: App transition
9682                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9683
9684                // Defer the resume so resume/pausing while moving stacks is dangerous.
9685                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9686                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9687                        ANIMATE, true /* deferResume */);
9688                final int size = tasks.size();
9689                for (int i = 0; i < size; i++) {
9690                    final int id = tasks.get(i).taskId;
9691                    if (id == topTask.taskId) {
9692                        continue;
9693                    }
9694                    mStackSupervisor.moveTaskToStackLocked(id,
9695                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9696                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9697                }
9698
9699                // Because we deferred the resume, to avoid conflicts with stack switches while
9700                // resuming, we need to do it after all the tasks are moved.
9701                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9702                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9703
9704                mWindowManager.executeAppTransition();
9705            } finally {
9706                Binder.restoreCallingIdentity(ident);
9707            }
9708        }
9709    }
9710
9711    /**
9712     * Moves the input task to the docked stack.
9713     *
9714     * @param taskId Id of task to move.
9715     * @param createMode The mode the docked stack should be created in if it doesn't exist
9716     *                   already. See
9717     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9718     *                   and
9719     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9720     * @param toTop If the task and stack should be moved to the top.
9721     * @param animate Whether we should play an animation for the moving the task
9722     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9723     *                      docked stack. Pass {@code null} to use default bounds.
9724     */
9725    @Override
9726    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9727            Rect initialBounds, boolean moveHomeStackFront) {
9728        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9729        synchronized (this) {
9730            long ident = Binder.clearCallingIdentity();
9731            try {
9732                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9733                        + " to createMode=" + createMode + " toTop=" + toTop);
9734                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9735                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9736                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9737                        animate, DEFER_RESUME);
9738                if (moved) {
9739                    if (moveHomeStackFront) {
9740                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9741                    }
9742                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9743                }
9744                return moved;
9745            } finally {
9746                Binder.restoreCallingIdentity(ident);
9747            }
9748        }
9749    }
9750
9751    /**
9752     * Moves the top activity in the input stackId to the pinned stack.
9753     *
9754     * @param stackId Id of stack to move the top activity to pinned stack.
9755     * @param bounds Bounds to use for pinned stack.
9756     *
9757     * @return True if the top activity of the input stack was successfully moved to the pinned
9758     *          stack.
9759     */
9760    @Override
9761    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9762        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9763        synchronized (this) {
9764            if (!mSupportsPictureInPicture) {
9765                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9766                        + "Device doesn't support picture-in-pciture mode");
9767            }
9768
9769            long ident = Binder.clearCallingIdentity();
9770            try {
9771                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9772            } finally {
9773                Binder.restoreCallingIdentity(ident);
9774            }
9775        }
9776    }
9777
9778    @Override
9779    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9780            boolean preserveWindows, boolean animate, int animationDuration) {
9781        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9782        long ident = Binder.clearCallingIdentity();
9783        try {
9784            synchronized (this) {
9785                if (animate) {
9786                    if (stackId == PINNED_STACK_ID) {
9787                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9788                    } else {
9789                        throw new IllegalArgumentException("Stack: " + stackId
9790                                + " doesn't support animated resize.");
9791                    }
9792                } else {
9793                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9794                            null /* tempTaskInsetBounds */, preserveWindows,
9795                            allowResizeInDockedMode, !DEFER_RESUME);
9796                }
9797            }
9798        } finally {
9799            Binder.restoreCallingIdentity(ident);
9800        }
9801    }
9802
9803    @Override
9804    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9805            Rect tempDockedTaskInsetBounds,
9806            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9807        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9808                "resizeDockedStack()");
9809        long ident = Binder.clearCallingIdentity();
9810        try {
9811            synchronized (this) {
9812                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9813                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9814                        PRESERVE_WINDOWS);
9815            }
9816        } finally {
9817            Binder.restoreCallingIdentity(ident);
9818        }
9819    }
9820
9821    @Override
9822    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9823        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9824                "resizePinnedStack()");
9825        final long ident = Binder.clearCallingIdentity();
9826        try {
9827            synchronized (this) {
9828                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9829            }
9830        } finally {
9831            Binder.restoreCallingIdentity(ident);
9832        }
9833    }
9834
9835    @Override
9836    public void positionTaskInStack(int taskId, int stackId, int position) {
9837        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9838        if (stackId == HOME_STACK_ID) {
9839            throw new IllegalArgumentException(
9840                    "positionTaskInStack: Attempt to change the position of task "
9841                    + taskId + " in/to home stack");
9842        }
9843        synchronized (this) {
9844            long ident = Binder.clearCallingIdentity();
9845            try {
9846                if (DEBUG_STACK) Slog.d(TAG_STACK,
9847                        "positionTaskInStack: positioning task=" + taskId
9848                        + " in stackId=" + stackId + " at position=" + position);
9849                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9850            } finally {
9851                Binder.restoreCallingIdentity(ident);
9852            }
9853        }
9854    }
9855
9856    @Override
9857    public List<StackInfo> getAllStackInfos() {
9858        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9859        long ident = Binder.clearCallingIdentity();
9860        try {
9861            synchronized (this) {
9862                return mStackSupervisor.getAllStackInfosLocked();
9863            }
9864        } finally {
9865            Binder.restoreCallingIdentity(ident);
9866        }
9867    }
9868
9869    @Override
9870    public StackInfo getStackInfo(int stackId) {
9871        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9872        long ident = Binder.clearCallingIdentity();
9873        try {
9874            synchronized (this) {
9875                return mStackSupervisor.getStackInfoLocked(stackId);
9876            }
9877        } finally {
9878            Binder.restoreCallingIdentity(ident);
9879        }
9880    }
9881
9882    @Override
9883    public boolean isInHomeStack(int taskId) {
9884        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9885        long ident = Binder.clearCallingIdentity();
9886        try {
9887            synchronized (this) {
9888                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9889                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9890                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9891            }
9892        } finally {
9893            Binder.restoreCallingIdentity(ident);
9894        }
9895    }
9896
9897    @Override
9898    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9899        synchronized(this) {
9900            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9901        }
9902    }
9903
9904    @Override
9905    public void updateDeviceOwner(String packageName) {
9906        final int callingUid = Binder.getCallingUid();
9907        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9908            throw new SecurityException("updateDeviceOwner called from non-system process");
9909        }
9910        synchronized (this) {
9911            mDeviceOwnerName = packageName;
9912        }
9913    }
9914
9915    @Override
9916    public void updateLockTaskPackages(int userId, String[] packages) {
9917        final int callingUid = Binder.getCallingUid();
9918        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9919            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9920                    "updateLockTaskPackages()");
9921        }
9922        synchronized (this) {
9923            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9924                    Arrays.toString(packages));
9925            mLockTaskPackages.put(userId, packages);
9926            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9927        }
9928    }
9929
9930
9931    void startLockTaskModeLocked(TaskRecord task) {
9932        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9933        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9934            return;
9935        }
9936
9937        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9938        // is initiated by system after the pinning request was shown and locked mode is initiated
9939        // by an authorized app directly
9940        final int callingUid = Binder.getCallingUid();
9941        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9942        long ident = Binder.clearCallingIdentity();
9943        try {
9944            if (!isSystemInitiated) {
9945                task.mLockTaskUid = callingUid;
9946                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9947                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9948                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9949                    StatusBarManagerInternal statusBarManager =
9950                            LocalServices.getService(StatusBarManagerInternal.class);
9951                    if (statusBarManager != null) {
9952                        statusBarManager.showScreenPinningRequest(task.taskId);
9953                    }
9954                    return;
9955                }
9956
9957                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9958                if (stack == null || task != stack.topTask()) {
9959                    throw new IllegalArgumentException("Invalid task, not in foreground");
9960                }
9961            }
9962            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9963                    "Locking fully");
9964            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9965                    ActivityManager.LOCK_TASK_MODE_PINNED :
9966                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9967                    "startLockTask", true);
9968        } finally {
9969            Binder.restoreCallingIdentity(ident);
9970        }
9971    }
9972
9973    @Override
9974    public void startLockTaskMode(int taskId) {
9975        synchronized (this) {
9976            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9977            if (task != null) {
9978                startLockTaskModeLocked(task);
9979            }
9980        }
9981    }
9982
9983    @Override
9984    public void startLockTaskMode(IBinder token) {
9985        synchronized (this) {
9986            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9987            if (r == null) {
9988                return;
9989            }
9990            final TaskRecord task = r.task;
9991            if (task != null) {
9992                startLockTaskModeLocked(task);
9993            }
9994        }
9995    }
9996
9997    @Override
9998    public void startSystemLockTaskMode(int taskId) throws RemoteException {
9999        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10000        // This makes inner call to look as if it was initiated by system.
10001        long ident = Binder.clearCallingIdentity();
10002        try {
10003            synchronized (this) {
10004                startLockTaskMode(taskId);
10005            }
10006        } finally {
10007            Binder.restoreCallingIdentity(ident);
10008        }
10009    }
10010
10011    @Override
10012    public void stopLockTaskMode() {
10013        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10014        if (lockTask == null) {
10015            // Our work here is done.
10016            return;
10017        }
10018
10019        final int callingUid = Binder.getCallingUid();
10020        final int lockTaskUid = lockTask.mLockTaskUid;
10021        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10022        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10023            // Done.
10024            return;
10025        } else {
10026            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10027            // It is possible lockTaskMode was started by the system process because
10028            // android:lockTaskMode is set to a locking value in the application manifest
10029            // instead of the app calling startLockTaskMode. In this case
10030            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10031            // {@link TaskRecord.effectiveUid} instead. Also caller with
10032            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10033            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10034                    && callingUid != lockTaskUid
10035                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10036                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10037                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10038            }
10039        }
10040        long ident = Binder.clearCallingIdentity();
10041        try {
10042            Log.d(TAG, "stopLockTaskMode");
10043            // Stop lock task
10044            synchronized (this) {
10045                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10046                        "stopLockTask", true);
10047            }
10048        } finally {
10049            Binder.restoreCallingIdentity(ident);
10050        }
10051    }
10052
10053    /**
10054     * This API should be called by SystemUI only when user perform certain action to dismiss
10055     * lock task mode. We should only dismiss pinned lock task mode in this case.
10056     */
10057    @Override
10058    public void stopSystemLockTaskMode() throws RemoteException {
10059        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10060            stopLockTaskMode();
10061        } else {
10062            mStackSupervisor.showLockTaskToast();
10063        }
10064    }
10065
10066    @Override
10067    public boolean isInLockTaskMode() {
10068        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10069    }
10070
10071    @Override
10072    public int getLockTaskModeState() {
10073        synchronized (this) {
10074            return mStackSupervisor.getLockTaskModeState();
10075        }
10076    }
10077
10078    @Override
10079    public void showLockTaskEscapeMessage(IBinder token) {
10080        synchronized (this) {
10081            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10082            if (r == null) {
10083                return;
10084            }
10085            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10086        }
10087    }
10088
10089    // =========================================================
10090    // CONTENT PROVIDERS
10091    // =========================================================
10092
10093    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10094        List<ProviderInfo> providers = null;
10095        try {
10096            providers = AppGlobals.getPackageManager()
10097                    .queryContentProviders(app.processName, app.uid,
10098                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10099                                    | MATCH_DEBUG_TRIAGED_MISSING)
10100                    .getList();
10101        } catch (RemoteException ex) {
10102        }
10103        if (DEBUG_MU) Slog.v(TAG_MU,
10104                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10105        int userId = app.userId;
10106        if (providers != null) {
10107            int N = providers.size();
10108            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10109            for (int i=0; i<N; i++) {
10110                ProviderInfo cpi =
10111                    (ProviderInfo)providers.get(i);
10112                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10113                        cpi.name, cpi.flags);
10114                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10115                    // This is a singleton provider, but a user besides the
10116                    // default user is asking to initialize a process it runs
10117                    // in...  well, no, it doesn't actually run in this process,
10118                    // it runs in the process of the default user.  Get rid of it.
10119                    providers.remove(i);
10120                    N--;
10121                    i--;
10122                    continue;
10123                }
10124
10125                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10126                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10127                if (cpr == null) {
10128                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10129                    mProviderMap.putProviderByClass(comp, cpr);
10130                }
10131                if (DEBUG_MU) Slog.v(TAG_MU,
10132                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10133                app.pubProviders.put(cpi.name, cpr);
10134                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10135                    // Don't add this if it is a platform component that is marked
10136                    // to run in multiple processes, because this is actually
10137                    // part of the framework so doesn't make sense to track as a
10138                    // separate apk in the process.
10139                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10140                            mProcessStats);
10141                }
10142                notifyPackageUse(cpi.applicationInfo.packageName,
10143                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10144            }
10145        }
10146        return providers;
10147    }
10148
10149    /**
10150     * Check if {@link ProcessRecord} has a possible chance at accessing the
10151     * given {@link ProviderInfo}. Final permission checking is always done
10152     * in {@link ContentProvider}.
10153     */
10154    private final String checkContentProviderPermissionLocked(
10155            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10156        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10157        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10158        boolean checkedGrants = false;
10159        if (checkUser) {
10160            // Looking for cross-user grants before enforcing the typical cross-users permissions
10161            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10162            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10163                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10164                    return null;
10165                }
10166                checkedGrants = true;
10167            }
10168            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10169                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10170            if (userId != tmpTargetUserId) {
10171                // When we actually went to determine the final targer user ID, this ended
10172                // up different than our initial check for the authority.  This is because
10173                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10174                // SELF.  So we need to re-check the grants again.
10175                checkedGrants = false;
10176            }
10177        }
10178        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10179                cpi.applicationInfo.uid, cpi.exported)
10180                == PackageManager.PERMISSION_GRANTED) {
10181            return null;
10182        }
10183        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10184                cpi.applicationInfo.uid, cpi.exported)
10185                == PackageManager.PERMISSION_GRANTED) {
10186            return null;
10187        }
10188
10189        PathPermission[] pps = cpi.pathPermissions;
10190        if (pps != null) {
10191            int i = pps.length;
10192            while (i > 0) {
10193                i--;
10194                PathPermission pp = pps[i];
10195                String pprperm = pp.getReadPermission();
10196                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10197                        cpi.applicationInfo.uid, cpi.exported)
10198                        == PackageManager.PERMISSION_GRANTED) {
10199                    return null;
10200                }
10201                String ppwperm = pp.getWritePermission();
10202                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10203                        cpi.applicationInfo.uid, cpi.exported)
10204                        == PackageManager.PERMISSION_GRANTED) {
10205                    return null;
10206                }
10207            }
10208        }
10209        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10210            return null;
10211        }
10212
10213        String msg;
10214        if (!cpi.exported) {
10215            msg = "Permission Denial: opening provider " + cpi.name
10216                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10217                    + ", uid=" + callingUid + ") that is not exported from uid "
10218                    + cpi.applicationInfo.uid;
10219        } else {
10220            msg = "Permission Denial: opening provider " + cpi.name
10221                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10222                    + ", uid=" + callingUid + ") requires "
10223                    + cpi.readPermission + " or " + cpi.writePermission;
10224        }
10225        Slog.w(TAG, msg);
10226        return msg;
10227    }
10228
10229    /**
10230     * Returns if the ContentProvider has granted a uri to callingUid
10231     */
10232    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10233        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10234        if (perms != null) {
10235            for (int i=perms.size()-1; i>=0; i--) {
10236                GrantUri grantUri = perms.keyAt(i);
10237                if (grantUri.sourceUserId == userId || !checkUser) {
10238                    if (matchesProvider(grantUri.uri, cpi)) {
10239                        return true;
10240                    }
10241                }
10242            }
10243        }
10244        return false;
10245    }
10246
10247    /**
10248     * Returns true if the uri authority is one of the authorities specified in the provider.
10249     */
10250    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10251        String uriAuth = uri.getAuthority();
10252        String cpiAuth = cpi.authority;
10253        if (cpiAuth.indexOf(';') == -1) {
10254            return cpiAuth.equals(uriAuth);
10255        }
10256        String[] cpiAuths = cpiAuth.split(";");
10257        int length = cpiAuths.length;
10258        for (int i = 0; i < length; i++) {
10259            if (cpiAuths[i].equals(uriAuth)) return true;
10260        }
10261        return false;
10262    }
10263
10264    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10265            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10266        if (r != null) {
10267            for (int i=0; i<r.conProviders.size(); i++) {
10268                ContentProviderConnection conn = r.conProviders.get(i);
10269                if (conn.provider == cpr) {
10270                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10271                            "Adding provider requested by "
10272                            + r.processName + " from process "
10273                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10274                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10275                    if (stable) {
10276                        conn.stableCount++;
10277                        conn.numStableIncs++;
10278                    } else {
10279                        conn.unstableCount++;
10280                        conn.numUnstableIncs++;
10281                    }
10282                    return conn;
10283                }
10284            }
10285            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10286            if (stable) {
10287                conn.stableCount = 1;
10288                conn.numStableIncs = 1;
10289            } else {
10290                conn.unstableCount = 1;
10291                conn.numUnstableIncs = 1;
10292            }
10293            cpr.connections.add(conn);
10294            r.conProviders.add(conn);
10295            startAssociationLocked(r.uid, r.processName, r.curProcState,
10296                    cpr.uid, cpr.name, cpr.info.processName);
10297            return conn;
10298        }
10299        cpr.addExternalProcessHandleLocked(externalProcessToken);
10300        return null;
10301    }
10302
10303    boolean decProviderCountLocked(ContentProviderConnection conn,
10304            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10305        if (conn != null) {
10306            cpr = conn.provider;
10307            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10308                    "Removing provider requested by "
10309                    + conn.client.processName + " from process "
10310                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10311                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10312            if (stable) {
10313                conn.stableCount--;
10314            } else {
10315                conn.unstableCount--;
10316            }
10317            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10318                cpr.connections.remove(conn);
10319                conn.client.conProviders.remove(conn);
10320                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10321                    // The client is more important than last activity -- note the time this
10322                    // is happening, so we keep the old provider process around a bit as last
10323                    // activity to avoid thrashing it.
10324                    if (cpr.proc != null) {
10325                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10326                    }
10327                }
10328                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10329                return true;
10330            }
10331            return false;
10332        }
10333        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10334        return false;
10335    }
10336
10337    private void checkTime(long startTime, String where) {
10338        long now = SystemClock.uptimeMillis();
10339        if ((now-startTime) > 50) {
10340            // If we are taking more than 50ms, log about it.
10341            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10342        }
10343    }
10344
10345    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10346            String name, IBinder token, boolean stable, int userId) {
10347        ContentProviderRecord cpr;
10348        ContentProviderConnection conn = null;
10349        ProviderInfo cpi = null;
10350
10351        synchronized(this) {
10352            long startTime = SystemClock.uptimeMillis();
10353
10354            ProcessRecord r = null;
10355            if (caller != null) {
10356                r = getRecordForAppLocked(caller);
10357                if (r == null) {
10358                    throw new SecurityException(
10359                            "Unable to find app for caller " + caller
10360                          + " (pid=" + Binder.getCallingPid()
10361                          + ") when getting content provider " + name);
10362                }
10363            }
10364
10365            boolean checkCrossUser = true;
10366
10367            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10368
10369            // First check if this content provider has been published...
10370            cpr = mProviderMap.getProviderByName(name, userId);
10371            // If that didn't work, check if it exists for user 0 and then
10372            // verify that it's a singleton provider before using it.
10373            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10374                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10375                if (cpr != null) {
10376                    cpi = cpr.info;
10377                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10378                            cpi.name, cpi.flags)
10379                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10380                        userId = UserHandle.USER_SYSTEM;
10381                        checkCrossUser = false;
10382                    } else {
10383                        cpr = null;
10384                        cpi = null;
10385                    }
10386                }
10387            }
10388
10389            boolean providerRunning = cpr != null;
10390            if (providerRunning) {
10391                cpi = cpr.info;
10392                String msg;
10393                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10394                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10395                        != null) {
10396                    throw new SecurityException(msg);
10397                }
10398                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10399
10400                if (r != null && cpr.canRunHere(r)) {
10401                    // This provider has been published or is in the process
10402                    // of being published...  but it is also allowed to run
10403                    // in the caller's process, so don't make a connection
10404                    // and just let the caller instantiate its own instance.
10405                    ContentProviderHolder holder = cpr.newHolder(null);
10406                    // don't give caller the provider object, it needs
10407                    // to make its own.
10408                    holder.provider = null;
10409                    return holder;
10410                }
10411
10412                final long origId = Binder.clearCallingIdentity();
10413
10414                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10415
10416                // In this case the provider instance already exists, so we can
10417                // return it right away.
10418                conn = incProviderCountLocked(r, cpr, token, stable);
10419                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10420                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10421                        // If this is a perceptible app accessing the provider,
10422                        // make sure to count it as being accessed and thus
10423                        // back up on the LRU list.  This is good because
10424                        // content providers are often expensive to start.
10425                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10426                        updateLruProcessLocked(cpr.proc, false, null);
10427                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10428                    }
10429                }
10430
10431                if (cpr.proc != null) {
10432                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10433                    boolean success = updateOomAdjLocked(cpr.proc);
10434                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10435                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10436                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10437                    // NOTE: there is still a race here where a signal could be
10438                    // pending on the process even though we managed to update its
10439                    // adj level.  Not sure what to do about this, but at least
10440                    // the race is now smaller.
10441                    if (!success) {
10442                        // Uh oh...  it looks like the provider's process
10443                        // has been killed on us.  We need to wait for a new
10444                        // process to be started, and make sure its death
10445                        // doesn't kill our process.
10446                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10447                                + " is crashing; detaching " + r);
10448                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10449                        checkTime(startTime, "getContentProviderImpl: before appDied");
10450                        appDiedLocked(cpr.proc);
10451                        checkTime(startTime, "getContentProviderImpl: after appDied");
10452                        if (!lastRef) {
10453                            // This wasn't the last ref our process had on
10454                            // the provider...  we have now been killed, bail.
10455                            return null;
10456                        }
10457                        providerRunning = false;
10458                        conn = null;
10459                    }
10460                }
10461
10462                Binder.restoreCallingIdentity(origId);
10463            }
10464
10465            if (!providerRunning) {
10466                try {
10467                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10468                    cpi = AppGlobals.getPackageManager().
10469                        resolveContentProvider(name,
10470                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10471                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10472                } catch (RemoteException ex) {
10473                }
10474                if (cpi == null) {
10475                    return null;
10476                }
10477                // If the provider is a singleton AND
10478                // (it's a call within the same user || the provider is a
10479                // privileged app)
10480                // Then allow connecting to the singleton provider
10481                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10482                        cpi.name, cpi.flags)
10483                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10484                if (singleton) {
10485                    userId = UserHandle.USER_SYSTEM;
10486                }
10487                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10488                checkTime(startTime, "getContentProviderImpl: got app info for user");
10489
10490                String msg;
10491                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10492                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10493                        != null) {
10494                    throw new SecurityException(msg);
10495                }
10496                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10497
10498                if (!mProcessesReady
10499                        && !cpi.processName.equals("system")) {
10500                    // If this content provider does not run in the system
10501                    // process, and the system is not yet ready to run other
10502                    // processes, then fail fast instead of hanging.
10503                    throw new IllegalArgumentException(
10504                            "Attempt to launch content provider before system ready");
10505                }
10506
10507                // Make sure that the user who owns this provider is running.  If not,
10508                // we don't want to allow it to run.
10509                if (!mUserController.isUserRunningLocked(userId, 0)) {
10510                    Slog.w(TAG, "Unable to launch app "
10511                            + cpi.applicationInfo.packageName + "/"
10512                            + cpi.applicationInfo.uid + " for provider "
10513                            + name + ": user " + userId + " is stopped");
10514                    return null;
10515                }
10516
10517                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10518                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10519                cpr = mProviderMap.getProviderByClass(comp, userId);
10520                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10521                final boolean firstClass = cpr == null;
10522                if (firstClass) {
10523                    final long ident = Binder.clearCallingIdentity();
10524
10525                    // If permissions need a review before any of the app components can run,
10526                    // we return no provider and launch a review activity if the calling app
10527                    // is in the foreground.
10528                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10529                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10530                            return null;
10531                        }
10532                    }
10533
10534                    try {
10535                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10536                        ApplicationInfo ai =
10537                            AppGlobals.getPackageManager().
10538                                getApplicationInfo(
10539                                        cpi.applicationInfo.packageName,
10540                                        STOCK_PM_FLAGS, userId);
10541                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10542                        if (ai == null) {
10543                            Slog.w(TAG, "No package info for content provider "
10544                                    + cpi.name);
10545                            return null;
10546                        }
10547                        ai = getAppInfoForUser(ai, userId);
10548                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10549                    } catch (RemoteException ex) {
10550                        // pm is in same process, this will never happen.
10551                    } finally {
10552                        Binder.restoreCallingIdentity(ident);
10553                    }
10554                }
10555
10556                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10557
10558                if (r != null && cpr.canRunHere(r)) {
10559                    // If this is a multiprocess provider, then just return its
10560                    // info and allow the caller to instantiate it.  Only do
10561                    // this if the provider is the same user as the caller's
10562                    // process, or can run as root (so can be in any process).
10563                    return cpr.newHolder(null);
10564                }
10565
10566                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10567                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10568                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10569
10570                // This is single process, and our app is now connecting to it.
10571                // See if we are already in the process of launching this
10572                // provider.
10573                final int N = mLaunchingProviders.size();
10574                int i;
10575                for (i = 0; i < N; i++) {
10576                    if (mLaunchingProviders.get(i) == cpr) {
10577                        break;
10578                    }
10579                }
10580
10581                // If the provider is not already being launched, then get it
10582                // started.
10583                if (i >= N) {
10584                    final long origId = Binder.clearCallingIdentity();
10585
10586                    try {
10587                        // Content provider is now in use, its package can't be stopped.
10588                        try {
10589                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10590                            AppGlobals.getPackageManager().setPackageStoppedState(
10591                                    cpr.appInfo.packageName, false, userId);
10592                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10593                        } catch (RemoteException e) {
10594                        } catch (IllegalArgumentException e) {
10595                            Slog.w(TAG, "Failed trying to unstop package "
10596                                    + cpr.appInfo.packageName + ": " + e);
10597                        }
10598
10599                        // Use existing process if already started
10600                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10601                        ProcessRecord proc = getProcessRecordLocked(
10602                                cpi.processName, cpr.appInfo.uid, false);
10603                        if (proc != null && proc.thread != null) {
10604                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10605                                    "Installing in existing process " + proc);
10606                            if (!proc.pubProviders.containsKey(cpi.name)) {
10607                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10608                                proc.pubProviders.put(cpi.name, cpr);
10609                                try {
10610                                    proc.thread.scheduleInstallProvider(cpi);
10611                                } catch (RemoteException e) {
10612                                }
10613                            }
10614                        } else {
10615                            checkTime(startTime, "getContentProviderImpl: before start process");
10616                            proc = startProcessLocked(cpi.processName,
10617                                    cpr.appInfo, false, 0, "content provider",
10618                                    new ComponentName(cpi.applicationInfo.packageName,
10619                                            cpi.name), false, false, false);
10620                            checkTime(startTime, "getContentProviderImpl: after start process");
10621                            if (proc == null) {
10622                                Slog.w(TAG, "Unable to launch app "
10623                                        + cpi.applicationInfo.packageName + "/"
10624                                        + cpi.applicationInfo.uid + " for provider "
10625                                        + name + ": process is bad");
10626                                return null;
10627                            }
10628                        }
10629                        cpr.launchingApp = proc;
10630                        mLaunchingProviders.add(cpr);
10631                    } finally {
10632                        Binder.restoreCallingIdentity(origId);
10633                    }
10634                }
10635
10636                checkTime(startTime, "getContentProviderImpl: updating data structures");
10637
10638                // Make sure the provider is published (the same provider class
10639                // may be published under multiple names).
10640                if (firstClass) {
10641                    mProviderMap.putProviderByClass(comp, cpr);
10642                }
10643
10644                mProviderMap.putProviderByName(name, cpr);
10645                conn = incProviderCountLocked(r, cpr, token, stable);
10646                if (conn != null) {
10647                    conn.waiting = true;
10648                }
10649            }
10650            checkTime(startTime, "getContentProviderImpl: done!");
10651        }
10652
10653        // Wait for the provider to be published...
10654        synchronized (cpr) {
10655            while (cpr.provider == null) {
10656                if (cpr.launchingApp == null) {
10657                    Slog.w(TAG, "Unable to launch app "
10658                            + cpi.applicationInfo.packageName + "/"
10659                            + cpi.applicationInfo.uid + " for provider "
10660                            + name + ": launching app became null");
10661                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10662                            UserHandle.getUserId(cpi.applicationInfo.uid),
10663                            cpi.applicationInfo.packageName,
10664                            cpi.applicationInfo.uid, name);
10665                    return null;
10666                }
10667                try {
10668                    if (DEBUG_MU) Slog.v(TAG_MU,
10669                            "Waiting to start provider " + cpr
10670                            + " launchingApp=" + cpr.launchingApp);
10671                    if (conn != null) {
10672                        conn.waiting = true;
10673                    }
10674                    cpr.wait();
10675                } catch (InterruptedException ex) {
10676                } finally {
10677                    if (conn != null) {
10678                        conn.waiting = false;
10679                    }
10680                }
10681            }
10682        }
10683        return cpr != null ? cpr.newHolder(conn) : null;
10684    }
10685
10686    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10687            ProcessRecord r, final int userId) {
10688        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10689                cpi.packageName, userId)) {
10690
10691            final boolean callerForeground = r == null || r.setSchedGroup
10692                    != ProcessList.SCHED_GROUP_BACKGROUND;
10693
10694            // Show a permission review UI only for starting from a foreground app
10695            if (!callerForeground) {
10696                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10697                        + cpi.packageName + " requires a permissions review");
10698                return false;
10699            }
10700
10701            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10702            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10703                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10704            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10705
10706            if (DEBUG_PERMISSIONS_REVIEW) {
10707                Slog.i(TAG, "u" + userId + " Launching permission review "
10708                        + "for package " + cpi.packageName);
10709            }
10710
10711            final UserHandle userHandle = new UserHandle(userId);
10712            mHandler.post(new Runnable() {
10713                @Override
10714                public void run() {
10715                    mContext.startActivityAsUser(intent, userHandle);
10716                }
10717            });
10718
10719            return false;
10720        }
10721
10722        return true;
10723    }
10724
10725    PackageManagerInternal getPackageManagerInternalLocked() {
10726        if (mPackageManagerInt == null) {
10727            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10728        }
10729        return mPackageManagerInt;
10730    }
10731
10732    @Override
10733    public final ContentProviderHolder getContentProvider(
10734            IApplicationThread caller, String name, int userId, boolean stable) {
10735        enforceNotIsolatedCaller("getContentProvider");
10736        if (caller == null) {
10737            String msg = "null IApplicationThread when getting content provider "
10738                    + name;
10739            Slog.w(TAG, msg);
10740            throw new SecurityException(msg);
10741        }
10742        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10743        // with cross-user grant.
10744        return getContentProviderImpl(caller, name, null, stable, userId);
10745    }
10746
10747    public ContentProviderHolder getContentProviderExternal(
10748            String name, int userId, IBinder token) {
10749        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10750            "Do not have permission in call getContentProviderExternal()");
10751        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10752                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10753        return getContentProviderExternalUnchecked(name, token, userId);
10754    }
10755
10756    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10757            IBinder token, int userId) {
10758        return getContentProviderImpl(null, name, token, true, userId);
10759    }
10760
10761    /**
10762     * Drop a content provider from a ProcessRecord's bookkeeping
10763     */
10764    public void removeContentProvider(IBinder connection, boolean stable) {
10765        enforceNotIsolatedCaller("removeContentProvider");
10766        long ident = Binder.clearCallingIdentity();
10767        try {
10768            synchronized (this) {
10769                ContentProviderConnection conn;
10770                try {
10771                    conn = (ContentProviderConnection)connection;
10772                } catch (ClassCastException e) {
10773                    String msg ="removeContentProvider: " + connection
10774                            + " not a ContentProviderConnection";
10775                    Slog.w(TAG, msg);
10776                    throw new IllegalArgumentException(msg);
10777                }
10778                if (conn == null) {
10779                    throw new NullPointerException("connection is null");
10780                }
10781                if (decProviderCountLocked(conn, null, null, stable)) {
10782                    updateOomAdjLocked();
10783                }
10784            }
10785        } finally {
10786            Binder.restoreCallingIdentity(ident);
10787        }
10788    }
10789
10790    public void removeContentProviderExternal(String name, IBinder token) {
10791        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10792            "Do not have permission in call removeContentProviderExternal()");
10793        int userId = UserHandle.getCallingUserId();
10794        long ident = Binder.clearCallingIdentity();
10795        try {
10796            removeContentProviderExternalUnchecked(name, token, userId);
10797        } finally {
10798            Binder.restoreCallingIdentity(ident);
10799        }
10800    }
10801
10802    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10803        synchronized (this) {
10804            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10805            if(cpr == null) {
10806                //remove from mProvidersByClass
10807                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10808                return;
10809            }
10810
10811            //update content provider record entry info
10812            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10813            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10814            if (localCpr.hasExternalProcessHandles()) {
10815                if (localCpr.removeExternalProcessHandleLocked(token)) {
10816                    updateOomAdjLocked();
10817                } else {
10818                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10819                            + " with no external reference for token: "
10820                            + token + ".");
10821                }
10822            } else {
10823                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10824                        + " with no external references.");
10825            }
10826        }
10827    }
10828
10829    public final void publishContentProviders(IApplicationThread caller,
10830            List<ContentProviderHolder> providers) {
10831        if (providers == null) {
10832            return;
10833        }
10834
10835        enforceNotIsolatedCaller("publishContentProviders");
10836        synchronized (this) {
10837            final ProcessRecord r = getRecordForAppLocked(caller);
10838            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10839            if (r == null) {
10840                throw new SecurityException(
10841                        "Unable to find app for caller " + caller
10842                      + " (pid=" + Binder.getCallingPid()
10843                      + ") when publishing content providers");
10844            }
10845
10846            final long origId = Binder.clearCallingIdentity();
10847
10848            final int N = providers.size();
10849            for (int i = 0; i < N; i++) {
10850                ContentProviderHolder src = providers.get(i);
10851                if (src == null || src.info == null || src.provider == null) {
10852                    continue;
10853                }
10854                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10855                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10856                if (dst != null) {
10857                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10858                    mProviderMap.putProviderByClass(comp, dst);
10859                    String names[] = dst.info.authority.split(";");
10860                    for (int j = 0; j < names.length; j++) {
10861                        mProviderMap.putProviderByName(names[j], dst);
10862                    }
10863
10864                    int launchingCount = mLaunchingProviders.size();
10865                    int j;
10866                    boolean wasInLaunchingProviders = false;
10867                    for (j = 0; j < launchingCount; j++) {
10868                        if (mLaunchingProviders.get(j) == dst) {
10869                            mLaunchingProviders.remove(j);
10870                            wasInLaunchingProviders = true;
10871                            j--;
10872                            launchingCount--;
10873                        }
10874                    }
10875                    if (wasInLaunchingProviders) {
10876                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10877                    }
10878                    synchronized (dst) {
10879                        dst.provider = src.provider;
10880                        dst.proc = r;
10881                        dst.notifyAll();
10882                    }
10883                    updateOomAdjLocked(r);
10884                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10885                            src.info.authority);
10886                }
10887            }
10888
10889            Binder.restoreCallingIdentity(origId);
10890        }
10891    }
10892
10893    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10894        ContentProviderConnection conn;
10895        try {
10896            conn = (ContentProviderConnection)connection;
10897        } catch (ClassCastException e) {
10898            String msg ="refContentProvider: " + connection
10899                    + " not a ContentProviderConnection";
10900            Slog.w(TAG, msg);
10901            throw new IllegalArgumentException(msg);
10902        }
10903        if (conn == null) {
10904            throw new NullPointerException("connection is null");
10905        }
10906
10907        synchronized (this) {
10908            if (stable > 0) {
10909                conn.numStableIncs += stable;
10910            }
10911            stable = conn.stableCount + stable;
10912            if (stable < 0) {
10913                throw new IllegalStateException("stableCount < 0: " + stable);
10914            }
10915
10916            if (unstable > 0) {
10917                conn.numUnstableIncs += unstable;
10918            }
10919            unstable = conn.unstableCount + unstable;
10920            if (unstable < 0) {
10921                throw new IllegalStateException("unstableCount < 0: " + unstable);
10922            }
10923
10924            if ((stable+unstable) <= 0) {
10925                throw new IllegalStateException("ref counts can't go to zero here: stable="
10926                        + stable + " unstable=" + unstable);
10927            }
10928            conn.stableCount = stable;
10929            conn.unstableCount = unstable;
10930            return !conn.dead;
10931        }
10932    }
10933
10934    public void unstableProviderDied(IBinder connection) {
10935        ContentProviderConnection conn;
10936        try {
10937            conn = (ContentProviderConnection)connection;
10938        } catch (ClassCastException e) {
10939            String msg ="refContentProvider: " + connection
10940                    + " not a ContentProviderConnection";
10941            Slog.w(TAG, msg);
10942            throw new IllegalArgumentException(msg);
10943        }
10944        if (conn == null) {
10945            throw new NullPointerException("connection is null");
10946        }
10947
10948        // Safely retrieve the content provider associated with the connection.
10949        IContentProvider provider;
10950        synchronized (this) {
10951            provider = conn.provider.provider;
10952        }
10953
10954        if (provider == null) {
10955            // Um, yeah, we're way ahead of you.
10956            return;
10957        }
10958
10959        // Make sure the caller is being honest with us.
10960        if (provider.asBinder().pingBinder()) {
10961            // Er, no, still looks good to us.
10962            synchronized (this) {
10963                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10964                        + " says " + conn + " died, but we don't agree");
10965                return;
10966            }
10967        }
10968
10969        // Well look at that!  It's dead!
10970        synchronized (this) {
10971            if (conn.provider.provider != provider) {
10972                // But something changed...  good enough.
10973                return;
10974            }
10975
10976            ProcessRecord proc = conn.provider.proc;
10977            if (proc == null || proc.thread == null) {
10978                // Seems like the process is already cleaned up.
10979                return;
10980            }
10981
10982            // As far as we're concerned, this is just like receiving a
10983            // death notification...  just a bit prematurely.
10984            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10985                    + ") early provider death");
10986            final long ident = Binder.clearCallingIdentity();
10987            try {
10988                appDiedLocked(proc);
10989            } finally {
10990                Binder.restoreCallingIdentity(ident);
10991            }
10992        }
10993    }
10994
10995    @Override
10996    public void appNotRespondingViaProvider(IBinder connection) {
10997        enforceCallingPermission(
10998                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10999
11000        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11001        if (conn == null) {
11002            Slog.w(TAG, "ContentProviderConnection is null");
11003            return;
11004        }
11005
11006        final ProcessRecord host = conn.provider.proc;
11007        if (host == null) {
11008            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11009            return;
11010        }
11011
11012        mHandler.post(new Runnable() {
11013            @Override
11014            public void run() {
11015                mAppErrors.appNotResponding(host, null, null, false,
11016                        "ContentProvider not responding");
11017            }
11018        });
11019    }
11020
11021    public final void installSystemProviders() {
11022        List<ProviderInfo> providers;
11023        synchronized (this) {
11024            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11025            providers = generateApplicationProvidersLocked(app);
11026            if (providers != null) {
11027                for (int i=providers.size()-1; i>=0; i--) {
11028                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11029                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11030                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11031                                + ": not system .apk");
11032                        providers.remove(i);
11033                    }
11034                }
11035            }
11036        }
11037        if (providers != null) {
11038            mSystemThread.installSystemProviders(providers);
11039        }
11040
11041        mCoreSettingsObserver = new CoreSettingsObserver(this);
11042        mFontScaleSettingObserver = new FontScaleSettingObserver();
11043
11044        //mUsageStatsService.monitorPackages();
11045    }
11046
11047    private void startPersistentApps(int matchFlags) {
11048        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11049
11050        synchronized (this) {
11051            try {
11052                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11053                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11054                for (ApplicationInfo app : apps) {
11055                    if (!"android".equals(app.packageName)) {
11056                        addAppLocked(app, false, null /* ABI override */);
11057                    }
11058                }
11059            } catch (RemoteException ex) {
11060            }
11061        }
11062    }
11063
11064    /**
11065     * When a user is unlocked, we need to install encryption-unaware providers
11066     * belonging to any running apps.
11067     */
11068    private void installEncryptionUnawareProviders(int userId) {
11069        // We're only interested in providers that are encryption unaware, and
11070        // we don't care about uninstalled apps, since there's no way they're
11071        // running at this point.
11072        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11073
11074        synchronized (this) {
11075            final int NP = mProcessNames.getMap().size();
11076            for (int ip = 0; ip < NP; ip++) {
11077                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11078                final int NA = apps.size();
11079                for (int ia = 0; ia < NA; ia++) {
11080                    final ProcessRecord app = apps.valueAt(ia);
11081                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11082
11083                    final int NG = app.pkgList.size();
11084                    for (int ig = 0; ig < NG; ig++) {
11085                        try {
11086                            final String pkgName = app.pkgList.keyAt(ig);
11087                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11088                                    .getPackageInfo(pkgName, matchFlags, userId);
11089                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11090                                for (ProviderInfo provInfo : pkgInfo.providers) {
11091                                    Log.v(TAG, "Installing " + provInfo);
11092                                    app.thread.scheduleInstallProvider(provInfo);
11093                                }
11094                            }
11095                        } catch (RemoteException ignored) {
11096                        }
11097                    }
11098                }
11099            }
11100        }
11101    }
11102
11103    /**
11104     * Allows apps to retrieve the MIME type of a URI.
11105     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11106     * users, then it does not need permission to access the ContentProvider.
11107     * Either, it needs cross-user uri grants.
11108     *
11109     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11110     *
11111     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11112     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11113     */
11114    public String getProviderMimeType(Uri uri, int userId) {
11115        enforceNotIsolatedCaller("getProviderMimeType");
11116        final String name = uri.getAuthority();
11117        int callingUid = Binder.getCallingUid();
11118        int callingPid = Binder.getCallingPid();
11119        long ident = 0;
11120        boolean clearedIdentity = false;
11121        synchronized (this) {
11122            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11123        }
11124        if (canClearIdentity(callingPid, callingUid, userId)) {
11125            clearedIdentity = true;
11126            ident = Binder.clearCallingIdentity();
11127        }
11128        ContentProviderHolder holder = null;
11129        try {
11130            holder = getContentProviderExternalUnchecked(name, null, userId);
11131            if (holder != null) {
11132                return holder.provider.getType(uri);
11133            }
11134        } catch (RemoteException e) {
11135            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11136            return null;
11137        } finally {
11138            // We need to clear the identity to call removeContentProviderExternalUnchecked
11139            if (!clearedIdentity) {
11140                ident = Binder.clearCallingIdentity();
11141            }
11142            try {
11143                if (holder != null) {
11144                    removeContentProviderExternalUnchecked(name, null, userId);
11145                }
11146            } finally {
11147                Binder.restoreCallingIdentity(ident);
11148            }
11149        }
11150
11151        return null;
11152    }
11153
11154    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11155        if (UserHandle.getUserId(callingUid) == userId) {
11156            return true;
11157        }
11158        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11159                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11160                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11161                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11162                return true;
11163        }
11164        return false;
11165    }
11166
11167    // =========================================================
11168    // GLOBAL MANAGEMENT
11169    // =========================================================
11170
11171    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11172            boolean isolated, int isolatedUid) {
11173        String proc = customProcess != null ? customProcess : info.processName;
11174        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11175        final int userId = UserHandle.getUserId(info.uid);
11176        int uid = info.uid;
11177        if (isolated) {
11178            if (isolatedUid == 0) {
11179                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11180                while (true) {
11181                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11182                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11183                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11184                    }
11185                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11186                    mNextIsolatedProcessUid++;
11187                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11188                        // No process for this uid, use it.
11189                        break;
11190                    }
11191                    stepsLeft--;
11192                    if (stepsLeft <= 0) {
11193                        return null;
11194                    }
11195                }
11196            } else {
11197                // Special case for startIsolatedProcess (internal only), where
11198                // the uid of the isolated process is specified by the caller.
11199                uid = isolatedUid;
11200            }
11201        }
11202        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11203        if (!mBooted && !mBooting
11204                && userId == UserHandle.USER_SYSTEM
11205                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11206            r.persistent = true;
11207        }
11208        addProcessNameLocked(r);
11209        return r;
11210    }
11211
11212    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11213            String abiOverride) {
11214        ProcessRecord app;
11215        if (!isolated) {
11216            app = getProcessRecordLocked(info.processName, info.uid, true);
11217        } else {
11218            app = null;
11219        }
11220
11221        if (app == null) {
11222            app = newProcessRecordLocked(info, null, isolated, 0);
11223            updateLruProcessLocked(app, false, null);
11224            updateOomAdjLocked();
11225        }
11226
11227        // This package really, really can not be stopped.
11228        try {
11229            AppGlobals.getPackageManager().setPackageStoppedState(
11230                    info.packageName, false, UserHandle.getUserId(app.uid));
11231        } catch (RemoteException e) {
11232        } catch (IllegalArgumentException e) {
11233            Slog.w(TAG, "Failed trying to unstop package "
11234                    + info.packageName + ": " + e);
11235        }
11236
11237        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11238            app.persistent = true;
11239            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11240        }
11241        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11242            mPersistentStartingProcesses.add(app);
11243            startProcessLocked(app, "added application", app.processName, abiOverride,
11244                    null /* entryPoint */, null /* entryPointArgs */);
11245        }
11246
11247        return app;
11248    }
11249
11250    public void unhandledBack() {
11251        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11252                "unhandledBack()");
11253
11254        synchronized(this) {
11255            final long origId = Binder.clearCallingIdentity();
11256            try {
11257                getFocusedStack().unhandledBackLocked();
11258            } finally {
11259                Binder.restoreCallingIdentity(origId);
11260            }
11261        }
11262    }
11263
11264    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11265        enforceNotIsolatedCaller("openContentUri");
11266        final int userId = UserHandle.getCallingUserId();
11267        String name = uri.getAuthority();
11268        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11269        ParcelFileDescriptor pfd = null;
11270        if (cph != null) {
11271            // We record the binder invoker's uid in thread-local storage before
11272            // going to the content provider to open the file.  Later, in the code
11273            // that handles all permissions checks, we look for this uid and use
11274            // that rather than the Activity Manager's own uid.  The effect is that
11275            // we do the check against the caller's permissions even though it looks
11276            // to the content provider like the Activity Manager itself is making
11277            // the request.
11278            Binder token = new Binder();
11279            sCallerIdentity.set(new Identity(
11280                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11281            try {
11282                pfd = cph.provider.openFile(null, uri, "r", null, token);
11283            } catch (FileNotFoundException e) {
11284                // do nothing; pfd will be returned null
11285            } finally {
11286                // Ensure that whatever happens, we clean up the identity state
11287                sCallerIdentity.remove();
11288                // Ensure we're done with the provider.
11289                removeContentProviderExternalUnchecked(name, null, userId);
11290            }
11291        } else {
11292            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11293        }
11294        return pfd;
11295    }
11296
11297    // Actually is sleeping or shutting down or whatever else in the future
11298    // is an inactive state.
11299    public boolean isSleepingOrShuttingDown() {
11300        return isSleeping() || mShuttingDown;
11301    }
11302
11303    public boolean isSleeping() {
11304        return mSleeping;
11305    }
11306
11307    void onWakefulnessChanged(int wakefulness) {
11308        synchronized(this) {
11309            mWakefulness = wakefulness;
11310            updateSleepIfNeededLocked();
11311        }
11312    }
11313
11314    void finishRunningVoiceLocked() {
11315        if (mRunningVoice != null) {
11316            mRunningVoice = null;
11317            mVoiceWakeLock.release();
11318            updateSleepIfNeededLocked();
11319        }
11320    }
11321
11322    void startTimeTrackingFocusedActivityLocked() {
11323        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11324            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11325        }
11326    }
11327
11328    void updateSleepIfNeededLocked() {
11329        if (mSleeping && !shouldSleepLocked()) {
11330            mSleeping = false;
11331            startTimeTrackingFocusedActivityLocked();
11332            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11333            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11334            updateOomAdjLocked();
11335        } else if (!mSleeping && shouldSleepLocked()) {
11336            mSleeping = true;
11337            if (mCurAppTimeTracker != null) {
11338                mCurAppTimeTracker.stop();
11339            }
11340            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11341            mStackSupervisor.goingToSleepLocked();
11342            updateOomAdjLocked();
11343
11344            // Initialize the wake times of all processes.
11345            checkExcessivePowerUsageLocked(false);
11346            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11347            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11348            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11349        }
11350    }
11351
11352    private boolean shouldSleepLocked() {
11353        // Resume applications while running a voice interactor.
11354        if (mRunningVoice != null) {
11355            return false;
11356        }
11357
11358        // TODO: Transform the lock screen state into a sleep token instead.
11359        switch (mWakefulness) {
11360            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11361            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11362            case PowerManagerInternal.WAKEFULNESS_DOZING:
11363                // Pause applications whenever the lock screen is shown or any sleep
11364                // tokens have been acquired.
11365                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11366            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11367            default:
11368                // If we're asleep then pause applications unconditionally.
11369                return true;
11370        }
11371    }
11372
11373    /** Pokes the task persister. */
11374    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11375        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11376    }
11377
11378    /** Notifies all listeners when the task stack has changed. */
11379    void notifyTaskStackChangedLocked() {
11380        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11381        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11382        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11383        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11384    }
11385
11386    /** Notifies all listeners when an Activity is pinned. */
11387    void notifyActivityPinnedLocked() {
11388        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11389        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11390    }
11391
11392    /**
11393     * Notifies all listeners when an attempt was made to start an an activity that is already
11394     * running in the pinned stack and the activity was not actually started, but the task is
11395     * either brought to the front or a new Intent is delivered to it.
11396     */
11397    void notifyPinnedActivityRestartAttemptLocked() {
11398        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11399        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11400    }
11401
11402    /** Notifies all listeners when the pinned stack animation ends. */
11403    @Override
11404    public void notifyPinnedStackAnimationEnded() {
11405        synchronized (this) {
11406            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11407            mHandler.obtainMessage(
11408                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11409        }
11410    }
11411
11412    @Override
11413    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11414        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11415    }
11416
11417    @Override
11418    public boolean shutdown(int timeout) {
11419        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11420                != PackageManager.PERMISSION_GRANTED) {
11421            throw new SecurityException("Requires permission "
11422                    + android.Manifest.permission.SHUTDOWN);
11423        }
11424
11425        boolean timedout = false;
11426
11427        synchronized(this) {
11428            mShuttingDown = true;
11429            updateEventDispatchingLocked();
11430            timedout = mStackSupervisor.shutdownLocked(timeout);
11431        }
11432
11433        mAppOpsService.shutdown();
11434        if (mUsageStatsService != null) {
11435            mUsageStatsService.prepareShutdown();
11436        }
11437        mBatteryStatsService.shutdown();
11438        synchronized (this) {
11439            mProcessStats.shutdownLocked();
11440            notifyTaskPersisterLocked(null, true);
11441        }
11442
11443        return timedout;
11444    }
11445
11446    public final void activitySlept(IBinder token) {
11447        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11448
11449        final long origId = Binder.clearCallingIdentity();
11450
11451        synchronized (this) {
11452            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11453            if (r != null) {
11454                mStackSupervisor.activitySleptLocked(r);
11455            }
11456        }
11457
11458        Binder.restoreCallingIdentity(origId);
11459    }
11460
11461    private String lockScreenShownToString() {
11462        switch (mLockScreenShown) {
11463            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11464            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11465            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11466            default: return "Unknown=" + mLockScreenShown;
11467        }
11468    }
11469
11470    void logLockScreen(String msg) {
11471        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11472                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11473                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11474                + " mSleeping=" + mSleeping);
11475    }
11476
11477    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11478        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11479        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11480        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11481            boolean wasRunningVoice = mRunningVoice != null;
11482            mRunningVoice = session;
11483            if (!wasRunningVoice) {
11484                mVoiceWakeLock.acquire();
11485                updateSleepIfNeededLocked();
11486            }
11487        }
11488    }
11489
11490    private void updateEventDispatchingLocked() {
11491        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11492    }
11493
11494    public void setLockScreenShown(boolean showing, boolean occluded) {
11495        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11496                != PackageManager.PERMISSION_GRANTED) {
11497            throw new SecurityException("Requires permission "
11498                    + android.Manifest.permission.DEVICE_POWER);
11499        }
11500
11501        synchronized(this) {
11502            long ident = Binder.clearCallingIdentity();
11503            try {
11504                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11505                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11506                if (showing && occluded) {
11507                    // The lock screen is currently showing, but is occluded by a window that can
11508                    // show on top of the lock screen. In this can we want to dismiss the docked
11509                    // stack since it will be complicated/risky to try to put the activity on top
11510                    // of the lock screen in the right fullscreen configuration.
11511                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11512                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11513                }
11514
11515                updateSleepIfNeededLocked();
11516            } finally {
11517                Binder.restoreCallingIdentity(ident);
11518            }
11519        }
11520    }
11521
11522    @Override
11523    public void notifyLockedProfile(@UserIdInt int userId) {
11524        try {
11525            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11526                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11527            }
11528        } catch (RemoteException ex) {
11529            throw new SecurityException("Fail to check is caller a privileged app", ex);
11530        }
11531
11532        synchronized (this) {
11533            if (mStackSupervisor.isUserLockedProfile(userId)) {
11534                final long ident = Binder.clearCallingIdentity();
11535                try {
11536                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11537                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11538                        // If there is no device lock, we will show the profile's credential page.
11539                        mActivityStarter.showConfirmDeviceCredential(userId);
11540                    } else {
11541                        // Showing launcher to avoid user entering credential twice.
11542                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11543                    }
11544                } finally {
11545                    Binder.restoreCallingIdentity(ident);
11546                }
11547            }
11548        }
11549    }
11550
11551    @Override
11552    public void startConfirmDeviceCredentialIntent(Intent intent) {
11553        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11554        synchronized (this) {
11555            final long ident = Binder.clearCallingIdentity();
11556            try {
11557                mActivityStarter.startConfirmCredentialIntent(intent);
11558            } finally {
11559                Binder.restoreCallingIdentity(ident);
11560            }
11561        }
11562    }
11563
11564    @Override
11565    public void stopAppSwitches() {
11566        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11567                != PackageManager.PERMISSION_GRANTED) {
11568            throw new SecurityException("viewquires permission "
11569                    + android.Manifest.permission.STOP_APP_SWITCHES);
11570        }
11571
11572        synchronized(this) {
11573            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11574                    + APP_SWITCH_DELAY_TIME;
11575            mDidAppSwitch = false;
11576            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11577            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11578            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11579        }
11580    }
11581
11582    public void resumeAppSwitches() {
11583        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11584                != PackageManager.PERMISSION_GRANTED) {
11585            throw new SecurityException("Requires permission "
11586                    + android.Manifest.permission.STOP_APP_SWITCHES);
11587        }
11588
11589        synchronized(this) {
11590            // Note that we don't execute any pending app switches... we will
11591            // let those wait until either the timeout, or the next start
11592            // activity request.
11593            mAppSwitchesAllowedTime = 0;
11594        }
11595    }
11596
11597    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11598            int callingPid, int callingUid, String name) {
11599        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11600            return true;
11601        }
11602
11603        int perm = checkComponentPermission(
11604                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11605                sourceUid, -1, true);
11606        if (perm == PackageManager.PERMISSION_GRANTED) {
11607            return true;
11608        }
11609
11610        // If the actual IPC caller is different from the logical source, then
11611        // also see if they are allowed to control app switches.
11612        if (callingUid != -1 && callingUid != sourceUid) {
11613            perm = checkComponentPermission(
11614                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11615                    callingUid, -1, true);
11616            if (perm == PackageManager.PERMISSION_GRANTED) {
11617                return true;
11618            }
11619        }
11620
11621        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11622        return false;
11623    }
11624
11625    public void setDebugApp(String packageName, boolean waitForDebugger,
11626            boolean persistent) {
11627        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11628                "setDebugApp()");
11629
11630        long ident = Binder.clearCallingIdentity();
11631        try {
11632            // Note that this is not really thread safe if there are multiple
11633            // callers into it at the same time, but that's not a situation we
11634            // care about.
11635            if (persistent) {
11636                final ContentResolver resolver = mContext.getContentResolver();
11637                Settings.Global.putString(
11638                    resolver, Settings.Global.DEBUG_APP,
11639                    packageName);
11640                Settings.Global.putInt(
11641                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11642                    waitForDebugger ? 1 : 0);
11643            }
11644
11645            synchronized (this) {
11646                if (!persistent) {
11647                    mOrigDebugApp = mDebugApp;
11648                    mOrigWaitForDebugger = mWaitForDebugger;
11649                }
11650                mDebugApp = packageName;
11651                mWaitForDebugger = waitForDebugger;
11652                mDebugTransient = !persistent;
11653                if (packageName != null) {
11654                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11655                            false, UserHandle.USER_ALL, "set debug app");
11656                }
11657            }
11658        } finally {
11659            Binder.restoreCallingIdentity(ident);
11660        }
11661    }
11662
11663    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11664        synchronized (this) {
11665            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11666            if (!isDebuggable) {
11667                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11668                    throw new SecurityException("Process not debuggable: " + app.packageName);
11669                }
11670            }
11671
11672            mTrackAllocationApp = processName;
11673        }
11674    }
11675
11676    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11677        synchronized (this) {
11678            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11679            if (!isDebuggable) {
11680                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11681                    throw new SecurityException("Process not debuggable: " + app.packageName);
11682                }
11683            }
11684            mProfileApp = processName;
11685            mProfileFile = profilerInfo.profileFile;
11686            if (mProfileFd != null) {
11687                try {
11688                    mProfileFd.close();
11689                } catch (IOException e) {
11690                }
11691                mProfileFd = null;
11692            }
11693            mProfileFd = profilerInfo.profileFd;
11694            mSamplingInterval = profilerInfo.samplingInterval;
11695            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11696            mProfileType = 0;
11697        }
11698    }
11699
11700    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11701        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11702        if (!isDebuggable) {
11703            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11704                throw new SecurityException("Process not debuggable: " + app.packageName);
11705            }
11706        }
11707        mNativeDebuggingApp = processName;
11708    }
11709
11710    @Override
11711    public void setAlwaysFinish(boolean enabled) {
11712        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11713                "setAlwaysFinish()");
11714
11715        long ident = Binder.clearCallingIdentity();
11716        try {
11717            Settings.Global.putInt(
11718                    mContext.getContentResolver(),
11719                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11720
11721            synchronized (this) {
11722                mAlwaysFinishActivities = enabled;
11723            }
11724        } finally {
11725            Binder.restoreCallingIdentity(ident);
11726        }
11727    }
11728
11729    @Override
11730    public void setLenientBackgroundCheck(boolean enabled) {
11731        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11732                "setLenientBackgroundCheck()");
11733
11734        long ident = Binder.clearCallingIdentity();
11735        try {
11736            Settings.Global.putInt(
11737                    mContext.getContentResolver(),
11738                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11739
11740            synchronized (this) {
11741                mLenientBackgroundCheck = enabled;
11742            }
11743        } finally {
11744            Binder.restoreCallingIdentity(ident);
11745        }
11746    }
11747
11748    @Override
11749    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11750        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11751                "setActivityController()");
11752        synchronized (this) {
11753            mController = controller;
11754            mControllerIsAMonkey = imAMonkey;
11755            Watchdog.getInstance().setActivityController(controller);
11756        }
11757    }
11758
11759    @Override
11760    public void setUserIsMonkey(boolean userIsMonkey) {
11761        synchronized (this) {
11762            synchronized (mPidsSelfLocked) {
11763                final int callingPid = Binder.getCallingPid();
11764                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11765                if (precessRecord == null) {
11766                    throw new SecurityException("Unknown process: " + callingPid);
11767                }
11768                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11769                    throw new SecurityException("Only an instrumentation process "
11770                            + "with a UiAutomation can call setUserIsMonkey");
11771                }
11772            }
11773            mUserIsMonkey = userIsMonkey;
11774        }
11775    }
11776
11777    @Override
11778    public boolean isUserAMonkey() {
11779        synchronized (this) {
11780            // If there is a controller also implies the user is a monkey.
11781            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11782        }
11783    }
11784
11785    public void requestBugReport(int bugreportType) {
11786        String service = null;
11787        switch (bugreportType) {
11788            case ActivityManager.BUGREPORT_OPTION_FULL:
11789                service = "bugreport";
11790                break;
11791            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11792                service = "bugreportplus";
11793                break;
11794            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11795                service = "bugreportremote";
11796                break;
11797        }
11798        if (service == null) {
11799            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11800                    + bugreportType);
11801        }
11802        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11803        SystemProperties.set("ctl.start", service);
11804    }
11805
11806    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11807        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11808    }
11809
11810    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11811        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11812            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11813        }
11814        return KEY_DISPATCHING_TIMEOUT;
11815    }
11816
11817    @Override
11818    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11819        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11820                != PackageManager.PERMISSION_GRANTED) {
11821            throw new SecurityException("Requires permission "
11822                    + android.Manifest.permission.FILTER_EVENTS);
11823        }
11824        ProcessRecord proc;
11825        long timeout;
11826        synchronized (this) {
11827            synchronized (mPidsSelfLocked) {
11828                proc = mPidsSelfLocked.get(pid);
11829            }
11830            timeout = getInputDispatchingTimeoutLocked(proc);
11831        }
11832
11833        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11834            return -1;
11835        }
11836
11837        return timeout;
11838    }
11839
11840    /**
11841     * Handle input dispatching timeouts.
11842     * Returns whether input dispatching should be aborted or not.
11843     */
11844    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11845            final ActivityRecord activity, final ActivityRecord parent,
11846            final boolean aboveSystem, String reason) {
11847        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11848                != PackageManager.PERMISSION_GRANTED) {
11849            throw new SecurityException("Requires permission "
11850                    + android.Manifest.permission.FILTER_EVENTS);
11851        }
11852
11853        final String annotation;
11854        if (reason == null) {
11855            annotation = "Input dispatching timed out";
11856        } else {
11857            annotation = "Input dispatching timed out (" + reason + ")";
11858        }
11859
11860        if (proc != null) {
11861            synchronized (this) {
11862                if (proc.debugging) {
11863                    return false;
11864                }
11865
11866                if (mDidDexOpt) {
11867                    // Give more time since we were dexopting.
11868                    mDidDexOpt = false;
11869                    return false;
11870                }
11871
11872                if (proc.instrumentationClass != null) {
11873                    Bundle info = new Bundle();
11874                    info.putString("shortMsg", "keyDispatchingTimedOut");
11875                    info.putString("longMsg", annotation);
11876                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11877                    return true;
11878                }
11879            }
11880            mHandler.post(new Runnable() {
11881                @Override
11882                public void run() {
11883                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11884                }
11885            });
11886        }
11887
11888        return true;
11889    }
11890
11891    @Override
11892    public Bundle getAssistContextExtras(int requestType) {
11893        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11894                null, null, true /* focused */, true /* newSessionId */,
11895                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11896        if (pae == null) {
11897            return null;
11898        }
11899        synchronized (pae) {
11900            while (!pae.haveResult) {
11901                try {
11902                    pae.wait();
11903                } catch (InterruptedException e) {
11904                }
11905            }
11906        }
11907        synchronized (this) {
11908            buildAssistBundleLocked(pae, pae.result);
11909            mPendingAssistExtras.remove(pae);
11910            mUiHandler.removeCallbacks(pae);
11911        }
11912        return pae.extras;
11913    }
11914
11915    @Override
11916    public boolean isAssistDataAllowedOnCurrentActivity() {
11917        int userId;
11918        synchronized (this) {
11919            userId = mUserController.getCurrentUserIdLocked();
11920            ActivityRecord activity = getFocusedStack().topActivity();
11921            if (activity == null) {
11922                return false;
11923            }
11924            userId = activity.userId;
11925        }
11926        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11927                Context.DEVICE_POLICY_SERVICE);
11928        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11929    }
11930
11931    @Override
11932    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11933        long ident = Binder.clearCallingIdentity();
11934        try {
11935            synchronized (this) {
11936                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11937                ActivityRecord top = getFocusedStack().topActivity();
11938                if (top != caller) {
11939                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11940                            + " is not current top " + top);
11941                    return false;
11942                }
11943                if (!top.nowVisible) {
11944                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11945                            + " is not visible");
11946                    return false;
11947                }
11948            }
11949            AssistUtils utils = new AssistUtils(mContext);
11950            return utils.showSessionForActiveService(args,
11951                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11952        } finally {
11953            Binder.restoreCallingIdentity(ident);
11954        }
11955    }
11956
11957    @Override
11958    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11959            Bundle receiverExtras,
11960            IBinder activityToken, boolean focused, boolean newSessionId) {
11961        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11962                activityToken, focused, newSessionId,
11963                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11964                != null;
11965    }
11966
11967    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11968            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
11969            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
11970        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11971                "enqueueAssistContext()");
11972        synchronized (this) {
11973            ActivityRecord activity = getFocusedStack().topActivity();
11974            if (activity == null) {
11975                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11976                return null;
11977            }
11978            if (activity.app == null || activity.app.thread == null) {
11979                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11980                return null;
11981            }
11982            if (focused) {
11983                if (activityToken != null) {
11984                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11985                    if (activity != caller) {
11986                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11987                                + " is not current top " + activity);
11988                        return null;
11989                    }
11990                }
11991            } else {
11992                activity = ActivityRecord.forTokenLocked(activityToken);
11993                if (activity == null) {
11994                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
11995                            + " couldn't be found");
11996                    return null;
11997                }
11998            }
11999
12000            PendingAssistExtras pae;
12001            Bundle extras = new Bundle();
12002            if (args != null) {
12003                extras.putAll(args);
12004            }
12005            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12006            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12007            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12008                    userHandle);
12009            // Increment the sessionId if necessary
12010            if (newSessionId) {
12011                mViSessionId++;
12012            }
12013            try {
12014                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12015                        requestType, mViSessionId);
12016                mPendingAssistExtras.add(pae);
12017                mUiHandler.postDelayed(pae, timeout);
12018            } catch (RemoteException e) {
12019                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12020                return null;
12021            }
12022            return pae;
12023        }
12024    }
12025
12026    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12027        IResultReceiver receiver;
12028        synchronized (this) {
12029            mPendingAssistExtras.remove(pae);
12030            receiver = pae.receiver;
12031        }
12032        if (receiver != null) {
12033            // Caller wants result sent back to them.
12034            Bundle sendBundle = new Bundle();
12035            // At least return the receiver extras
12036            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12037                    pae.receiverExtras);
12038            try {
12039                pae.receiver.send(0, sendBundle);
12040            } catch (RemoteException e) {
12041            }
12042        }
12043    }
12044
12045    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12046        if (result != null) {
12047            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12048        }
12049        if (pae.hint != null) {
12050            pae.extras.putBoolean(pae.hint, true);
12051        }
12052    }
12053
12054    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12055            AssistContent content, Uri referrer) {
12056        PendingAssistExtras pae = (PendingAssistExtras)token;
12057        synchronized (pae) {
12058            pae.result = extras;
12059            pae.structure = structure;
12060            pae.content = content;
12061            if (referrer != null) {
12062                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12063            }
12064            pae.haveResult = true;
12065            pae.notifyAll();
12066            if (pae.intent == null && pae.receiver == null) {
12067                // Caller is just waiting for the result.
12068                return;
12069            }
12070        }
12071
12072        // We are now ready to launch the assist activity.
12073        IResultReceiver sendReceiver = null;
12074        Bundle sendBundle = null;
12075        synchronized (this) {
12076            buildAssistBundleLocked(pae, extras);
12077            boolean exists = mPendingAssistExtras.remove(pae);
12078            mUiHandler.removeCallbacks(pae);
12079            if (!exists) {
12080                // Timed out.
12081                return;
12082            }
12083            if ((sendReceiver=pae.receiver) != null) {
12084                // Caller wants result sent back to them.
12085                sendBundle = new Bundle();
12086                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12087                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12088                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12089                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12090                        pae.receiverExtras);
12091            }
12092        }
12093        if (sendReceiver != null) {
12094            try {
12095                sendReceiver.send(0, sendBundle);
12096            } catch (RemoteException e) {
12097            }
12098            return;
12099        }
12100
12101        long ident = Binder.clearCallingIdentity();
12102        try {
12103            pae.intent.replaceExtras(pae.extras);
12104            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12105                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12106                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12107            closeSystemDialogs("assist");
12108            try {
12109                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12110            } catch (ActivityNotFoundException e) {
12111                Slog.w(TAG, "No activity to handle assist action.", e);
12112            }
12113        } finally {
12114            Binder.restoreCallingIdentity(ident);
12115        }
12116    }
12117
12118    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12119            Bundle args) {
12120        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12121                true /* focused */, true /* newSessionId */,
12122                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12123    }
12124
12125    public void registerProcessObserver(IProcessObserver observer) {
12126        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12127                "registerProcessObserver()");
12128        synchronized (this) {
12129            mProcessObservers.register(observer);
12130        }
12131    }
12132
12133    @Override
12134    public void unregisterProcessObserver(IProcessObserver observer) {
12135        synchronized (this) {
12136            mProcessObservers.unregister(observer);
12137        }
12138    }
12139
12140    @Override
12141    public void registerUidObserver(IUidObserver observer, int which) {
12142        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12143                "registerUidObserver()");
12144        synchronized (this) {
12145            mUidObservers.register(observer, which);
12146        }
12147    }
12148
12149    @Override
12150    public void unregisterUidObserver(IUidObserver observer) {
12151        synchronized (this) {
12152            mUidObservers.unregister(observer);
12153        }
12154    }
12155
12156    @Override
12157    public boolean convertFromTranslucent(IBinder token) {
12158        final long origId = Binder.clearCallingIdentity();
12159        try {
12160            synchronized (this) {
12161                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12162                if (r == null) {
12163                    return false;
12164                }
12165                final boolean translucentChanged = r.changeWindowTranslucency(true);
12166                if (translucentChanged) {
12167                    r.task.stack.releaseBackgroundResources(r);
12168                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12169                }
12170                mWindowManager.setAppFullscreen(token, true);
12171                return translucentChanged;
12172            }
12173        } finally {
12174            Binder.restoreCallingIdentity(origId);
12175        }
12176    }
12177
12178    @Override
12179    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12180        final long origId = Binder.clearCallingIdentity();
12181        try {
12182            synchronized (this) {
12183                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12184                if (r == null) {
12185                    return false;
12186                }
12187                int index = r.task.mActivities.lastIndexOf(r);
12188                if (index > 0) {
12189                    ActivityRecord under = r.task.mActivities.get(index - 1);
12190                    under.returningOptions = options;
12191                }
12192                final boolean translucentChanged = r.changeWindowTranslucency(false);
12193                if (translucentChanged) {
12194                    r.task.stack.convertActivityToTranslucent(r);
12195                }
12196                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12197                mWindowManager.setAppFullscreen(token, false);
12198                return translucentChanged;
12199            }
12200        } finally {
12201            Binder.restoreCallingIdentity(origId);
12202        }
12203    }
12204
12205    @Override
12206    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12207        final long origId = Binder.clearCallingIdentity();
12208        try {
12209            synchronized (this) {
12210                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12211                if (r != null) {
12212                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12213                }
12214            }
12215            return false;
12216        } finally {
12217            Binder.restoreCallingIdentity(origId);
12218        }
12219    }
12220
12221    @Override
12222    public boolean isBackgroundVisibleBehind(IBinder token) {
12223        final long origId = Binder.clearCallingIdentity();
12224        try {
12225            synchronized (this) {
12226                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12227                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12228                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12229                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12230                return visible;
12231            }
12232        } finally {
12233            Binder.restoreCallingIdentity(origId);
12234        }
12235    }
12236
12237    @Override
12238    public ActivityOptions getActivityOptions(IBinder token) {
12239        final long origId = Binder.clearCallingIdentity();
12240        try {
12241            synchronized (this) {
12242                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12243                if (r != null) {
12244                    final ActivityOptions activityOptions = r.pendingOptions;
12245                    r.pendingOptions = null;
12246                    return activityOptions;
12247                }
12248                return null;
12249            }
12250        } finally {
12251            Binder.restoreCallingIdentity(origId);
12252        }
12253    }
12254
12255    @Override
12256    public void setImmersive(IBinder token, boolean immersive) {
12257        synchronized(this) {
12258            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12259            if (r == null) {
12260                throw new IllegalArgumentException();
12261            }
12262            r.immersive = immersive;
12263
12264            // update associated state if we're frontmost
12265            if (r == mFocusedActivity) {
12266                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12267                applyUpdateLockStateLocked(r);
12268            }
12269        }
12270    }
12271
12272    @Override
12273    public boolean isImmersive(IBinder token) {
12274        synchronized (this) {
12275            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12276            if (r == null) {
12277                throw new IllegalArgumentException();
12278            }
12279            return r.immersive;
12280        }
12281    }
12282
12283    @Override
12284    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12285        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12286            throw new UnsupportedOperationException("VR mode not supported on this device!");
12287        }
12288
12289        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12290
12291        ActivityRecord r;
12292        synchronized (this) {
12293            r = ActivityRecord.isInStackLocked(token);
12294        }
12295
12296        if (r == null) {
12297            throw new IllegalArgumentException();
12298        }
12299
12300        int err;
12301        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12302                VrManagerInternal.NO_ERROR) {
12303            return err;
12304        }
12305
12306        synchronized(this) {
12307            r.requestedVrComponent = (enabled) ? packageName : null;
12308
12309            // Update associated state if this activity is currently focused
12310            if (r == mFocusedActivity) {
12311                applyUpdateVrModeLocked(r);
12312            }
12313            return 0;
12314        }
12315    }
12316
12317    @Override
12318    public boolean isVrModePackageEnabled(ComponentName packageName) {
12319        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12320            throw new UnsupportedOperationException("VR mode not supported on this device!");
12321        }
12322
12323        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12324
12325        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12326                VrManagerInternal.NO_ERROR;
12327    }
12328
12329    public boolean isTopActivityImmersive() {
12330        enforceNotIsolatedCaller("startActivity");
12331        synchronized (this) {
12332            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12333            return (r != null) ? r.immersive : false;
12334        }
12335    }
12336
12337    @Override
12338    public boolean isTopOfTask(IBinder token) {
12339        synchronized (this) {
12340            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12341            if (r == null) {
12342                throw new IllegalArgumentException();
12343            }
12344            return r.task.getTopActivity() == r;
12345        }
12346    }
12347
12348    public final void enterSafeMode() {
12349        synchronized(this) {
12350            // It only makes sense to do this before the system is ready
12351            // and started launching other packages.
12352            if (!mSystemReady) {
12353                try {
12354                    AppGlobals.getPackageManager().enterSafeMode();
12355                } catch (RemoteException e) {
12356                }
12357            }
12358
12359            mSafeMode = true;
12360        }
12361    }
12362
12363    public final void showSafeModeOverlay() {
12364        View v = LayoutInflater.from(mContext).inflate(
12365                com.android.internal.R.layout.safe_mode, null);
12366        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12367        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12368        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12369        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12370        lp.gravity = Gravity.BOTTOM | Gravity.START;
12371        lp.format = v.getBackground().getOpacity();
12372        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12373                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12374        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12375        ((WindowManager)mContext.getSystemService(
12376                Context.WINDOW_SERVICE)).addView(v, lp);
12377    }
12378
12379    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12380        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12381            return;
12382        }
12383        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12384        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12385        synchronized (stats) {
12386            if (mBatteryStatsService.isOnBattery()) {
12387                mBatteryStatsService.enforceCallingPermission();
12388                int MY_UID = Binder.getCallingUid();
12389                final int uid;
12390                if (sender == null) {
12391                    uid = sourceUid;
12392                } else {
12393                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12394                }
12395                BatteryStatsImpl.Uid.Pkg pkg =
12396                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12397                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12398                pkg.noteWakeupAlarmLocked(tag);
12399            }
12400        }
12401    }
12402
12403    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12404        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12405            return;
12406        }
12407        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12408        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12409        synchronized (stats) {
12410            mBatteryStatsService.enforceCallingPermission();
12411            int MY_UID = Binder.getCallingUid();
12412            final int uid;
12413            if (sender == null) {
12414                uid = sourceUid;
12415            } else {
12416                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12417            }
12418            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12419        }
12420    }
12421
12422    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12423        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12424            return;
12425        }
12426        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12427        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12428        synchronized (stats) {
12429            mBatteryStatsService.enforceCallingPermission();
12430            int MY_UID = Binder.getCallingUid();
12431            final int uid;
12432            if (sender == null) {
12433                uid = sourceUid;
12434            } else {
12435                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12436            }
12437            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12438        }
12439    }
12440
12441    public boolean killPids(int[] pids, String pReason, boolean secure) {
12442        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12443            throw new SecurityException("killPids only available to the system");
12444        }
12445        String reason = (pReason == null) ? "Unknown" : pReason;
12446        // XXX Note: don't acquire main activity lock here, because the window
12447        // manager calls in with its locks held.
12448
12449        boolean killed = false;
12450        synchronized (mPidsSelfLocked) {
12451            int worstType = 0;
12452            for (int i=0; i<pids.length; i++) {
12453                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12454                if (proc != null) {
12455                    int type = proc.setAdj;
12456                    if (type > worstType) {
12457                        worstType = type;
12458                    }
12459                }
12460            }
12461
12462            // If the worst oom_adj is somewhere in the cached proc LRU range,
12463            // then constrain it so we will kill all cached procs.
12464            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12465                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12466                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12467            }
12468
12469            // If this is not a secure call, don't let it kill processes that
12470            // are important.
12471            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12472                worstType = ProcessList.SERVICE_ADJ;
12473            }
12474
12475            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12476            for (int i=0; i<pids.length; i++) {
12477                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12478                if (proc == null) {
12479                    continue;
12480                }
12481                int adj = proc.setAdj;
12482                if (adj >= worstType && !proc.killedByAm) {
12483                    proc.kill(reason, true);
12484                    killed = true;
12485                }
12486            }
12487        }
12488        return killed;
12489    }
12490
12491    @Override
12492    public void killUid(int appId, int userId, String reason) {
12493        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12494        synchronized (this) {
12495            final long identity = Binder.clearCallingIdentity();
12496            try {
12497                killPackageProcessesLocked(null, appId, userId,
12498                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12499                        reason != null ? reason : "kill uid");
12500            } finally {
12501                Binder.restoreCallingIdentity(identity);
12502            }
12503        }
12504    }
12505
12506    @Override
12507    public boolean killProcessesBelowForeground(String reason) {
12508        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12509            throw new SecurityException("killProcessesBelowForeground() only available to system");
12510        }
12511
12512        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12513    }
12514
12515    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12516        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12517            throw new SecurityException("killProcessesBelowAdj() only available to system");
12518        }
12519
12520        boolean killed = false;
12521        synchronized (mPidsSelfLocked) {
12522            final int size = mPidsSelfLocked.size();
12523            for (int i = 0; i < size; i++) {
12524                final int pid = mPidsSelfLocked.keyAt(i);
12525                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12526                if (proc == null) continue;
12527
12528                final int adj = proc.setAdj;
12529                if (adj > belowAdj && !proc.killedByAm) {
12530                    proc.kill(reason, true);
12531                    killed = true;
12532                }
12533            }
12534        }
12535        return killed;
12536    }
12537
12538    @Override
12539    public void hang(final IBinder who, boolean allowRestart) {
12540        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12541                != PackageManager.PERMISSION_GRANTED) {
12542            throw new SecurityException("Requires permission "
12543                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12544        }
12545
12546        final IBinder.DeathRecipient death = new DeathRecipient() {
12547            @Override
12548            public void binderDied() {
12549                synchronized (this) {
12550                    notifyAll();
12551                }
12552            }
12553        };
12554
12555        try {
12556            who.linkToDeath(death, 0);
12557        } catch (RemoteException e) {
12558            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12559            return;
12560        }
12561
12562        synchronized (this) {
12563            Watchdog.getInstance().setAllowRestart(allowRestart);
12564            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12565            synchronized (death) {
12566                while (who.isBinderAlive()) {
12567                    try {
12568                        death.wait();
12569                    } catch (InterruptedException e) {
12570                    }
12571                }
12572            }
12573            Watchdog.getInstance().setAllowRestart(true);
12574        }
12575    }
12576
12577    @Override
12578    public void restart() {
12579        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12580                != PackageManager.PERMISSION_GRANTED) {
12581            throw new SecurityException("Requires permission "
12582                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12583        }
12584
12585        Log.i(TAG, "Sending shutdown broadcast...");
12586
12587        BroadcastReceiver br = new BroadcastReceiver() {
12588            @Override public void onReceive(Context context, Intent intent) {
12589                // Now the broadcast is done, finish up the low-level shutdown.
12590                Log.i(TAG, "Shutting down activity manager...");
12591                shutdown(10000);
12592                Log.i(TAG, "Shutdown complete, restarting!");
12593                Process.killProcess(Process.myPid());
12594                System.exit(10);
12595            }
12596        };
12597
12598        // First send the high-level shut down broadcast.
12599        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12600        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12601        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12602        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12603        mContext.sendOrderedBroadcastAsUser(intent,
12604                UserHandle.ALL, null, br, mHandler, 0, null, null);
12605        */
12606        br.onReceive(mContext, intent);
12607    }
12608
12609    private long getLowRamTimeSinceIdle(long now) {
12610        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12611    }
12612
12613    @Override
12614    public void performIdleMaintenance() {
12615        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12616                != PackageManager.PERMISSION_GRANTED) {
12617            throw new SecurityException("Requires permission "
12618                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12619        }
12620
12621        synchronized (this) {
12622            final long now = SystemClock.uptimeMillis();
12623            final long timeSinceLastIdle = now - mLastIdleTime;
12624            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12625            mLastIdleTime = now;
12626            mLowRamTimeSinceLastIdle = 0;
12627            if (mLowRamStartTime != 0) {
12628                mLowRamStartTime = now;
12629            }
12630
12631            StringBuilder sb = new StringBuilder(128);
12632            sb.append("Idle maintenance over ");
12633            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12634            sb.append(" low RAM for ");
12635            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12636            Slog.i(TAG, sb.toString());
12637
12638            // If at least 1/3 of our time since the last idle period has been spent
12639            // with RAM low, then we want to kill processes.
12640            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12641
12642            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12643                ProcessRecord proc = mLruProcesses.get(i);
12644                if (proc.notCachedSinceIdle) {
12645                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12646                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12647                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12648                        if (doKilling && proc.initialIdlePss != 0
12649                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12650                            sb = new StringBuilder(128);
12651                            sb.append("Kill");
12652                            sb.append(proc.processName);
12653                            sb.append(" in idle maint: pss=");
12654                            sb.append(proc.lastPss);
12655                            sb.append(", swapPss=");
12656                            sb.append(proc.lastSwapPss);
12657                            sb.append(", initialPss=");
12658                            sb.append(proc.initialIdlePss);
12659                            sb.append(", period=");
12660                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12661                            sb.append(", lowRamPeriod=");
12662                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12663                            Slog.wtfQuiet(TAG, sb.toString());
12664                            proc.kill("idle maint (pss " + proc.lastPss
12665                                    + " from " + proc.initialIdlePss + ")", true);
12666                        }
12667                    }
12668                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12669                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12670                    proc.notCachedSinceIdle = true;
12671                    proc.initialIdlePss = 0;
12672                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12673                            mTestPssMode, isSleeping(), now);
12674                }
12675            }
12676
12677            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12678            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12679        }
12680    }
12681
12682    @Override
12683    public void sendIdleJobTrigger() {
12684        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12685                != PackageManager.PERMISSION_GRANTED) {
12686            throw new SecurityException("Requires permission "
12687                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12688        }
12689
12690        final long ident = Binder.clearCallingIdentity();
12691        try {
12692            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12693                    .setPackage("android")
12694                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12695            broadcastIntent(null, intent, null, null, 0, null, null, null,
12696                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12697        } finally {
12698            Binder.restoreCallingIdentity(ident);
12699        }
12700    }
12701
12702    private void retrieveSettings() {
12703        final ContentResolver resolver = mContext.getContentResolver();
12704        final boolean freeformWindowManagement =
12705                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12706                        || Settings.Global.getInt(
12707                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12708        final boolean supportsPictureInPicture =
12709                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12710
12711        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12712        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12713        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12714        final boolean alwaysFinishActivities =
12715                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12716        final boolean lenientBackgroundCheck =
12717                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12718        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12719        final boolean forceResizable = Settings.Global.getInt(
12720                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12721        // Transfer any global setting for forcing RTL layout, into a System Property
12722        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12723
12724        final Configuration configuration = new Configuration();
12725        Settings.System.getConfiguration(resolver, configuration);
12726        if (forceRtl) {
12727            // This will take care of setting the correct layout direction flags
12728            configuration.setLayoutDirection(configuration.locale);
12729        }
12730
12731        synchronized (this) {
12732            mDebugApp = mOrigDebugApp = debugApp;
12733            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12734            mAlwaysFinishActivities = alwaysFinishActivities;
12735            mLenientBackgroundCheck = lenientBackgroundCheck;
12736            mForceResizableActivities = forceResizable;
12737            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12738            if (supportsMultiWindow || forceResizable) {
12739                mSupportsMultiWindow = true;
12740                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12741                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12742            } else {
12743                mSupportsMultiWindow = false;
12744                mSupportsFreeformWindowManagement = false;
12745                mSupportsPictureInPicture = false;
12746            }
12747            // This happens before any activities are started, so we can
12748            // change mConfiguration in-place.
12749            updateConfigurationLocked(configuration, null, true);
12750            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12751                    "Initial config: " + mConfiguration);
12752
12753            // Load resources only after the current configuration has been set.
12754            final Resources res = mContext.getResources();
12755            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12756            mThumbnailWidth = res.getDimensionPixelSize(
12757                    com.android.internal.R.dimen.thumbnail_width);
12758            mThumbnailHeight = res.getDimensionPixelSize(
12759                    com.android.internal.R.dimen.thumbnail_height);
12760            mFullscreenThumbnailScale = res.getFraction(
12761                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12762            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12763                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12764            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12765                    com.android.internal.R.string.config_appsNotReportingCrashes));
12766        }
12767    }
12768
12769    public boolean testIsSystemReady() {
12770        // no need to synchronize(this) just to read & return the value
12771        return mSystemReady;
12772    }
12773
12774    public void systemReady(final Runnable goingCallback) {
12775        synchronized(this) {
12776            if (mSystemReady) {
12777                // If we're done calling all the receivers, run the next "boot phase" passed in
12778                // by the SystemServer
12779                if (goingCallback != null) {
12780                    goingCallback.run();
12781                }
12782                return;
12783            }
12784
12785            mLocalDeviceIdleController
12786                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12787
12788            // Make sure we have the current profile info, since it is needed for security checks.
12789            mUserController.onSystemReady();
12790            mRecentTasks.onSystemReadyLocked();
12791            mAppOpsService.systemReady();
12792            mSystemReady = true;
12793        }
12794
12795        ArrayList<ProcessRecord> procsToKill = null;
12796        synchronized(mPidsSelfLocked) {
12797            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12798                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12799                if (!isAllowedWhileBooting(proc.info)){
12800                    if (procsToKill == null) {
12801                        procsToKill = new ArrayList<ProcessRecord>();
12802                    }
12803                    procsToKill.add(proc);
12804                }
12805            }
12806        }
12807
12808        synchronized(this) {
12809            if (procsToKill != null) {
12810                for (int i=procsToKill.size()-1; i>=0; i--) {
12811                    ProcessRecord proc = procsToKill.get(i);
12812                    Slog.i(TAG, "Removing system update proc: " + proc);
12813                    removeProcessLocked(proc, true, false, "system update done");
12814                }
12815            }
12816
12817            // Now that we have cleaned up any update processes, we
12818            // are ready to start launching real processes and know that
12819            // we won't trample on them any more.
12820            mProcessesReady = true;
12821        }
12822
12823        Slog.i(TAG, "System now ready");
12824        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12825            SystemClock.uptimeMillis());
12826
12827        synchronized(this) {
12828            // Make sure we have no pre-ready processes sitting around.
12829
12830            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12831                ResolveInfo ri = mContext.getPackageManager()
12832                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12833                                STOCK_PM_FLAGS);
12834                CharSequence errorMsg = null;
12835                if (ri != null) {
12836                    ActivityInfo ai = ri.activityInfo;
12837                    ApplicationInfo app = ai.applicationInfo;
12838                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12839                        mTopAction = Intent.ACTION_FACTORY_TEST;
12840                        mTopData = null;
12841                        mTopComponent = new ComponentName(app.packageName,
12842                                ai.name);
12843                    } else {
12844                        errorMsg = mContext.getResources().getText(
12845                                com.android.internal.R.string.factorytest_not_system);
12846                    }
12847                } else {
12848                    errorMsg = mContext.getResources().getText(
12849                            com.android.internal.R.string.factorytest_no_action);
12850                }
12851                if (errorMsg != null) {
12852                    mTopAction = null;
12853                    mTopData = null;
12854                    mTopComponent = null;
12855                    Message msg = Message.obtain();
12856                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12857                    msg.getData().putCharSequence("msg", errorMsg);
12858                    mUiHandler.sendMessage(msg);
12859                }
12860            }
12861        }
12862
12863        retrieveSettings();
12864        final int currentUserId;
12865        synchronized (this) {
12866            currentUserId = mUserController.getCurrentUserIdLocked();
12867            readGrantedUriPermissionsLocked();
12868        }
12869
12870        if (goingCallback != null) goingCallback.run();
12871
12872        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12873                Integer.toString(currentUserId), currentUserId);
12874        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12875                Integer.toString(currentUserId), currentUserId);
12876        mSystemServiceManager.startUser(currentUserId);
12877
12878        synchronized (this) {
12879            // Only start up encryption-aware persistent apps; once user is
12880            // unlocked we'll come back around and start unaware apps
12881            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12882
12883            // Start up initial activity.
12884            mBooting = true;
12885            // Enable home activity for system user, so that the system can always boot. We don't
12886            // do this when the system user is not setup since the setup wizard should be the one
12887            // to handle home activity in this case.
12888            if (UserManager.isSplitSystemUser() &&
12889                    Settings.Secure.getInt(mContext.getContentResolver(),
12890                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
12891                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12892                try {
12893                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12894                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12895                            UserHandle.USER_SYSTEM);
12896                } catch (RemoteException e) {
12897                    throw e.rethrowAsRuntimeException();
12898                }
12899            }
12900            startHomeActivityLocked(currentUserId, "systemReady");
12901
12902            try {
12903                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12904                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12905                            + " data partition or your device will be unstable.");
12906                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12907                }
12908            } catch (RemoteException e) {
12909            }
12910
12911            if (!Build.isBuildConsistent()) {
12912                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12913                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12914            }
12915
12916            long ident = Binder.clearCallingIdentity();
12917            try {
12918                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12919                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12920                        | Intent.FLAG_RECEIVER_FOREGROUND);
12921                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12922                broadcastIntentLocked(null, null, intent,
12923                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12924                        null, false, false, MY_PID, Process.SYSTEM_UID,
12925                        currentUserId);
12926                intent = new Intent(Intent.ACTION_USER_STARTING);
12927                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12928                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12929                broadcastIntentLocked(null, null, intent,
12930                        null, new IIntentReceiver.Stub() {
12931                            @Override
12932                            public void performReceive(Intent intent, int resultCode, String data,
12933                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12934                                    throws RemoteException {
12935                            }
12936                        }, 0, null, null,
12937                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12938                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12939            } catch (Throwable t) {
12940                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12941            } finally {
12942                Binder.restoreCallingIdentity(ident);
12943            }
12944            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12945            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12946        }
12947    }
12948
12949    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12950        synchronized (this) {
12951            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12952        }
12953    }
12954
12955    void skipCurrentReceiverLocked(ProcessRecord app) {
12956        for (BroadcastQueue queue : mBroadcastQueues) {
12957            queue.skipCurrentReceiverLocked(app);
12958        }
12959    }
12960
12961    /**
12962     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12963     * The application process will exit immediately after this call returns.
12964     * @param app object of the crashing app, null for the system server
12965     * @param crashInfo describing the exception
12966     */
12967    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12968        ProcessRecord r = findAppProcess(app, "Crash");
12969        final String processName = app == null ? "system_server"
12970                : (r == null ? "unknown" : r.processName);
12971
12972        handleApplicationCrashInner("crash", r, processName, crashInfo);
12973    }
12974
12975    /* Native crash reporting uses this inner version because it needs to be somewhat
12976     * decoupled from the AM-managed cleanup lifecycle
12977     */
12978    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12979            ApplicationErrorReport.CrashInfo crashInfo) {
12980        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12981                UserHandle.getUserId(Binder.getCallingUid()), processName,
12982                r == null ? -1 : r.info.flags,
12983                crashInfo.exceptionClassName,
12984                crashInfo.exceptionMessage,
12985                crashInfo.throwFileName,
12986                crashInfo.throwLineNumber);
12987
12988        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12989
12990        mAppErrors.crashApplication(r, crashInfo);
12991    }
12992
12993    public void handleApplicationStrictModeViolation(
12994            IBinder app,
12995            int violationMask,
12996            StrictMode.ViolationInfo info) {
12997        ProcessRecord r = findAppProcess(app, "StrictMode");
12998        if (r == null) {
12999            return;
13000        }
13001
13002        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13003            Integer stackFingerprint = info.hashCode();
13004            boolean logIt = true;
13005            synchronized (mAlreadyLoggedViolatedStacks) {
13006                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13007                    logIt = false;
13008                    // TODO: sub-sample into EventLog for these, with
13009                    // the info.durationMillis?  Then we'd get
13010                    // the relative pain numbers, without logging all
13011                    // the stack traces repeatedly.  We'd want to do
13012                    // likewise in the client code, which also does
13013                    // dup suppression, before the Binder call.
13014                } else {
13015                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13016                        mAlreadyLoggedViolatedStacks.clear();
13017                    }
13018                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13019                }
13020            }
13021            if (logIt) {
13022                logStrictModeViolationToDropBox(r, info);
13023            }
13024        }
13025
13026        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13027            AppErrorResult result = new AppErrorResult();
13028            synchronized (this) {
13029                final long origId = Binder.clearCallingIdentity();
13030
13031                Message msg = Message.obtain();
13032                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13033                HashMap<String, Object> data = new HashMap<String, Object>();
13034                data.put("result", result);
13035                data.put("app", r);
13036                data.put("violationMask", violationMask);
13037                data.put("info", info);
13038                msg.obj = data;
13039                mUiHandler.sendMessage(msg);
13040
13041                Binder.restoreCallingIdentity(origId);
13042            }
13043            int res = result.get();
13044            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13045        }
13046    }
13047
13048    // Depending on the policy in effect, there could be a bunch of
13049    // these in quick succession so we try to batch these together to
13050    // minimize disk writes, number of dropbox entries, and maximize
13051    // compression, by having more fewer, larger records.
13052    private void logStrictModeViolationToDropBox(
13053            ProcessRecord process,
13054            StrictMode.ViolationInfo info) {
13055        if (info == null) {
13056            return;
13057        }
13058        final boolean isSystemApp = process == null ||
13059                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13060                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13061        final String processName = process == null ? "unknown" : process.processName;
13062        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13063        final DropBoxManager dbox = (DropBoxManager)
13064                mContext.getSystemService(Context.DROPBOX_SERVICE);
13065
13066        // Exit early if the dropbox isn't configured to accept this report type.
13067        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13068
13069        boolean bufferWasEmpty;
13070        boolean needsFlush;
13071        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13072        synchronized (sb) {
13073            bufferWasEmpty = sb.length() == 0;
13074            appendDropBoxProcessHeaders(process, processName, sb);
13075            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13076            sb.append("System-App: ").append(isSystemApp).append("\n");
13077            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13078            if (info.violationNumThisLoop != 0) {
13079                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13080            }
13081            if (info.numAnimationsRunning != 0) {
13082                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13083            }
13084            if (info.broadcastIntentAction != null) {
13085                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13086            }
13087            if (info.durationMillis != -1) {
13088                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13089            }
13090            if (info.numInstances != -1) {
13091                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13092            }
13093            if (info.tags != null) {
13094                for (String tag : info.tags) {
13095                    sb.append("Span-Tag: ").append(tag).append("\n");
13096                }
13097            }
13098            sb.append("\n");
13099            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13100                sb.append(info.crashInfo.stackTrace);
13101                sb.append("\n");
13102            }
13103            if (info.message != null) {
13104                sb.append(info.message);
13105                sb.append("\n");
13106            }
13107
13108            // Only buffer up to ~64k.  Various logging bits truncate
13109            // things at 128k.
13110            needsFlush = (sb.length() > 64 * 1024);
13111        }
13112
13113        // Flush immediately if the buffer's grown too large, or this
13114        // is a non-system app.  Non-system apps are isolated with a
13115        // different tag & policy and not batched.
13116        //
13117        // Batching is useful during internal testing with
13118        // StrictMode settings turned up high.  Without batching,
13119        // thousands of separate files could be created on boot.
13120        if (!isSystemApp || needsFlush) {
13121            new Thread("Error dump: " + dropboxTag) {
13122                @Override
13123                public void run() {
13124                    String report;
13125                    synchronized (sb) {
13126                        report = sb.toString();
13127                        sb.delete(0, sb.length());
13128                        sb.trimToSize();
13129                    }
13130                    if (report.length() != 0) {
13131                        dbox.addText(dropboxTag, report);
13132                    }
13133                }
13134            }.start();
13135            return;
13136        }
13137
13138        // System app batching:
13139        if (!bufferWasEmpty) {
13140            // An existing dropbox-writing thread is outstanding, so
13141            // we don't need to start it up.  The existing thread will
13142            // catch the buffer appends we just did.
13143            return;
13144        }
13145
13146        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13147        // (After this point, we shouldn't access AMS internal data structures.)
13148        new Thread("Error dump: " + dropboxTag) {
13149            @Override
13150            public void run() {
13151                // 5 second sleep to let stacks arrive and be batched together
13152                try {
13153                    Thread.sleep(5000);  // 5 seconds
13154                } catch (InterruptedException e) {}
13155
13156                String errorReport;
13157                synchronized (mStrictModeBuffer) {
13158                    errorReport = mStrictModeBuffer.toString();
13159                    if (errorReport.length() == 0) {
13160                        return;
13161                    }
13162                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13163                    mStrictModeBuffer.trimToSize();
13164                }
13165                dbox.addText(dropboxTag, errorReport);
13166            }
13167        }.start();
13168    }
13169
13170    /**
13171     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13172     * @param app object of the crashing app, null for the system server
13173     * @param tag reported by the caller
13174     * @param system whether this wtf is coming from the system
13175     * @param crashInfo describing the context of the error
13176     * @return true if the process should exit immediately (WTF is fatal)
13177     */
13178    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13179            final ApplicationErrorReport.CrashInfo crashInfo) {
13180        final int callingUid = Binder.getCallingUid();
13181        final int callingPid = Binder.getCallingPid();
13182
13183        if (system) {
13184            // If this is coming from the system, we could very well have low-level
13185            // system locks held, so we want to do this all asynchronously.  And we
13186            // never want this to become fatal, so there is that too.
13187            mHandler.post(new Runnable() {
13188                @Override public void run() {
13189                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13190                }
13191            });
13192            return false;
13193        }
13194
13195        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13196                crashInfo);
13197
13198        if (r != null && r.pid != Process.myPid() &&
13199                Settings.Global.getInt(mContext.getContentResolver(),
13200                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13201            mAppErrors.crashApplication(r, crashInfo);
13202            return true;
13203        } else {
13204            return false;
13205        }
13206    }
13207
13208    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13209            final ApplicationErrorReport.CrashInfo crashInfo) {
13210        final ProcessRecord r = findAppProcess(app, "WTF");
13211        final String processName = app == null ? "system_server"
13212                : (r == null ? "unknown" : r.processName);
13213
13214        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13215                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13216
13217        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13218
13219        return r;
13220    }
13221
13222    /**
13223     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13224     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13225     */
13226    private ProcessRecord findAppProcess(IBinder app, String reason) {
13227        if (app == null) {
13228            return null;
13229        }
13230
13231        synchronized (this) {
13232            final int NP = mProcessNames.getMap().size();
13233            for (int ip=0; ip<NP; ip++) {
13234                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13235                final int NA = apps.size();
13236                for (int ia=0; ia<NA; ia++) {
13237                    ProcessRecord p = apps.valueAt(ia);
13238                    if (p.thread != null && p.thread.asBinder() == app) {
13239                        return p;
13240                    }
13241                }
13242            }
13243
13244            Slog.w(TAG, "Can't find mystery application for " + reason
13245                    + " from pid=" + Binder.getCallingPid()
13246                    + " uid=" + Binder.getCallingUid() + ": " + app);
13247            return null;
13248        }
13249    }
13250
13251    /**
13252     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13253     * to append various headers to the dropbox log text.
13254     */
13255    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13256            StringBuilder sb) {
13257        // Watchdog thread ends up invoking this function (with
13258        // a null ProcessRecord) to add the stack file to dropbox.
13259        // Do not acquire a lock on this (am) in such cases, as it
13260        // could cause a potential deadlock, if and when watchdog
13261        // is invoked due to unavailability of lock on am and it
13262        // would prevent watchdog from killing system_server.
13263        if (process == null) {
13264            sb.append("Process: ").append(processName).append("\n");
13265            return;
13266        }
13267        // Note: ProcessRecord 'process' is guarded by the service
13268        // instance.  (notably process.pkgList, which could otherwise change
13269        // concurrently during execution of this method)
13270        synchronized (this) {
13271            sb.append("Process: ").append(processName).append("\n");
13272            int flags = process.info.flags;
13273            IPackageManager pm = AppGlobals.getPackageManager();
13274            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13275            for (int ip=0; ip<process.pkgList.size(); ip++) {
13276                String pkg = process.pkgList.keyAt(ip);
13277                sb.append("Package: ").append(pkg);
13278                try {
13279                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13280                    if (pi != null) {
13281                        sb.append(" v").append(pi.versionCode);
13282                        if (pi.versionName != null) {
13283                            sb.append(" (").append(pi.versionName).append(")");
13284                        }
13285                    }
13286                } catch (RemoteException e) {
13287                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13288                }
13289                sb.append("\n");
13290            }
13291        }
13292    }
13293
13294    private static String processClass(ProcessRecord process) {
13295        if (process == null || process.pid == MY_PID) {
13296            return "system_server";
13297        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13298            return "system_app";
13299        } else {
13300            return "data_app";
13301        }
13302    }
13303
13304    private volatile long mWtfClusterStart;
13305    private volatile int mWtfClusterCount;
13306
13307    /**
13308     * Write a description of an error (crash, WTF, ANR) to the drop box.
13309     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13310     * @param process which caused the error, null means the system server
13311     * @param activity which triggered the error, null if unknown
13312     * @param parent activity related to the error, null if unknown
13313     * @param subject line related to the error, null if absent
13314     * @param report in long form describing the error, null if absent
13315     * @param logFile to include in the report, null if none
13316     * @param crashInfo giving an application stack trace, null if absent
13317     */
13318    public void addErrorToDropBox(String eventType,
13319            ProcessRecord process, String processName, ActivityRecord activity,
13320            ActivityRecord parent, String subject,
13321            final String report, final File logFile,
13322            final ApplicationErrorReport.CrashInfo crashInfo) {
13323        // NOTE -- this must never acquire the ActivityManagerService lock,
13324        // otherwise the watchdog may be prevented from resetting the system.
13325
13326        final String dropboxTag = processClass(process) + "_" + eventType;
13327        final DropBoxManager dbox = (DropBoxManager)
13328                mContext.getSystemService(Context.DROPBOX_SERVICE);
13329
13330        // Exit early if the dropbox isn't configured to accept this report type.
13331        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13332
13333        // Rate-limit how often we're willing to do the heavy lifting below to
13334        // collect and record logs; currently 5 logs per 10 second period.
13335        final long now = SystemClock.elapsedRealtime();
13336        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13337            mWtfClusterStart = now;
13338            mWtfClusterCount = 1;
13339        } else {
13340            if (mWtfClusterCount++ >= 5) return;
13341        }
13342
13343        final StringBuilder sb = new StringBuilder(1024);
13344        appendDropBoxProcessHeaders(process, processName, sb);
13345        if (process != null) {
13346            sb.append("Foreground: ")
13347                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13348                    .append("\n");
13349        }
13350        if (activity != null) {
13351            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13352        }
13353        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13354            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13355        }
13356        if (parent != null && parent != activity) {
13357            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13358        }
13359        if (subject != null) {
13360            sb.append("Subject: ").append(subject).append("\n");
13361        }
13362        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13363        if (Debug.isDebuggerConnected()) {
13364            sb.append("Debugger: Connected\n");
13365        }
13366        sb.append("\n");
13367
13368        // Do the rest in a worker thread to avoid blocking the caller on I/O
13369        // (After this point, we shouldn't access AMS internal data structures.)
13370        Thread worker = new Thread("Error dump: " + dropboxTag) {
13371            @Override
13372            public void run() {
13373                if (report != null) {
13374                    sb.append(report);
13375                }
13376                if (logFile != null) {
13377                    try {
13378                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13379                                    "\n\n[[TRUNCATED]]"));
13380                    } catch (IOException e) {
13381                        Slog.e(TAG, "Error reading " + logFile, e);
13382                    }
13383                }
13384                if (crashInfo != null && crashInfo.stackTrace != null) {
13385                    sb.append(crashInfo.stackTrace);
13386                }
13387
13388                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13389                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13390                if (lines > 0) {
13391                    sb.append("\n");
13392
13393                    // Merge several logcat streams, and take the last N lines
13394                    InputStreamReader input = null;
13395                    try {
13396                        java.lang.Process logcat = new ProcessBuilder(
13397                                "/system/bin/timeout", "-k", "15s", "10s",
13398                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13399                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13400                                        .redirectErrorStream(true).start();
13401
13402                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13403                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13404                        input = new InputStreamReader(logcat.getInputStream());
13405
13406                        int num;
13407                        char[] buf = new char[8192];
13408                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13409                    } catch (IOException e) {
13410                        Slog.e(TAG, "Error running logcat", e);
13411                    } finally {
13412                        if (input != null) try { input.close(); } catch (IOException e) {}
13413                    }
13414                }
13415
13416                dbox.addText(dropboxTag, sb.toString());
13417            }
13418        };
13419
13420        if (process == null) {
13421            // If process is null, we are being called from some internal code
13422            // and may be about to die -- run this synchronously.
13423            worker.run();
13424        } else {
13425            worker.start();
13426        }
13427    }
13428
13429    @Override
13430    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13431        enforceNotIsolatedCaller("getProcessesInErrorState");
13432        // assume our apps are happy - lazy create the list
13433        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13434
13435        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13436                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13437        int userId = UserHandle.getUserId(Binder.getCallingUid());
13438
13439        synchronized (this) {
13440
13441            // iterate across all processes
13442            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13443                ProcessRecord app = mLruProcesses.get(i);
13444                if (!allUsers && app.userId != userId) {
13445                    continue;
13446                }
13447                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13448                    // This one's in trouble, so we'll generate a report for it
13449                    // crashes are higher priority (in case there's a crash *and* an anr)
13450                    ActivityManager.ProcessErrorStateInfo report = null;
13451                    if (app.crashing) {
13452                        report = app.crashingReport;
13453                    } else if (app.notResponding) {
13454                        report = app.notRespondingReport;
13455                    }
13456
13457                    if (report != null) {
13458                        if (errList == null) {
13459                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13460                        }
13461                        errList.add(report);
13462                    } else {
13463                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13464                                " crashing = " + app.crashing +
13465                                " notResponding = " + app.notResponding);
13466                    }
13467                }
13468            }
13469        }
13470
13471        return errList;
13472    }
13473
13474    static int procStateToImportance(int procState, int memAdj,
13475            ActivityManager.RunningAppProcessInfo currApp) {
13476        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13477        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13478            currApp.lru = memAdj;
13479        } else {
13480            currApp.lru = 0;
13481        }
13482        return imp;
13483    }
13484
13485    private void fillInProcMemInfo(ProcessRecord app,
13486            ActivityManager.RunningAppProcessInfo outInfo) {
13487        outInfo.pid = app.pid;
13488        outInfo.uid = app.info.uid;
13489        if (mHeavyWeightProcess == app) {
13490            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13491        }
13492        if (app.persistent) {
13493            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13494        }
13495        if (app.activities.size() > 0) {
13496            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13497        }
13498        outInfo.lastTrimLevel = app.trimMemoryLevel;
13499        int adj = app.curAdj;
13500        int procState = app.curProcState;
13501        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13502        outInfo.importanceReasonCode = app.adjTypeCode;
13503        outInfo.processState = app.curProcState;
13504    }
13505
13506    @Override
13507    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13508        enforceNotIsolatedCaller("getRunningAppProcesses");
13509
13510        final int callingUid = Binder.getCallingUid();
13511
13512        // Lazy instantiation of list
13513        List<ActivityManager.RunningAppProcessInfo> runList = null;
13514        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13515                callingUid) == PackageManager.PERMISSION_GRANTED;
13516        final int userId = UserHandle.getUserId(callingUid);
13517        final boolean allUids = isGetTasksAllowed(
13518                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13519
13520        synchronized (this) {
13521            // Iterate across all processes
13522            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13523                ProcessRecord app = mLruProcesses.get(i);
13524                if ((!allUsers && app.userId != userId)
13525                        || (!allUids && app.uid != callingUid)) {
13526                    continue;
13527                }
13528                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13529                    // Generate process state info for running application
13530                    ActivityManager.RunningAppProcessInfo currApp =
13531                        new ActivityManager.RunningAppProcessInfo(app.processName,
13532                                app.pid, app.getPackageList());
13533                    fillInProcMemInfo(app, currApp);
13534                    if (app.adjSource instanceof ProcessRecord) {
13535                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13536                        currApp.importanceReasonImportance =
13537                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13538                                        app.adjSourceProcState);
13539                    } else if (app.adjSource instanceof ActivityRecord) {
13540                        ActivityRecord r = (ActivityRecord)app.adjSource;
13541                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13542                    }
13543                    if (app.adjTarget instanceof ComponentName) {
13544                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13545                    }
13546                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13547                    //        + " lru=" + currApp.lru);
13548                    if (runList == null) {
13549                        runList = new ArrayList<>();
13550                    }
13551                    runList.add(currApp);
13552                }
13553            }
13554        }
13555        return runList;
13556    }
13557
13558    @Override
13559    public List<ApplicationInfo> getRunningExternalApplications() {
13560        enforceNotIsolatedCaller("getRunningExternalApplications");
13561        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13562        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13563        if (runningApps != null && runningApps.size() > 0) {
13564            Set<String> extList = new HashSet<String>();
13565            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13566                if (app.pkgList != null) {
13567                    for (String pkg : app.pkgList) {
13568                        extList.add(pkg);
13569                    }
13570                }
13571            }
13572            IPackageManager pm = AppGlobals.getPackageManager();
13573            for (String pkg : extList) {
13574                try {
13575                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13576                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13577                        retList.add(info);
13578                    }
13579                } catch (RemoteException e) {
13580                }
13581            }
13582        }
13583        return retList;
13584    }
13585
13586    @Override
13587    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13588        enforceNotIsolatedCaller("getMyMemoryState");
13589        synchronized (this) {
13590            ProcessRecord proc;
13591            synchronized (mPidsSelfLocked) {
13592                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13593            }
13594            fillInProcMemInfo(proc, outInfo);
13595        }
13596    }
13597
13598    @Override
13599    public int getMemoryTrimLevel() {
13600        enforceNotIsolatedCaller("getMyMemoryState");
13601        synchronized (this) {
13602            return mLastMemoryLevel;
13603        }
13604    }
13605
13606    @Override
13607    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13608            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13609        (new ActivityManagerShellCommand(this, false)).exec(
13610                this, in, out, err, args, resultReceiver);
13611    }
13612
13613    @Override
13614    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13615        if (checkCallingPermission(android.Manifest.permission.DUMP)
13616                != PackageManager.PERMISSION_GRANTED) {
13617            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13618                    + Binder.getCallingPid()
13619                    + ", uid=" + Binder.getCallingUid()
13620                    + " without permission "
13621                    + android.Manifest.permission.DUMP);
13622            return;
13623        }
13624
13625        boolean dumpAll = false;
13626        boolean dumpClient = false;
13627        String dumpPackage = null;
13628
13629        int opti = 0;
13630        while (opti < args.length) {
13631            String opt = args[opti];
13632            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13633                break;
13634            }
13635            opti++;
13636            if ("-a".equals(opt)) {
13637                dumpAll = true;
13638            } else if ("-c".equals(opt)) {
13639                dumpClient = true;
13640            } else if ("-p".equals(opt)) {
13641                if (opti < args.length) {
13642                    dumpPackage = args[opti];
13643                    opti++;
13644                } else {
13645                    pw.println("Error: -p option requires package argument");
13646                    return;
13647                }
13648                dumpClient = true;
13649            } else if ("-h".equals(opt)) {
13650                ActivityManagerShellCommand.dumpHelp(pw, true);
13651                return;
13652            } else {
13653                pw.println("Unknown argument: " + opt + "; use -h for help");
13654            }
13655        }
13656
13657        long origId = Binder.clearCallingIdentity();
13658        boolean more = false;
13659        // Is the caller requesting to dump a particular piece of data?
13660        if (opti < args.length) {
13661            String cmd = args[opti];
13662            opti++;
13663            if ("activities".equals(cmd) || "a".equals(cmd)) {
13664                synchronized (this) {
13665                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13666                }
13667            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13668                synchronized (this) {
13669                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13670                }
13671            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13672                String[] newArgs;
13673                String name;
13674                if (opti >= args.length) {
13675                    name = null;
13676                    newArgs = EMPTY_STRING_ARRAY;
13677                } else {
13678                    dumpPackage = args[opti];
13679                    opti++;
13680                    newArgs = new String[args.length - opti];
13681                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13682                            args.length - opti);
13683                }
13684                synchronized (this) {
13685                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13686                }
13687            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13688                String[] newArgs;
13689                String name;
13690                if (opti >= args.length) {
13691                    name = null;
13692                    newArgs = EMPTY_STRING_ARRAY;
13693                } else {
13694                    dumpPackage = args[opti];
13695                    opti++;
13696                    newArgs = new String[args.length - opti];
13697                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13698                            args.length - opti);
13699                }
13700                synchronized (this) {
13701                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13702                }
13703            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13704                String[] newArgs;
13705                String name;
13706                if (opti >= args.length) {
13707                    name = null;
13708                    newArgs = EMPTY_STRING_ARRAY;
13709                } else {
13710                    dumpPackage = args[opti];
13711                    opti++;
13712                    newArgs = new String[args.length - opti];
13713                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13714                            args.length - opti);
13715                }
13716                synchronized (this) {
13717                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13718                }
13719            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13720                synchronized (this) {
13721                    dumpOomLocked(fd, pw, args, opti, true);
13722                }
13723            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13724                synchronized (this) {
13725                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13726                }
13727            } else if ("provider".equals(cmd)) {
13728                String[] newArgs;
13729                String name;
13730                if (opti >= args.length) {
13731                    name = null;
13732                    newArgs = EMPTY_STRING_ARRAY;
13733                } else {
13734                    name = args[opti];
13735                    opti++;
13736                    newArgs = new String[args.length - opti];
13737                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13738                }
13739                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13740                    pw.println("No providers match: " + name);
13741                    pw.println("Use -h for help.");
13742                }
13743            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13744                synchronized (this) {
13745                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13746                }
13747            } else if ("service".equals(cmd)) {
13748                String[] newArgs;
13749                String name;
13750                if (opti >= args.length) {
13751                    name = null;
13752                    newArgs = EMPTY_STRING_ARRAY;
13753                } else {
13754                    name = args[opti];
13755                    opti++;
13756                    newArgs = new String[args.length - opti];
13757                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13758                            args.length - opti);
13759                }
13760                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13761                    pw.println("No services match: " + name);
13762                    pw.println("Use -h for help.");
13763                }
13764            } else if ("package".equals(cmd)) {
13765                String[] newArgs;
13766                if (opti >= args.length) {
13767                    pw.println("package: no package name specified");
13768                    pw.println("Use -h for help.");
13769                } else {
13770                    dumpPackage = args[opti];
13771                    opti++;
13772                    newArgs = new String[args.length - opti];
13773                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13774                            args.length - opti);
13775                    args = newArgs;
13776                    opti = 0;
13777                    more = true;
13778                }
13779            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13780                synchronized (this) {
13781                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13782                }
13783            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13784                synchronized (this) {
13785                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13786                }
13787            } else if ("locks".equals(cmd)) {
13788                LockGuard.dump(fd, pw, args);
13789            } else {
13790                // Dumping a single activity?
13791                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13792                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13793                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13794                    if (res < 0) {
13795                        pw.println("Bad activity command, or no activities match: " + cmd);
13796                        pw.println("Use -h for help.");
13797                    }
13798                }
13799            }
13800            if (!more) {
13801                Binder.restoreCallingIdentity(origId);
13802                return;
13803            }
13804        }
13805
13806        // No piece of data specified, dump everything.
13807        synchronized (this) {
13808            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13809            pw.println();
13810            if (dumpAll) {
13811                pw.println("-------------------------------------------------------------------------------");
13812            }
13813            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13814            pw.println();
13815            if (dumpAll) {
13816                pw.println("-------------------------------------------------------------------------------");
13817            }
13818            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13819            pw.println();
13820            if (dumpAll) {
13821                pw.println("-------------------------------------------------------------------------------");
13822            }
13823            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13824            pw.println();
13825            if (dumpAll) {
13826                pw.println("-------------------------------------------------------------------------------");
13827            }
13828            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13829            pw.println();
13830            if (dumpAll) {
13831                pw.println("-------------------------------------------------------------------------------");
13832            }
13833            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13834            pw.println();
13835            if (dumpAll) {
13836                pw.println("-------------------------------------------------------------------------------");
13837            }
13838            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13839            if (mAssociations.size() > 0) {
13840                pw.println();
13841                if (dumpAll) {
13842                    pw.println("-------------------------------------------------------------------------------");
13843                }
13844                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13845            }
13846            pw.println();
13847            if (dumpAll) {
13848                pw.println("-------------------------------------------------------------------------------");
13849            }
13850            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13851        }
13852        Binder.restoreCallingIdentity(origId);
13853    }
13854
13855    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13856            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13857        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13858
13859        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13860                dumpPackage);
13861        boolean needSep = printedAnything;
13862
13863        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13864                dumpPackage, needSep, "  mFocusedActivity: ");
13865        if (printed) {
13866            printedAnything = true;
13867            needSep = false;
13868        }
13869
13870        if (dumpPackage == null) {
13871            if (needSep) {
13872                pw.println();
13873            }
13874            needSep = true;
13875            printedAnything = true;
13876            mStackSupervisor.dump(pw, "  ");
13877        }
13878
13879        if (!printedAnything) {
13880            pw.println("  (nothing)");
13881        }
13882    }
13883
13884    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13885            int opti, boolean dumpAll, String dumpPackage) {
13886        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13887
13888        boolean printedAnything = false;
13889
13890        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13891            boolean printedHeader = false;
13892
13893            final int N = mRecentTasks.size();
13894            for (int i=0; i<N; i++) {
13895                TaskRecord tr = mRecentTasks.get(i);
13896                if (dumpPackage != null) {
13897                    if (tr.realActivity == null ||
13898                            !dumpPackage.equals(tr.realActivity)) {
13899                        continue;
13900                    }
13901                }
13902                if (!printedHeader) {
13903                    pw.println("  Recent tasks:");
13904                    printedHeader = true;
13905                    printedAnything = true;
13906                }
13907                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13908                        pw.println(tr);
13909                if (dumpAll) {
13910                    mRecentTasks.get(i).dump(pw, "    ");
13911                }
13912            }
13913        }
13914
13915        if (!printedAnything) {
13916            pw.println("  (nothing)");
13917        }
13918    }
13919
13920    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13921            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13922        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13923
13924        int dumpUid = 0;
13925        if (dumpPackage != null) {
13926            IPackageManager pm = AppGlobals.getPackageManager();
13927            try {
13928                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13929            } catch (RemoteException e) {
13930            }
13931        }
13932
13933        boolean printedAnything = false;
13934
13935        final long now = SystemClock.uptimeMillis();
13936
13937        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13938            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13939                    = mAssociations.valueAt(i1);
13940            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13941                SparseArray<ArrayMap<String, Association>> sourceUids
13942                        = targetComponents.valueAt(i2);
13943                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13944                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13945                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13946                        Association ass = sourceProcesses.valueAt(i4);
13947                        if (dumpPackage != null) {
13948                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13949                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13950                                continue;
13951                            }
13952                        }
13953                        printedAnything = true;
13954                        pw.print("  ");
13955                        pw.print(ass.mTargetProcess);
13956                        pw.print("/");
13957                        UserHandle.formatUid(pw, ass.mTargetUid);
13958                        pw.print(" <- ");
13959                        pw.print(ass.mSourceProcess);
13960                        pw.print("/");
13961                        UserHandle.formatUid(pw, ass.mSourceUid);
13962                        pw.println();
13963                        pw.print("    via ");
13964                        pw.print(ass.mTargetComponent.flattenToShortString());
13965                        pw.println();
13966                        pw.print("    ");
13967                        long dur = ass.mTime;
13968                        if (ass.mNesting > 0) {
13969                            dur += now - ass.mStartTime;
13970                        }
13971                        TimeUtils.formatDuration(dur, pw);
13972                        pw.print(" (");
13973                        pw.print(ass.mCount);
13974                        pw.print(" times)");
13975                        pw.print("  ");
13976                        for (int i=0; i<ass.mStateTimes.length; i++) {
13977                            long amt = ass.mStateTimes[i];
13978                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13979                                amt += now - ass.mLastStateUptime;
13980                            }
13981                            if (amt != 0) {
13982                                pw.print(" ");
13983                                pw.print(ProcessList.makeProcStateString(
13984                                            i + ActivityManager.MIN_PROCESS_STATE));
13985                                pw.print("=");
13986                                TimeUtils.formatDuration(amt, pw);
13987                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13988                                    pw.print("*");
13989                                }
13990                            }
13991                        }
13992                        pw.println();
13993                        if (ass.mNesting > 0) {
13994                            pw.print("    Currently active: ");
13995                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13996                            pw.println();
13997                        }
13998                    }
13999                }
14000            }
14001
14002        }
14003
14004        if (!printedAnything) {
14005            pw.println("  (nothing)");
14006        }
14007    }
14008
14009    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14010            String header, boolean needSep) {
14011        boolean printed = false;
14012        int whichAppId = -1;
14013        if (dumpPackage != null) {
14014            try {
14015                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14016                        dumpPackage, 0);
14017                whichAppId = UserHandle.getAppId(info.uid);
14018            } catch (NameNotFoundException e) {
14019                e.printStackTrace();
14020            }
14021        }
14022        for (int i=0; i<uids.size(); i++) {
14023            UidRecord uidRec = uids.valueAt(i);
14024            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14025                continue;
14026            }
14027            if (!printed) {
14028                printed = true;
14029                if (needSep) {
14030                    pw.println();
14031                }
14032                pw.print("  ");
14033                pw.println(header);
14034                needSep = true;
14035            }
14036            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14037            pw.print(": "); pw.println(uidRec);
14038        }
14039        return printed;
14040    }
14041
14042    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14043            int opti, boolean dumpAll, String dumpPackage) {
14044        boolean needSep = false;
14045        boolean printedAnything = false;
14046        int numPers = 0;
14047
14048        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14049
14050        if (dumpAll) {
14051            final int NP = mProcessNames.getMap().size();
14052            for (int ip=0; ip<NP; ip++) {
14053                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14054                final int NA = procs.size();
14055                for (int ia=0; ia<NA; ia++) {
14056                    ProcessRecord r = procs.valueAt(ia);
14057                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14058                        continue;
14059                    }
14060                    if (!needSep) {
14061                        pw.println("  All known processes:");
14062                        needSep = true;
14063                        printedAnything = true;
14064                    }
14065                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14066                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14067                        pw.print(" "); pw.println(r);
14068                    r.dump(pw, "    ");
14069                    if (r.persistent) {
14070                        numPers++;
14071                    }
14072                }
14073            }
14074        }
14075
14076        if (mIsolatedProcesses.size() > 0) {
14077            boolean printed = false;
14078            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14079                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14080                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14081                    continue;
14082                }
14083                if (!printed) {
14084                    if (needSep) {
14085                        pw.println();
14086                    }
14087                    pw.println("  Isolated process list (sorted by uid):");
14088                    printedAnything = true;
14089                    printed = true;
14090                    needSep = true;
14091                }
14092                pw.println(String.format("%sIsolated #%2d: %s",
14093                        "    ", i, r.toString()));
14094            }
14095        }
14096
14097        if (mActiveUids.size() > 0) {
14098            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14099                printedAnything = needSep = true;
14100            }
14101        }
14102        if (mValidateUids.size() > 0) {
14103            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14104                printedAnything = needSep = true;
14105            }
14106        }
14107
14108        if (mLruProcesses.size() > 0) {
14109            if (needSep) {
14110                pw.println();
14111            }
14112            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14113                    pw.print(" total, non-act at ");
14114                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14115                    pw.print(", non-svc at ");
14116                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14117                    pw.println("):");
14118            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14119            needSep = true;
14120            printedAnything = true;
14121        }
14122
14123        if (dumpAll || dumpPackage != null) {
14124            synchronized (mPidsSelfLocked) {
14125                boolean printed = false;
14126                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14127                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14128                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14129                        continue;
14130                    }
14131                    if (!printed) {
14132                        if (needSep) pw.println();
14133                        needSep = true;
14134                        pw.println("  PID mappings:");
14135                        printed = true;
14136                        printedAnything = true;
14137                    }
14138                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14139                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14140                }
14141            }
14142        }
14143
14144        if (mForegroundProcesses.size() > 0) {
14145            synchronized (mPidsSelfLocked) {
14146                boolean printed = false;
14147                for (int i=0; i<mForegroundProcesses.size(); i++) {
14148                    ProcessRecord r = mPidsSelfLocked.get(
14149                            mForegroundProcesses.valueAt(i).pid);
14150                    if (dumpPackage != null && (r == null
14151                            || !r.pkgList.containsKey(dumpPackage))) {
14152                        continue;
14153                    }
14154                    if (!printed) {
14155                        if (needSep) pw.println();
14156                        needSep = true;
14157                        pw.println("  Foreground Processes:");
14158                        printed = true;
14159                        printedAnything = true;
14160                    }
14161                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14162                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14163                }
14164            }
14165        }
14166
14167        if (mPersistentStartingProcesses.size() > 0) {
14168            if (needSep) pw.println();
14169            needSep = true;
14170            printedAnything = true;
14171            pw.println("  Persisent processes that are starting:");
14172            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14173                    "Starting Norm", "Restarting PERS", dumpPackage);
14174        }
14175
14176        if (mRemovedProcesses.size() > 0) {
14177            if (needSep) pw.println();
14178            needSep = true;
14179            printedAnything = true;
14180            pw.println("  Processes that are being removed:");
14181            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14182                    "Removed Norm", "Removed PERS", dumpPackage);
14183        }
14184
14185        if (mProcessesOnHold.size() > 0) {
14186            if (needSep) pw.println();
14187            needSep = true;
14188            printedAnything = true;
14189            pw.println("  Processes that are on old until the system is ready:");
14190            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14191                    "OnHold Norm", "OnHold PERS", dumpPackage);
14192        }
14193
14194        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14195
14196        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14197        if (needSep) {
14198            printedAnything = true;
14199        }
14200
14201        if (dumpPackage == null) {
14202            pw.println();
14203            needSep = false;
14204            mUserController.dump(pw, dumpAll);
14205        }
14206        if (mHomeProcess != null && (dumpPackage == null
14207                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14208            if (needSep) {
14209                pw.println();
14210                needSep = false;
14211            }
14212            pw.println("  mHomeProcess: " + mHomeProcess);
14213        }
14214        if (mPreviousProcess != null && (dumpPackage == null
14215                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14216            if (needSep) {
14217                pw.println();
14218                needSep = false;
14219            }
14220            pw.println("  mPreviousProcess: " + mPreviousProcess);
14221        }
14222        if (dumpAll) {
14223            StringBuilder sb = new StringBuilder(128);
14224            sb.append("  mPreviousProcessVisibleTime: ");
14225            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14226            pw.println(sb);
14227        }
14228        if (mHeavyWeightProcess != null && (dumpPackage == null
14229                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14230            if (needSep) {
14231                pw.println();
14232                needSep = false;
14233            }
14234            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14235        }
14236        if (dumpPackage == null) {
14237            pw.println("  mConfiguration: " + mConfiguration);
14238        }
14239        if (dumpAll) {
14240            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14241            if (mCompatModePackages.getPackages().size() > 0) {
14242                boolean printed = false;
14243                for (Map.Entry<String, Integer> entry
14244                        : mCompatModePackages.getPackages().entrySet()) {
14245                    String pkg = entry.getKey();
14246                    int mode = entry.getValue();
14247                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14248                        continue;
14249                    }
14250                    if (!printed) {
14251                        pw.println("  mScreenCompatPackages:");
14252                        printed = true;
14253                    }
14254                    pw.print("    "); pw.print(pkg); pw.print(": ");
14255                            pw.print(mode); pw.println();
14256                }
14257            }
14258        }
14259        if (dumpPackage == null) {
14260            pw.println("  mWakefulness="
14261                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14262            pw.println("  mSleepTokens=" + mSleepTokens);
14263            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14264                    + lockScreenShownToString());
14265            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14266            if (mRunningVoice != null) {
14267                pw.println("  mRunningVoice=" + mRunningVoice);
14268                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14269            }
14270        }
14271        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14272                || mOrigWaitForDebugger) {
14273            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14274                    || dumpPackage.equals(mOrigDebugApp)) {
14275                if (needSep) {
14276                    pw.println();
14277                    needSep = false;
14278                }
14279                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14280                        + " mDebugTransient=" + mDebugTransient
14281                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14282            }
14283        }
14284        if (mCurAppTimeTracker != null) {
14285            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14286        }
14287        if (mMemWatchProcesses.getMap().size() > 0) {
14288            pw.println("  Mem watch processes:");
14289            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14290                    = mMemWatchProcesses.getMap();
14291            for (int i=0; i<procs.size(); i++) {
14292                final String proc = procs.keyAt(i);
14293                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14294                for (int j=0; j<uids.size(); j++) {
14295                    if (needSep) {
14296                        pw.println();
14297                        needSep = false;
14298                    }
14299                    StringBuilder sb = new StringBuilder();
14300                    sb.append("    ").append(proc).append('/');
14301                    UserHandle.formatUid(sb, uids.keyAt(j));
14302                    Pair<Long, String> val = uids.valueAt(j);
14303                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14304                    if (val.second != null) {
14305                        sb.append(", report to ").append(val.second);
14306                    }
14307                    pw.println(sb.toString());
14308                }
14309            }
14310            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14311            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14312            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14313                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14314        }
14315        if (mTrackAllocationApp != null) {
14316            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14317                if (needSep) {
14318                    pw.println();
14319                    needSep = false;
14320                }
14321                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14322            }
14323        }
14324        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14325                || mProfileFd != null) {
14326            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14327                if (needSep) {
14328                    pw.println();
14329                    needSep = false;
14330                }
14331                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14332                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14333                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14334                        + mAutoStopProfiler);
14335                pw.println("  mProfileType=" + mProfileType);
14336            }
14337        }
14338        if (mNativeDebuggingApp != null) {
14339            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14340                if (needSep) {
14341                    pw.println();
14342                    needSep = false;
14343                }
14344                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14345            }
14346        }
14347        if (dumpPackage == null) {
14348            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14349                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14350                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14351            }
14352            if (mController != null) {
14353                pw.println("  mController=" + mController
14354                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14355            }
14356            if (dumpAll) {
14357                pw.println("  Total persistent processes: " + numPers);
14358                pw.println("  mProcessesReady=" + mProcessesReady
14359                        + " mSystemReady=" + mSystemReady
14360                        + " mBooted=" + mBooted
14361                        + " mFactoryTest=" + mFactoryTest);
14362                pw.println("  mBooting=" + mBooting
14363                        + " mCallFinishBooting=" + mCallFinishBooting
14364                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14365                pw.print("  mLastPowerCheckRealtime=");
14366                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14367                        pw.println("");
14368                pw.print("  mLastPowerCheckUptime=");
14369                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14370                        pw.println("");
14371                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14372                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14373                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14374                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14375                        + " (" + mLruProcesses.size() + " total)"
14376                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14377                        + " mNumServiceProcs=" + mNumServiceProcs
14378                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14379                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14380                        + " mLastMemoryLevel=" + mLastMemoryLevel
14381                        + " mLastNumProcesses=" + mLastNumProcesses);
14382                long now = SystemClock.uptimeMillis();
14383                pw.print("  mLastIdleTime=");
14384                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14385                        pw.print(" mLowRamSinceLastIdle=");
14386                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14387                        pw.println();
14388            }
14389        }
14390
14391        if (!printedAnything) {
14392            pw.println("  (nothing)");
14393        }
14394    }
14395
14396    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14397            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14398        if (mProcessesToGc.size() > 0) {
14399            boolean printed = false;
14400            long now = SystemClock.uptimeMillis();
14401            for (int i=0; i<mProcessesToGc.size(); i++) {
14402                ProcessRecord proc = mProcessesToGc.get(i);
14403                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14404                    continue;
14405                }
14406                if (!printed) {
14407                    if (needSep) pw.println();
14408                    needSep = true;
14409                    pw.println("  Processes that are waiting to GC:");
14410                    printed = true;
14411                }
14412                pw.print("    Process "); pw.println(proc);
14413                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14414                        pw.print(", last gced=");
14415                        pw.print(now-proc.lastRequestedGc);
14416                        pw.print(" ms ago, last lowMem=");
14417                        pw.print(now-proc.lastLowMemory);
14418                        pw.println(" ms ago");
14419
14420            }
14421        }
14422        return needSep;
14423    }
14424
14425    void printOomLevel(PrintWriter pw, String name, int adj) {
14426        pw.print("    ");
14427        if (adj >= 0) {
14428            pw.print(' ');
14429            if (adj < 10) pw.print(' ');
14430        } else {
14431            if (adj > -10) pw.print(' ');
14432        }
14433        pw.print(adj);
14434        pw.print(": ");
14435        pw.print(name);
14436        pw.print(" (");
14437        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14438        pw.println(")");
14439    }
14440
14441    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14442            int opti, boolean dumpAll) {
14443        boolean needSep = false;
14444
14445        if (mLruProcesses.size() > 0) {
14446            if (needSep) pw.println();
14447            needSep = true;
14448            pw.println("  OOM levels:");
14449            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14450            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14451            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14452            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14453            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14454            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14455            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14456            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14457            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14458            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14459            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14460            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14461            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14462            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14463
14464            if (needSep) pw.println();
14465            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14466                    pw.print(" total, non-act at ");
14467                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14468                    pw.print(", non-svc at ");
14469                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14470                    pw.println("):");
14471            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14472            needSep = true;
14473        }
14474
14475        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14476
14477        pw.println();
14478        pw.println("  mHomeProcess: " + mHomeProcess);
14479        pw.println("  mPreviousProcess: " + mPreviousProcess);
14480        if (mHeavyWeightProcess != null) {
14481            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14482        }
14483
14484        return true;
14485    }
14486
14487    /**
14488     * There are three ways to call this:
14489     *  - no provider specified: dump all the providers
14490     *  - a flattened component name that matched an existing provider was specified as the
14491     *    first arg: dump that one provider
14492     *  - the first arg isn't the flattened component name of an existing provider:
14493     *    dump all providers whose component contains the first arg as a substring
14494     */
14495    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14496            int opti, boolean dumpAll) {
14497        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14498    }
14499
14500    static class ItemMatcher {
14501        ArrayList<ComponentName> components;
14502        ArrayList<String> strings;
14503        ArrayList<Integer> objects;
14504        boolean all;
14505
14506        ItemMatcher() {
14507            all = true;
14508        }
14509
14510        void build(String name) {
14511            ComponentName componentName = ComponentName.unflattenFromString(name);
14512            if (componentName != null) {
14513                if (components == null) {
14514                    components = new ArrayList<ComponentName>();
14515                }
14516                components.add(componentName);
14517                all = false;
14518            } else {
14519                int objectId = 0;
14520                // Not a '/' separated full component name; maybe an object ID?
14521                try {
14522                    objectId = Integer.parseInt(name, 16);
14523                    if (objects == null) {
14524                        objects = new ArrayList<Integer>();
14525                    }
14526                    objects.add(objectId);
14527                    all = false;
14528                } catch (RuntimeException e) {
14529                    // Not an integer; just do string match.
14530                    if (strings == null) {
14531                        strings = new ArrayList<String>();
14532                    }
14533                    strings.add(name);
14534                    all = false;
14535                }
14536            }
14537        }
14538
14539        int build(String[] args, int opti) {
14540            for (; opti<args.length; opti++) {
14541                String name = args[opti];
14542                if ("--".equals(name)) {
14543                    return opti+1;
14544                }
14545                build(name);
14546            }
14547            return opti;
14548        }
14549
14550        boolean match(Object object, ComponentName comp) {
14551            if (all) {
14552                return true;
14553            }
14554            if (components != null) {
14555                for (int i=0; i<components.size(); i++) {
14556                    if (components.get(i).equals(comp)) {
14557                        return true;
14558                    }
14559                }
14560            }
14561            if (objects != null) {
14562                for (int i=0; i<objects.size(); i++) {
14563                    if (System.identityHashCode(object) == objects.get(i)) {
14564                        return true;
14565                    }
14566                }
14567            }
14568            if (strings != null) {
14569                String flat = comp.flattenToString();
14570                for (int i=0; i<strings.size(); i++) {
14571                    if (flat.contains(strings.get(i))) {
14572                        return true;
14573                    }
14574                }
14575            }
14576            return false;
14577        }
14578    }
14579
14580    /**
14581     * There are three things that cmd can be:
14582     *  - a flattened component name that matches an existing activity
14583     *  - the cmd arg isn't the flattened component name of an existing activity:
14584     *    dump all activity whose component contains the cmd as a substring
14585     *  - A hex number of the ActivityRecord object instance.
14586     */
14587    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14588            int opti, boolean dumpAll) {
14589        ArrayList<ActivityRecord> activities;
14590
14591        synchronized (this) {
14592            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14593        }
14594
14595        if (activities.size() <= 0) {
14596            return false;
14597        }
14598
14599        String[] newArgs = new String[args.length - opti];
14600        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14601
14602        TaskRecord lastTask = null;
14603        boolean needSep = false;
14604        for (int i=activities.size()-1; i>=0; i--) {
14605            ActivityRecord r = activities.get(i);
14606            if (needSep) {
14607                pw.println();
14608            }
14609            needSep = true;
14610            synchronized (this) {
14611                if (lastTask != r.task) {
14612                    lastTask = r.task;
14613                    pw.print("TASK "); pw.print(lastTask.affinity);
14614                            pw.print(" id="); pw.println(lastTask.taskId);
14615                    if (dumpAll) {
14616                        lastTask.dump(pw, "  ");
14617                    }
14618                }
14619            }
14620            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14621        }
14622        return true;
14623    }
14624
14625    /**
14626     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14627     * there is a thread associated with the activity.
14628     */
14629    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14630            final ActivityRecord r, String[] args, boolean dumpAll) {
14631        String innerPrefix = prefix + "  ";
14632        synchronized (this) {
14633            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14634                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14635                    pw.print(" pid=");
14636                    if (r.app != null) pw.println(r.app.pid);
14637                    else pw.println("(not running)");
14638            if (dumpAll) {
14639                r.dump(pw, innerPrefix);
14640            }
14641        }
14642        if (r.app != null && r.app.thread != null) {
14643            // flush anything that is already in the PrintWriter since the thread is going
14644            // to write to the file descriptor directly
14645            pw.flush();
14646            try {
14647                TransferPipe tp = new TransferPipe();
14648                try {
14649                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14650                            r.appToken, innerPrefix, args);
14651                    tp.go(fd);
14652                } finally {
14653                    tp.kill();
14654                }
14655            } catch (IOException e) {
14656                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14657            } catch (RemoteException e) {
14658                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14659            }
14660        }
14661    }
14662
14663    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14664            int opti, boolean dumpAll, String dumpPackage) {
14665        boolean needSep = false;
14666        boolean onlyHistory = false;
14667        boolean printedAnything = false;
14668
14669        if ("history".equals(dumpPackage)) {
14670            if (opti < args.length && "-s".equals(args[opti])) {
14671                dumpAll = false;
14672            }
14673            onlyHistory = true;
14674            dumpPackage = null;
14675        }
14676
14677        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14678        if (!onlyHistory && dumpAll) {
14679            if (mRegisteredReceivers.size() > 0) {
14680                boolean printed = false;
14681                Iterator it = mRegisteredReceivers.values().iterator();
14682                while (it.hasNext()) {
14683                    ReceiverList r = (ReceiverList)it.next();
14684                    if (dumpPackage != null && (r.app == null ||
14685                            !dumpPackage.equals(r.app.info.packageName))) {
14686                        continue;
14687                    }
14688                    if (!printed) {
14689                        pw.println("  Registered Receivers:");
14690                        needSep = true;
14691                        printed = true;
14692                        printedAnything = true;
14693                    }
14694                    pw.print("  * "); pw.println(r);
14695                    r.dump(pw, "    ");
14696                }
14697            }
14698
14699            if (mReceiverResolver.dump(pw, needSep ?
14700                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14701                    "    ", dumpPackage, false, false)) {
14702                needSep = true;
14703                printedAnything = true;
14704            }
14705        }
14706
14707        for (BroadcastQueue q : mBroadcastQueues) {
14708            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14709            printedAnything |= needSep;
14710        }
14711
14712        needSep = true;
14713
14714        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14715            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14716                if (needSep) {
14717                    pw.println();
14718                }
14719                needSep = true;
14720                printedAnything = true;
14721                pw.print("  Sticky broadcasts for user ");
14722                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14723                StringBuilder sb = new StringBuilder(128);
14724                for (Map.Entry<String, ArrayList<Intent>> ent
14725                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14726                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14727                    if (dumpAll) {
14728                        pw.println(":");
14729                        ArrayList<Intent> intents = ent.getValue();
14730                        final int N = intents.size();
14731                        for (int i=0; i<N; i++) {
14732                            sb.setLength(0);
14733                            sb.append("    Intent: ");
14734                            intents.get(i).toShortString(sb, false, true, false, false);
14735                            pw.println(sb.toString());
14736                            Bundle bundle = intents.get(i).getExtras();
14737                            if (bundle != null) {
14738                                pw.print("      ");
14739                                pw.println(bundle.toString());
14740                            }
14741                        }
14742                    } else {
14743                        pw.println("");
14744                    }
14745                }
14746            }
14747        }
14748
14749        if (!onlyHistory && dumpAll) {
14750            pw.println();
14751            for (BroadcastQueue queue : mBroadcastQueues) {
14752                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14753                        + queue.mBroadcastsScheduled);
14754            }
14755            pw.println("  mHandler:");
14756            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14757            needSep = true;
14758            printedAnything = true;
14759        }
14760
14761        if (!printedAnything) {
14762            pw.println("  (nothing)");
14763        }
14764    }
14765
14766    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14767            int opti, boolean dumpAll, String dumpPackage) {
14768        boolean needSep;
14769        boolean printedAnything = false;
14770
14771        ItemMatcher matcher = new ItemMatcher();
14772        matcher.build(args, opti);
14773
14774        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14775
14776        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14777        printedAnything |= needSep;
14778
14779        if (mLaunchingProviders.size() > 0) {
14780            boolean printed = false;
14781            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14782                ContentProviderRecord r = mLaunchingProviders.get(i);
14783                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14784                    continue;
14785                }
14786                if (!printed) {
14787                    if (needSep) pw.println();
14788                    needSep = true;
14789                    pw.println("  Launching content providers:");
14790                    printed = true;
14791                    printedAnything = true;
14792                }
14793                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14794                        pw.println(r);
14795            }
14796        }
14797
14798        if (!printedAnything) {
14799            pw.println("  (nothing)");
14800        }
14801    }
14802
14803    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14804            int opti, boolean dumpAll, String dumpPackage) {
14805        boolean needSep = false;
14806        boolean printedAnything = false;
14807
14808        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14809
14810        if (mGrantedUriPermissions.size() > 0) {
14811            boolean printed = false;
14812            int dumpUid = -2;
14813            if (dumpPackage != null) {
14814                try {
14815                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14816                            MATCH_UNINSTALLED_PACKAGES, 0);
14817                } catch (NameNotFoundException e) {
14818                    dumpUid = -1;
14819                }
14820            }
14821            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14822                int uid = mGrantedUriPermissions.keyAt(i);
14823                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14824                    continue;
14825                }
14826                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14827                if (!printed) {
14828                    if (needSep) pw.println();
14829                    needSep = true;
14830                    pw.println("  Granted Uri Permissions:");
14831                    printed = true;
14832                    printedAnything = true;
14833                }
14834                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14835                for (UriPermission perm : perms.values()) {
14836                    pw.print("    "); pw.println(perm);
14837                    if (dumpAll) {
14838                        perm.dump(pw, "      ");
14839                    }
14840                }
14841            }
14842        }
14843
14844        if (!printedAnything) {
14845            pw.println("  (nothing)");
14846        }
14847    }
14848
14849    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14850            int opti, boolean dumpAll, String dumpPackage) {
14851        boolean printed = false;
14852
14853        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14854
14855        if (mIntentSenderRecords.size() > 0) {
14856            Iterator<WeakReference<PendingIntentRecord>> it
14857                    = mIntentSenderRecords.values().iterator();
14858            while (it.hasNext()) {
14859                WeakReference<PendingIntentRecord> ref = it.next();
14860                PendingIntentRecord rec = ref != null ? ref.get(): null;
14861                if (dumpPackage != null && (rec == null
14862                        || !dumpPackage.equals(rec.key.packageName))) {
14863                    continue;
14864                }
14865                printed = true;
14866                if (rec != null) {
14867                    pw.print("  * "); pw.println(rec);
14868                    if (dumpAll) {
14869                        rec.dump(pw, "    ");
14870                    }
14871                } else {
14872                    pw.print("  * "); pw.println(ref);
14873                }
14874            }
14875        }
14876
14877        if (!printed) {
14878            pw.println("  (nothing)");
14879        }
14880    }
14881
14882    private static final int dumpProcessList(PrintWriter pw,
14883            ActivityManagerService service, List list,
14884            String prefix, String normalLabel, String persistentLabel,
14885            String dumpPackage) {
14886        int numPers = 0;
14887        final int N = list.size()-1;
14888        for (int i=N; i>=0; i--) {
14889            ProcessRecord r = (ProcessRecord)list.get(i);
14890            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14891                continue;
14892            }
14893            pw.println(String.format("%s%s #%2d: %s",
14894                    prefix, (r.persistent ? persistentLabel : normalLabel),
14895                    i, r.toString()));
14896            if (r.persistent) {
14897                numPers++;
14898            }
14899        }
14900        return numPers;
14901    }
14902
14903    private static final boolean dumpProcessOomList(PrintWriter pw,
14904            ActivityManagerService service, List<ProcessRecord> origList,
14905            String prefix, String normalLabel, String persistentLabel,
14906            boolean inclDetails, String dumpPackage) {
14907
14908        ArrayList<Pair<ProcessRecord, Integer>> list
14909                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14910        for (int i=0; i<origList.size(); i++) {
14911            ProcessRecord r = origList.get(i);
14912            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14913                continue;
14914            }
14915            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14916        }
14917
14918        if (list.size() <= 0) {
14919            return false;
14920        }
14921
14922        Comparator<Pair<ProcessRecord, Integer>> comparator
14923                = new Comparator<Pair<ProcessRecord, Integer>>() {
14924            @Override
14925            public int compare(Pair<ProcessRecord, Integer> object1,
14926                    Pair<ProcessRecord, Integer> object2) {
14927                if (object1.first.setAdj != object2.first.setAdj) {
14928                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14929                }
14930                if (object1.first.setProcState != object2.first.setProcState) {
14931                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14932                }
14933                if (object1.second.intValue() != object2.second.intValue()) {
14934                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14935                }
14936                return 0;
14937            }
14938        };
14939
14940        Collections.sort(list, comparator);
14941
14942        final long curRealtime = SystemClock.elapsedRealtime();
14943        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14944        final long curUptime = SystemClock.uptimeMillis();
14945        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14946
14947        for (int i=list.size()-1; i>=0; i--) {
14948            ProcessRecord r = list.get(i).first;
14949            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14950            char schedGroup;
14951            switch (r.setSchedGroup) {
14952                case ProcessList.SCHED_GROUP_BACKGROUND:
14953                    schedGroup = 'B';
14954                    break;
14955                case ProcessList.SCHED_GROUP_DEFAULT:
14956                    schedGroup = 'F';
14957                    break;
14958                case ProcessList.SCHED_GROUP_TOP_APP:
14959                    schedGroup = 'T';
14960                    break;
14961                default:
14962                    schedGroup = '?';
14963                    break;
14964            }
14965            char foreground;
14966            if (r.foregroundActivities) {
14967                foreground = 'A';
14968            } else if (r.foregroundServices) {
14969                foreground = 'S';
14970            } else {
14971                foreground = ' ';
14972            }
14973            String procState = ProcessList.makeProcStateString(r.curProcState);
14974            pw.print(prefix);
14975            pw.print(r.persistent ? persistentLabel : normalLabel);
14976            pw.print(" #");
14977            int num = (origList.size()-1)-list.get(i).second;
14978            if (num < 10) pw.print(' ');
14979            pw.print(num);
14980            pw.print(": ");
14981            pw.print(oomAdj);
14982            pw.print(' ');
14983            pw.print(schedGroup);
14984            pw.print('/');
14985            pw.print(foreground);
14986            pw.print('/');
14987            pw.print(procState);
14988            pw.print(" trm:");
14989            if (r.trimMemoryLevel < 10) pw.print(' ');
14990            pw.print(r.trimMemoryLevel);
14991            pw.print(' ');
14992            pw.print(r.toShortString());
14993            pw.print(" (");
14994            pw.print(r.adjType);
14995            pw.println(')');
14996            if (r.adjSource != null || r.adjTarget != null) {
14997                pw.print(prefix);
14998                pw.print("    ");
14999                if (r.adjTarget instanceof ComponentName) {
15000                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15001                } else if (r.adjTarget != null) {
15002                    pw.print(r.adjTarget.toString());
15003                } else {
15004                    pw.print("{null}");
15005                }
15006                pw.print("<=");
15007                if (r.adjSource instanceof ProcessRecord) {
15008                    pw.print("Proc{");
15009                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15010                    pw.println("}");
15011                } else if (r.adjSource != null) {
15012                    pw.println(r.adjSource.toString());
15013                } else {
15014                    pw.println("{null}");
15015                }
15016            }
15017            if (inclDetails) {
15018                pw.print(prefix);
15019                pw.print("    ");
15020                pw.print("oom: max="); pw.print(r.maxAdj);
15021                pw.print(" curRaw="); pw.print(r.curRawAdj);
15022                pw.print(" setRaw="); pw.print(r.setRawAdj);
15023                pw.print(" cur="); pw.print(r.curAdj);
15024                pw.print(" set="); pw.println(r.setAdj);
15025                pw.print(prefix);
15026                pw.print("    ");
15027                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15028                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15029                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15030                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15031                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15032                pw.println();
15033                pw.print(prefix);
15034                pw.print("    ");
15035                pw.print("cached="); pw.print(r.cached);
15036                pw.print(" empty="); pw.print(r.empty);
15037                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15038
15039                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15040                    if (r.lastWakeTime != 0) {
15041                        long wtime;
15042                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15043                        synchronized (stats) {
15044                            wtime = stats.getProcessWakeTime(r.info.uid,
15045                                    r.pid, curRealtime);
15046                        }
15047                        long timeUsed = wtime - r.lastWakeTime;
15048                        pw.print(prefix);
15049                        pw.print("    ");
15050                        pw.print("keep awake over ");
15051                        TimeUtils.formatDuration(realtimeSince, pw);
15052                        pw.print(" used ");
15053                        TimeUtils.formatDuration(timeUsed, pw);
15054                        pw.print(" (");
15055                        pw.print((timeUsed*100)/realtimeSince);
15056                        pw.println("%)");
15057                    }
15058                    if (r.lastCpuTime != 0) {
15059                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15060                        pw.print(prefix);
15061                        pw.print("    ");
15062                        pw.print("run cpu over ");
15063                        TimeUtils.formatDuration(uptimeSince, pw);
15064                        pw.print(" used ");
15065                        TimeUtils.formatDuration(timeUsed, pw);
15066                        pw.print(" (");
15067                        pw.print((timeUsed*100)/uptimeSince);
15068                        pw.println("%)");
15069                    }
15070                }
15071            }
15072        }
15073        return true;
15074    }
15075
15076    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15077            String[] args) {
15078        ArrayList<ProcessRecord> procs;
15079        synchronized (this) {
15080            if (args != null && args.length > start
15081                    && args[start].charAt(0) != '-') {
15082                procs = new ArrayList<ProcessRecord>();
15083                int pid = -1;
15084                try {
15085                    pid = Integer.parseInt(args[start]);
15086                } catch (NumberFormatException e) {
15087                }
15088                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15089                    ProcessRecord proc = mLruProcesses.get(i);
15090                    if (proc.pid == pid) {
15091                        procs.add(proc);
15092                    } else if (allPkgs && proc.pkgList != null
15093                            && proc.pkgList.containsKey(args[start])) {
15094                        procs.add(proc);
15095                    } else if (proc.processName.equals(args[start])) {
15096                        procs.add(proc);
15097                    }
15098                }
15099                if (procs.size() <= 0) {
15100                    return null;
15101                }
15102            } else {
15103                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15104            }
15105        }
15106        return procs;
15107    }
15108
15109    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15110            PrintWriter pw, String[] args) {
15111        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15112        if (procs == null) {
15113            pw.println("No process found for: " + args[0]);
15114            return;
15115        }
15116
15117        long uptime = SystemClock.uptimeMillis();
15118        long realtime = SystemClock.elapsedRealtime();
15119        pw.println("Applications Graphics Acceleration Info:");
15120        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15121
15122        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15123            ProcessRecord r = procs.get(i);
15124            if (r.thread != null) {
15125                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15126                pw.flush();
15127                try {
15128                    TransferPipe tp = new TransferPipe();
15129                    try {
15130                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15131                        tp.go(fd);
15132                    } finally {
15133                        tp.kill();
15134                    }
15135                } catch (IOException e) {
15136                    pw.println("Failure while dumping the app: " + r);
15137                    pw.flush();
15138                } catch (RemoteException e) {
15139                    pw.println("Got a RemoteException while dumping the app " + r);
15140                    pw.flush();
15141                }
15142            }
15143        }
15144    }
15145
15146    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15147        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15148        if (procs == null) {
15149            pw.println("No process found for: " + args[0]);
15150            return;
15151        }
15152
15153        pw.println("Applications Database Info:");
15154
15155        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15156            ProcessRecord r = procs.get(i);
15157            if (r.thread != null) {
15158                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15159                pw.flush();
15160                try {
15161                    TransferPipe tp = new TransferPipe();
15162                    try {
15163                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15164                        tp.go(fd);
15165                    } finally {
15166                        tp.kill();
15167                    }
15168                } catch (IOException e) {
15169                    pw.println("Failure while dumping the app: " + r);
15170                    pw.flush();
15171                } catch (RemoteException e) {
15172                    pw.println("Got a RemoteException while dumping the app " + r);
15173                    pw.flush();
15174                }
15175            }
15176        }
15177    }
15178
15179    final static class MemItem {
15180        final boolean isProc;
15181        final String label;
15182        final String shortLabel;
15183        final long pss;
15184        final long swapPss;
15185        final int id;
15186        final boolean hasActivities;
15187        ArrayList<MemItem> subitems;
15188
15189        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15190                boolean _hasActivities) {
15191            isProc = true;
15192            label = _label;
15193            shortLabel = _shortLabel;
15194            pss = _pss;
15195            swapPss = _swapPss;
15196            id = _id;
15197            hasActivities = _hasActivities;
15198        }
15199
15200        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15201            isProc = false;
15202            label = _label;
15203            shortLabel = _shortLabel;
15204            pss = _pss;
15205            swapPss = _swapPss;
15206            id = _id;
15207            hasActivities = false;
15208        }
15209    }
15210
15211    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15212            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15213        if (sort && !isCompact) {
15214            Collections.sort(items, new Comparator<MemItem>() {
15215                @Override
15216                public int compare(MemItem lhs, MemItem rhs) {
15217                    if (lhs.pss < rhs.pss) {
15218                        return 1;
15219                    } else if (lhs.pss > rhs.pss) {
15220                        return -1;
15221                    }
15222                    return 0;
15223                }
15224            });
15225        }
15226
15227        for (int i=0; i<items.size(); i++) {
15228            MemItem mi = items.get(i);
15229            if (!isCompact) {
15230                if (dumpSwapPss) {
15231                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15232                            mi.label, stringifyKBSize(mi.swapPss));
15233                } else {
15234                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15235                }
15236            } else if (mi.isProc) {
15237                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15238                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15239                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15240                pw.println(mi.hasActivities ? ",a" : ",e");
15241            } else {
15242                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15243                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15244            }
15245            if (mi.subitems != null) {
15246                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15247                        true, isCompact, dumpSwapPss);
15248            }
15249        }
15250    }
15251
15252    // These are in KB.
15253    static final long[] DUMP_MEM_BUCKETS = new long[] {
15254        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15255        120*1024, 160*1024, 200*1024,
15256        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15257        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15258    };
15259
15260    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15261            boolean stackLike) {
15262        int start = label.lastIndexOf('.');
15263        if (start >= 0) start++;
15264        else start = 0;
15265        int end = label.length();
15266        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15267            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15268                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15269                out.append(bucket);
15270                out.append(stackLike ? "MB." : "MB ");
15271                out.append(label, start, end);
15272                return;
15273            }
15274        }
15275        out.append(memKB/1024);
15276        out.append(stackLike ? "MB." : "MB ");
15277        out.append(label, start, end);
15278    }
15279
15280    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15281            ProcessList.NATIVE_ADJ,
15282            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15283            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15284            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15285            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15286            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15287            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15288    };
15289    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15290            "Native",
15291            "System", "Persistent", "Persistent Service", "Foreground",
15292            "Visible", "Perceptible",
15293            "Heavy Weight", "Backup",
15294            "A Services", "Home",
15295            "Previous", "B Services", "Cached"
15296    };
15297    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15298            "native",
15299            "sys", "pers", "persvc", "fore",
15300            "vis", "percept",
15301            "heavy", "backup",
15302            "servicea", "home",
15303            "prev", "serviceb", "cached"
15304    };
15305
15306    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15307            long realtime, boolean isCheckinRequest, boolean isCompact) {
15308        if (isCompact) {
15309            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15310        }
15311        if (isCheckinRequest || isCompact) {
15312            // short checkin version
15313            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15314        } else {
15315            pw.println("Applications Memory Usage (in Kilobytes):");
15316            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15317        }
15318    }
15319
15320    private static final int KSM_SHARED = 0;
15321    private static final int KSM_SHARING = 1;
15322    private static final int KSM_UNSHARED = 2;
15323    private static final int KSM_VOLATILE = 3;
15324
15325    private final long[] getKsmInfo() {
15326        long[] longOut = new long[4];
15327        final int[] SINGLE_LONG_FORMAT = new int[] {
15328            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15329        };
15330        long[] longTmp = new long[1];
15331        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15332                SINGLE_LONG_FORMAT, null, longTmp, null);
15333        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15334        longTmp[0] = 0;
15335        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15336                SINGLE_LONG_FORMAT, null, longTmp, null);
15337        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15338        longTmp[0] = 0;
15339        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15340                SINGLE_LONG_FORMAT, null, longTmp, null);
15341        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15342        longTmp[0] = 0;
15343        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15344                SINGLE_LONG_FORMAT, null, longTmp, null);
15345        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15346        return longOut;
15347    }
15348
15349    private static String stringifySize(long size, int order) {
15350        Locale locale = Locale.US;
15351        switch (order) {
15352            case 1:
15353                return String.format(locale, "%,13d", size);
15354            case 1024:
15355                return String.format(locale, "%,9dK", size / 1024);
15356            case 1024 * 1024:
15357                return String.format(locale, "%,5dM", size / 1024 / 1024);
15358            case 1024 * 1024 * 1024:
15359                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15360            default:
15361                throw new IllegalArgumentException("Invalid size order");
15362        }
15363    }
15364
15365    private static String stringifyKBSize(long size) {
15366        return stringifySize(size * 1024, 1024);
15367    }
15368
15369    // Update this version number in case you change the 'compact' format
15370    private static final int MEMINFO_COMPACT_VERSION = 1;
15371
15372    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15373            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15374        boolean dumpDetails = false;
15375        boolean dumpFullDetails = false;
15376        boolean dumpDalvik = false;
15377        boolean dumpSummaryOnly = false;
15378        boolean dumpUnreachable = false;
15379        boolean oomOnly = false;
15380        boolean isCompact = false;
15381        boolean localOnly = false;
15382        boolean packages = false;
15383        boolean isCheckinRequest = false;
15384        boolean dumpSwapPss = false;
15385
15386        int opti = 0;
15387        while (opti < args.length) {
15388            String opt = args[opti];
15389            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15390                break;
15391            }
15392            opti++;
15393            if ("-a".equals(opt)) {
15394                dumpDetails = true;
15395                dumpFullDetails = true;
15396                dumpDalvik = true;
15397                dumpSwapPss = true;
15398            } else if ("-d".equals(opt)) {
15399                dumpDalvik = true;
15400            } else if ("-c".equals(opt)) {
15401                isCompact = true;
15402            } else if ("-s".equals(opt)) {
15403                dumpDetails = true;
15404                dumpSummaryOnly = true;
15405            } else if ("-S".equals(opt)) {
15406                dumpSwapPss = true;
15407            } else if ("--unreachable".equals(opt)) {
15408                dumpUnreachable = true;
15409            } else if ("--oom".equals(opt)) {
15410                oomOnly = true;
15411            } else if ("--local".equals(opt)) {
15412                localOnly = true;
15413            } else if ("--package".equals(opt)) {
15414                packages = true;
15415            } else if ("--checkin".equals(opt)) {
15416                isCheckinRequest = true;
15417
15418            } else if ("-h".equals(opt)) {
15419                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15420                pw.println("  -a: include all available information for each process.");
15421                pw.println("  -d: include dalvik details.");
15422                pw.println("  -c: dump in a compact machine-parseable representation.");
15423                pw.println("  -s: dump only summary of application memory usage.");
15424                pw.println("  -S: dump also SwapPss.");
15425                pw.println("  --oom: only show processes organized by oom adj.");
15426                pw.println("  --local: only collect details locally, don't call process.");
15427                pw.println("  --package: interpret process arg as package, dumping all");
15428                pw.println("             processes that have loaded that package.");
15429                pw.println("  --checkin: dump data for a checkin");
15430                pw.println("If [process] is specified it can be the name or ");
15431                pw.println("pid of a specific process to dump.");
15432                return;
15433            } else {
15434                pw.println("Unknown argument: " + opt + "; use -h for help");
15435            }
15436        }
15437
15438        long uptime = SystemClock.uptimeMillis();
15439        long realtime = SystemClock.elapsedRealtime();
15440        final long[] tmpLong = new long[1];
15441
15442        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15443        if (procs == null) {
15444            // No Java processes.  Maybe they want to print a native process.
15445            if (args != null && args.length > opti
15446                    && args[opti].charAt(0) != '-') {
15447                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15448                        = new ArrayList<ProcessCpuTracker.Stats>();
15449                updateCpuStatsNow();
15450                int findPid = -1;
15451                try {
15452                    findPid = Integer.parseInt(args[opti]);
15453                } catch (NumberFormatException e) {
15454                }
15455                synchronized (mProcessCpuTracker) {
15456                    final int N = mProcessCpuTracker.countStats();
15457                    for (int i=0; i<N; i++) {
15458                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15459                        if (st.pid == findPid || (st.baseName != null
15460                                && st.baseName.equals(args[opti]))) {
15461                            nativeProcs.add(st);
15462                        }
15463                    }
15464                }
15465                if (nativeProcs.size() > 0) {
15466                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15467                            isCompact);
15468                    Debug.MemoryInfo mi = null;
15469                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15470                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15471                        final int pid = r.pid;
15472                        if (!isCheckinRequest && dumpDetails) {
15473                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15474                        }
15475                        if (mi == null) {
15476                            mi = new Debug.MemoryInfo();
15477                        }
15478                        if (dumpDetails || (!brief && !oomOnly)) {
15479                            Debug.getMemoryInfo(pid, mi);
15480                        } else {
15481                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15482                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15483                        }
15484                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15485                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15486                        if (isCheckinRequest) {
15487                            pw.println();
15488                        }
15489                    }
15490                    return;
15491                }
15492            }
15493            pw.println("No process found for: " + args[opti]);
15494            return;
15495        }
15496
15497        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15498            dumpDetails = true;
15499        }
15500
15501        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15502
15503        String[] innerArgs = new String[args.length-opti];
15504        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15505
15506        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15507        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15508        long nativePss = 0;
15509        long nativeSwapPss = 0;
15510        long dalvikPss = 0;
15511        long dalvikSwapPss = 0;
15512        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15513                EmptyArray.LONG;
15514        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15515                EmptyArray.LONG;
15516        long otherPss = 0;
15517        long otherSwapPss = 0;
15518        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15519        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15520
15521        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15522        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15523        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15524                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15525
15526        long totalPss = 0;
15527        long totalSwapPss = 0;
15528        long cachedPss = 0;
15529        long cachedSwapPss = 0;
15530        boolean hasSwapPss = false;
15531
15532        Debug.MemoryInfo mi = null;
15533        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15534            final ProcessRecord r = procs.get(i);
15535            final IApplicationThread thread;
15536            final int pid;
15537            final int oomAdj;
15538            final boolean hasActivities;
15539            synchronized (this) {
15540                thread = r.thread;
15541                pid = r.pid;
15542                oomAdj = r.getSetAdjWithServices();
15543                hasActivities = r.activities.size() > 0;
15544            }
15545            if (thread != null) {
15546                if (!isCheckinRequest && dumpDetails) {
15547                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15548                }
15549                if (mi == null) {
15550                    mi = new Debug.MemoryInfo();
15551                }
15552                if (dumpDetails || (!brief && !oomOnly)) {
15553                    Debug.getMemoryInfo(pid, mi);
15554                    hasSwapPss = mi.hasSwappedOutPss;
15555                } else {
15556                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15557                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15558                }
15559                if (dumpDetails) {
15560                    if (localOnly) {
15561                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15562                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15563                        if (isCheckinRequest) {
15564                            pw.println();
15565                        }
15566                    } else {
15567                        try {
15568                            pw.flush();
15569                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15570                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15571                        } catch (RemoteException e) {
15572                            if (!isCheckinRequest) {
15573                                pw.println("Got RemoteException!");
15574                                pw.flush();
15575                            }
15576                        }
15577                    }
15578                }
15579
15580                final long myTotalPss = mi.getTotalPss();
15581                final long myTotalUss = mi.getTotalUss();
15582                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15583
15584                synchronized (this) {
15585                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15586                        // Record this for posterity if the process has been stable.
15587                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15588                    }
15589                }
15590
15591                if (!isCheckinRequest && mi != null) {
15592                    totalPss += myTotalPss;
15593                    totalSwapPss += myTotalSwapPss;
15594                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15595                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15596                            myTotalSwapPss, pid, hasActivities);
15597                    procMems.add(pssItem);
15598                    procMemsMap.put(pid, pssItem);
15599
15600                    nativePss += mi.nativePss;
15601                    nativeSwapPss += mi.nativeSwappedOutPss;
15602                    dalvikPss += mi.dalvikPss;
15603                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15604                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15605                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15606                        dalvikSubitemSwapPss[j] +=
15607                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15608                    }
15609                    otherPss += mi.otherPss;
15610                    otherSwapPss += mi.otherSwappedOutPss;
15611                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15612                        long mem = mi.getOtherPss(j);
15613                        miscPss[j] += mem;
15614                        otherPss -= mem;
15615                        mem = mi.getOtherSwappedOutPss(j);
15616                        miscSwapPss[j] += mem;
15617                        otherSwapPss -= mem;
15618                    }
15619
15620                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15621                        cachedPss += myTotalPss;
15622                        cachedSwapPss += myTotalSwapPss;
15623                    }
15624
15625                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15626                        if (oomIndex == (oomPss.length - 1)
15627                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15628                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15629                            oomPss[oomIndex] += myTotalPss;
15630                            oomSwapPss[oomIndex] += myTotalSwapPss;
15631                            if (oomProcs[oomIndex] == null) {
15632                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15633                            }
15634                            oomProcs[oomIndex].add(pssItem);
15635                            break;
15636                        }
15637                    }
15638                }
15639            }
15640        }
15641
15642        long nativeProcTotalPss = 0;
15643
15644        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15645            // If we are showing aggregations, also look for native processes to
15646            // include so that our aggregations are more accurate.
15647            updateCpuStatsNow();
15648            mi = null;
15649            synchronized (mProcessCpuTracker) {
15650                final int N = mProcessCpuTracker.countStats();
15651                for (int i=0; i<N; i++) {
15652                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15653                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15654                        if (mi == null) {
15655                            mi = new Debug.MemoryInfo();
15656                        }
15657                        if (!brief && !oomOnly) {
15658                            Debug.getMemoryInfo(st.pid, mi);
15659                        } else {
15660                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15661                            mi.nativePrivateDirty = (int)tmpLong[0];
15662                        }
15663
15664                        final long myTotalPss = mi.getTotalPss();
15665                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15666                        totalPss += myTotalPss;
15667                        nativeProcTotalPss += myTotalPss;
15668
15669                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15670                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15671                        procMems.add(pssItem);
15672
15673                        nativePss += mi.nativePss;
15674                        nativeSwapPss += mi.nativeSwappedOutPss;
15675                        dalvikPss += mi.dalvikPss;
15676                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15677                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15678                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15679                            dalvikSubitemSwapPss[j] +=
15680                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15681                        }
15682                        otherPss += mi.otherPss;
15683                        otherSwapPss += mi.otherSwappedOutPss;
15684                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15685                            long mem = mi.getOtherPss(j);
15686                            miscPss[j] += mem;
15687                            otherPss -= mem;
15688                            mem = mi.getOtherSwappedOutPss(j);
15689                            miscSwapPss[j] += mem;
15690                            otherSwapPss -= mem;
15691                        }
15692                        oomPss[0] += myTotalPss;
15693                        oomSwapPss[0] += myTotalSwapPss;
15694                        if (oomProcs[0] == null) {
15695                            oomProcs[0] = new ArrayList<MemItem>();
15696                        }
15697                        oomProcs[0].add(pssItem);
15698                    }
15699                }
15700            }
15701
15702            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15703
15704            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15705            final MemItem dalvikItem =
15706                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15707            if (dalvikSubitemPss.length > 0) {
15708                dalvikItem.subitems = new ArrayList<MemItem>();
15709                for (int j=0; j<dalvikSubitemPss.length; j++) {
15710                    final String name = Debug.MemoryInfo.getOtherLabel(
15711                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15712                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15713                                    dalvikSubitemSwapPss[j], j));
15714                }
15715            }
15716            catMems.add(dalvikItem);
15717            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15718            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15719                String label = Debug.MemoryInfo.getOtherLabel(j);
15720                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15721            }
15722
15723            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15724            for (int j=0; j<oomPss.length; j++) {
15725                if (oomPss[j] != 0) {
15726                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15727                            : DUMP_MEM_OOM_LABEL[j];
15728                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15729                            DUMP_MEM_OOM_ADJ[j]);
15730                    item.subitems = oomProcs[j];
15731                    oomMems.add(item);
15732                }
15733            }
15734
15735            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15736            if (!brief && !oomOnly && !isCompact) {
15737                pw.println();
15738                pw.println("Total PSS by process:");
15739                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15740                pw.println();
15741            }
15742            if (!isCompact) {
15743                pw.println("Total PSS by OOM adjustment:");
15744            }
15745            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15746            if (!brief && !oomOnly) {
15747                PrintWriter out = categoryPw != null ? categoryPw : pw;
15748                if (!isCompact) {
15749                    out.println();
15750                    out.println("Total PSS by category:");
15751                }
15752                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15753            }
15754            if (!isCompact) {
15755                pw.println();
15756            }
15757            MemInfoReader memInfo = new MemInfoReader();
15758            memInfo.readMemInfo();
15759            if (nativeProcTotalPss > 0) {
15760                synchronized (this) {
15761                    final long cachedKb = memInfo.getCachedSizeKb();
15762                    final long freeKb = memInfo.getFreeSizeKb();
15763                    final long zramKb = memInfo.getZramTotalSizeKb();
15764                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15765                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15766                            kernelKb*1024, nativeProcTotalPss*1024);
15767                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15768                            nativeProcTotalPss);
15769                }
15770            }
15771            if (!brief) {
15772                if (!isCompact) {
15773                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15774                    pw.print(" (status ");
15775                    switch (mLastMemoryLevel) {
15776                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15777                            pw.println("normal)");
15778                            break;
15779                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15780                            pw.println("moderate)");
15781                            break;
15782                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15783                            pw.println("low)");
15784                            break;
15785                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15786                            pw.println("critical)");
15787                            break;
15788                        default:
15789                            pw.print(mLastMemoryLevel);
15790                            pw.println(")");
15791                            break;
15792                    }
15793                    pw.print(" Free RAM: ");
15794                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15795                            + memInfo.getFreeSizeKb()));
15796                    pw.print(" (");
15797                    pw.print(stringifyKBSize(cachedPss));
15798                    pw.print(" cached pss + ");
15799                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15800                    pw.print(" cached kernel + ");
15801                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15802                    pw.println(" free)");
15803                } else {
15804                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15805                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15806                            + memInfo.getFreeSizeKb()); pw.print(",");
15807                    pw.println(totalPss - cachedPss);
15808                }
15809            }
15810            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15811                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15812                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15813            if (!isCompact) {
15814                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15815                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15816                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15817                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15818                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15819            } else {
15820                pw.print("lostram,"); pw.println(lostRAM);
15821            }
15822            if (!brief) {
15823                if (memInfo.getZramTotalSizeKb() != 0) {
15824                    if (!isCompact) {
15825                        pw.print("     ZRAM: ");
15826                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15827                                pw.print(" physical used for ");
15828                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15829                                        - memInfo.getSwapFreeSizeKb()));
15830                                pw.print(" in swap (");
15831                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15832                                pw.println(" total swap)");
15833                    } else {
15834                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15835                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15836                                pw.println(memInfo.getSwapFreeSizeKb());
15837                    }
15838                }
15839                final long[] ksm = getKsmInfo();
15840                if (!isCompact) {
15841                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15842                            || ksm[KSM_VOLATILE] != 0) {
15843                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15844                                pw.print(" saved from shared ");
15845                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15846                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15847                                pw.print(" unshared; ");
15848                                pw.print(stringifyKBSize(
15849                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15850                    }
15851                    pw.print("   Tuning: ");
15852                    pw.print(ActivityManager.staticGetMemoryClass());
15853                    pw.print(" (large ");
15854                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15855                    pw.print("), oom ");
15856                    pw.print(stringifySize(
15857                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15858                    pw.print(", restore limit ");
15859                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15860                    if (ActivityManager.isLowRamDeviceStatic()) {
15861                        pw.print(" (low-ram)");
15862                    }
15863                    if (ActivityManager.isHighEndGfx()) {
15864                        pw.print(" (high-end-gfx)");
15865                    }
15866                    pw.println();
15867                } else {
15868                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15869                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15870                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15871                    pw.print("tuning,");
15872                    pw.print(ActivityManager.staticGetMemoryClass());
15873                    pw.print(',');
15874                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15875                    pw.print(',');
15876                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15877                    if (ActivityManager.isLowRamDeviceStatic()) {
15878                        pw.print(",low-ram");
15879                    }
15880                    if (ActivityManager.isHighEndGfx()) {
15881                        pw.print(",high-end-gfx");
15882                    }
15883                    pw.println();
15884                }
15885            }
15886        }
15887    }
15888
15889    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15890            long memtrack, String name) {
15891        sb.append("  ");
15892        sb.append(ProcessList.makeOomAdjString(oomAdj));
15893        sb.append(' ');
15894        sb.append(ProcessList.makeProcStateString(procState));
15895        sb.append(' ');
15896        ProcessList.appendRamKb(sb, pss);
15897        sb.append(": ");
15898        sb.append(name);
15899        if (memtrack > 0) {
15900            sb.append(" (");
15901            sb.append(stringifyKBSize(memtrack));
15902            sb.append(" memtrack)");
15903        }
15904    }
15905
15906    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15907        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15908        sb.append(" (pid ");
15909        sb.append(mi.pid);
15910        sb.append(") ");
15911        sb.append(mi.adjType);
15912        sb.append('\n');
15913        if (mi.adjReason != null) {
15914            sb.append("                      ");
15915            sb.append(mi.adjReason);
15916            sb.append('\n');
15917        }
15918    }
15919
15920    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15921        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15922        for (int i=0, N=memInfos.size(); i<N; i++) {
15923            ProcessMemInfo mi = memInfos.get(i);
15924            infoMap.put(mi.pid, mi);
15925        }
15926        updateCpuStatsNow();
15927        long[] memtrackTmp = new long[1];
15928        synchronized (mProcessCpuTracker) {
15929            final int N = mProcessCpuTracker.countStats();
15930            for (int i=0; i<N; i++) {
15931                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15932                if (st.vsize > 0) {
15933                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15934                    if (pss > 0) {
15935                        if (infoMap.indexOfKey(st.pid) < 0) {
15936                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15937                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15938                            mi.pss = pss;
15939                            mi.memtrack = memtrackTmp[0];
15940                            memInfos.add(mi);
15941                        }
15942                    }
15943                }
15944            }
15945        }
15946
15947        long totalPss = 0;
15948        long totalMemtrack = 0;
15949        for (int i=0, N=memInfos.size(); i<N; i++) {
15950            ProcessMemInfo mi = memInfos.get(i);
15951            if (mi.pss == 0) {
15952                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15953                mi.memtrack = memtrackTmp[0];
15954            }
15955            totalPss += mi.pss;
15956            totalMemtrack += mi.memtrack;
15957        }
15958        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15959            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15960                if (lhs.oomAdj != rhs.oomAdj) {
15961                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15962                }
15963                if (lhs.pss != rhs.pss) {
15964                    return lhs.pss < rhs.pss ? 1 : -1;
15965                }
15966                return 0;
15967            }
15968        });
15969
15970        StringBuilder tag = new StringBuilder(128);
15971        StringBuilder stack = new StringBuilder(128);
15972        tag.append("Low on memory -- ");
15973        appendMemBucket(tag, totalPss, "total", false);
15974        appendMemBucket(stack, totalPss, "total", true);
15975
15976        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15977        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15978        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15979
15980        boolean firstLine = true;
15981        int lastOomAdj = Integer.MIN_VALUE;
15982        long extraNativeRam = 0;
15983        long extraNativeMemtrack = 0;
15984        long cachedPss = 0;
15985        for (int i=0, N=memInfos.size(); i<N; i++) {
15986            ProcessMemInfo mi = memInfos.get(i);
15987
15988            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15989                cachedPss += mi.pss;
15990            }
15991
15992            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15993                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15994                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15995                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15996                if (lastOomAdj != mi.oomAdj) {
15997                    lastOomAdj = mi.oomAdj;
15998                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15999                        tag.append(" / ");
16000                    }
16001                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16002                        if (firstLine) {
16003                            stack.append(":");
16004                            firstLine = false;
16005                        }
16006                        stack.append("\n\t at ");
16007                    } else {
16008                        stack.append("$");
16009                    }
16010                } else {
16011                    tag.append(" ");
16012                    stack.append("$");
16013                }
16014                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16015                    appendMemBucket(tag, mi.pss, mi.name, false);
16016                }
16017                appendMemBucket(stack, mi.pss, mi.name, true);
16018                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16019                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16020                    stack.append("(");
16021                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16022                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16023                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16024                            stack.append(":");
16025                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16026                        }
16027                    }
16028                    stack.append(")");
16029                }
16030            }
16031
16032            appendMemInfo(fullNativeBuilder, mi);
16033            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16034                // The short form only has native processes that are >= 512K.
16035                if (mi.pss >= 512) {
16036                    appendMemInfo(shortNativeBuilder, mi);
16037                } else {
16038                    extraNativeRam += mi.pss;
16039                    extraNativeMemtrack += mi.memtrack;
16040                }
16041            } else {
16042                // Short form has all other details, but if we have collected RAM
16043                // from smaller native processes let's dump a summary of that.
16044                if (extraNativeRam > 0) {
16045                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16046                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16047                    shortNativeBuilder.append('\n');
16048                    extraNativeRam = 0;
16049                }
16050                appendMemInfo(fullJavaBuilder, mi);
16051            }
16052        }
16053
16054        fullJavaBuilder.append("           ");
16055        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16056        fullJavaBuilder.append(": TOTAL");
16057        if (totalMemtrack > 0) {
16058            fullJavaBuilder.append(" (");
16059            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16060            fullJavaBuilder.append(" memtrack)");
16061        } else {
16062        }
16063        fullJavaBuilder.append("\n");
16064
16065        MemInfoReader memInfo = new MemInfoReader();
16066        memInfo.readMemInfo();
16067        final long[] infos = memInfo.getRawInfo();
16068
16069        StringBuilder memInfoBuilder = new StringBuilder(1024);
16070        Debug.getMemInfo(infos);
16071        memInfoBuilder.append("  MemInfo: ");
16072        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16073        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16074        memInfoBuilder.append(stringifyKBSize(
16075                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16076        memInfoBuilder.append(stringifyKBSize(
16077                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16078        memInfoBuilder.append(stringifyKBSize(
16079                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16080        memInfoBuilder.append("           ");
16081        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16082        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16083        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16084        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16085        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16086            memInfoBuilder.append("  ZRAM: ");
16087            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16088            memInfoBuilder.append(" RAM, ");
16089            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16090            memInfoBuilder.append(" swap total, ");
16091            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16092            memInfoBuilder.append(" swap free\n");
16093        }
16094        final long[] ksm = getKsmInfo();
16095        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16096                || ksm[KSM_VOLATILE] != 0) {
16097            memInfoBuilder.append("  KSM: ");
16098            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16099            memInfoBuilder.append(" saved from shared ");
16100            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16101            memInfoBuilder.append("\n       ");
16102            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16103            memInfoBuilder.append(" unshared; ");
16104            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16105            memInfoBuilder.append(" volatile\n");
16106        }
16107        memInfoBuilder.append("  Free RAM: ");
16108        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16109                + memInfo.getFreeSizeKb()));
16110        memInfoBuilder.append("\n");
16111        memInfoBuilder.append("  Used RAM: ");
16112        memInfoBuilder.append(stringifyKBSize(
16113                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16114        memInfoBuilder.append("\n");
16115        memInfoBuilder.append("  Lost RAM: ");
16116        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16117                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16118                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16119        memInfoBuilder.append("\n");
16120        Slog.i(TAG, "Low on memory:");
16121        Slog.i(TAG, shortNativeBuilder.toString());
16122        Slog.i(TAG, fullJavaBuilder.toString());
16123        Slog.i(TAG, memInfoBuilder.toString());
16124
16125        StringBuilder dropBuilder = new StringBuilder(1024);
16126        /*
16127        StringWriter oomSw = new StringWriter();
16128        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16129        StringWriter catSw = new StringWriter();
16130        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16131        String[] emptyArgs = new String[] { };
16132        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16133        oomPw.flush();
16134        String oomString = oomSw.toString();
16135        */
16136        dropBuilder.append("Low on memory:");
16137        dropBuilder.append(stack);
16138        dropBuilder.append('\n');
16139        dropBuilder.append(fullNativeBuilder);
16140        dropBuilder.append(fullJavaBuilder);
16141        dropBuilder.append('\n');
16142        dropBuilder.append(memInfoBuilder);
16143        dropBuilder.append('\n');
16144        /*
16145        dropBuilder.append(oomString);
16146        dropBuilder.append('\n');
16147        */
16148        StringWriter catSw = new StringWriter();
16149        synchronized (ActivityManagerService.this) {
16150            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16151            String[] emptyArgs = new String[] { };
16152            catPw.println();
16153            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16154            catPw.println();
16155            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16156                    false, false, null);
16157            catPw.println();
16158            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16159            catPw.flush();
16160        }
16161        dropBuilder.append(catSw.toString());
16162        addErrorToDropBox("lowmem", null, "system_server", null,
16163                null, tag.toString(), dropBuilder.toString(), null, null);
16164        //Slog.i(TAG, "Sent to dropbox:");
16165        //Slog.i(TAG, dropBuilder.toString());
16166        synchronized (ActivityManagerService.this) {
16167            long now = SystemClock.uptimeMillis();
16168            if (mLastMemUsageReportTime < now) {
16169                mLastMemUsageReportTime = now;
16170            }
16171        }
16172    }
16173
16174    /**
16175     * Searches array of arguments for the specified string
16176     * @param args array of argument strings
16177     * @param value value to search for
16178     * @return true if the value is contained in the array
16179     */
16180    private static boolean scanArgs(String[] args, String value) {
16181        if (args != null) {
16182            for (String arg : args) {
16183                if (value.equals(arg)) {
16184                    return true;
16185                }
16186            }
16187        }
16188        return false;
16189    }
16190
16191    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16192            ContentProviderRecord cpr, boolean always) {
16193        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16194
16195        if (!inLaunching || always) {
16196            synchronized (cpr) {
16197                cpr.launchingApp = null;
16198                cpr.notifyAll();
16199            }
16200            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16201            String names[] = cpr.info.authority.split(";");
16202            for (int j = 0; j < names.length; j++) {
16203                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16204            }
16205        }
16206
16207        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16208            ContentProviderConnection conn = cpr.connections.get(i);
16209            if (conn.waiting) {
16210                // If this connection is waiting for the provider, then we don't
16211                // need to mess with its process unless we are always removing
16212                // or for some reason the provider is not currently launching.
16213                if (inLaunching && !always) {
16214                    continue;
16215                }
16216            }
16217            ProcessRecord capp = conn.client;
16218            conn.dead = true;
16219            if (conn.stableCount > 0) {
16220                if (!capp.persistent && capp.thread != null
16221                        && capp.pid != 0
16222                        && capp.pid != MY_PID) {
16223                    capp.kill("depends on provider "
16224                            + cpr.name.flattenToShortString()
16225                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16226                }
16227            } else if (capp.thread != null && conn.provider.provider != null) {
16228                try {
16229                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16230                } catch (RemoteException e) {
16231                }
16232                // In the protocol here, we don't expect the client to correctly
16233                // clean up this connection, we'll just remove it.
16234                cpr.connections.remove(i);
16235                if (conn.client.conProviders.remove(conn)) {
16236                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16237                }
16238            }
16239        }
16240
16241        if (inLaunching && always) {
16242            mLaunchingProviders.remove(cpr);
16243        }
16244        return inLaunching;
16245    }
16246
16247    /**
16248     * Main code for cleaning up a process when it has gone away.  This is
16249     * called both as a result of the process dying, or directly when stopping
16250     * a process when running in single process mode.
16251     *
16252     * @return Returns true if the given process has been restarted, so the
16253     * app that was passed in must remain on the process lists.
16254     */
16255    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16256            boolean restarting, boolean allowRestart, int index) {
16257        if (index >= 0) {
16258            removeLruProcessLocked(app);
16259            ProcessList.remove(app.pid);
16260        }
16261
16262        mProcessesToGc.remove(app);
16263        mPendingPssProcesses.remove(app);
16264
16265        // Dismiss any open dialogs.
16266        if (app.crashDialog != null && !app.forceCrashReport) {
16267            app.crashDialog.dismiss();
16268            app.crashDialog = null;
16269        }
16270        if (app.anrDialog != null) {
16271            app.anrDialog.dismiss();
16272            app.anrDialog = null;
16273        }
16274        if (app.waitDialog != null) {
16275            app.waitDialog.dismiss();
16276            app.waitDialog = null;
16277        }
16278
16279        app.crashing = false;
16280        app.notResponding = false;
16281
16282        app.resetPackageList(mProcessStats);
16283        app.unlinkDeathRecipient();
16284        app.makeInactive(mProcessStats);
16285        app.waitingToKill = null;
16286        app.forcingToForeground = null;
16287        updateProcessForegroundLocked(app, false, false);
16288        app.foregroundActivities = false;
16289        app.hasShownUi = false;
16290        app.treatLikeActivity = false;
16291        app.hasAboveClient = false;
16292        app.hasClientActivities = false;
16293
16294        mServices.killServicesLocked(app, allowRestart);
16295
16296        boolean restart = false;
16297
16298        // Remove published content providers.
16299        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16300            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16301            final boolean always = app.bad || !allowRestart;
16302            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16303            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16304                // We left the provider in the launching list, need to
16305                // restart it.
16306                restart = true;
16307            }
16308
16309            cpr.provider = null;
16310            cpr.proc = null;
16311        }
16312        app.pubProviders.clear();
16313
16314        // Take care of any launching providers waiting for this process.
16315        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16316            restart = true;
16317        }
16318
16319        // Unregister from connected content providers.
16320        if (!app.conProviders.isEmpty()) {
16321            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16322                ContentProviderConnection conn = app.conProviders.get(i);
16323                conn.provider.connections.remove(conn);
16324                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16325                        conn.provider.name);
16326            }
16327            app.conProviders.clear();
16328        }
16329
16330        // At this point there may be remaining entries in mLaunchingProviders
16331        // where we were the only one waiting, so they are no longer of use.
16332        // Look for these and clean up if found.
16333        // XXX Commented out for now.  Trying to figure out a way to reproduce
16334        // the actual situation to identify what is actually going on.
16335        if (false) {
16336            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16337                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16338                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16339                    synchronized (cpr) {
16340                        cpr.launchingApp = null;
16341                        cpr.notifyAll();
16342                    }
16343                }
16344            }
16345        }
16346
16347        skipCurrentReceiverLocked(app);
16348
16349        // Unregister any receivers.
16350        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16351            removeReceiverLocked(app.receivers.valueAt(i));
16352        }
16353        app.receivers.clear();
16354
16355        // If the app is undergoing backup, tell the backup manager about it
16356        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16357            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16358                    + mBackupTarget.appInfo + " died during backup");
16359            try {
16360                IBackupManager bm = IBackupManager.Stub.asInterface(
16361                        ServiceManager.getService(Context.BACKUP_SERVICE));
16362                bm.agentDisconnected(app.info.packageName);
16363            } catch (RemoteException e) {
16364                // can't happen; backup manager is local
16365            }
16366        }
16367
16368        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16369            ProcessChangeItem item = mPendingProcessChanges.get(i);
16370            if (item.pid == app.pid) {
16371                mPendingProcessChanges.remove(i);
16372                mAvailProcessChanges.add(item);
16373            }
16374        }
16375        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16376                null).sendToTarget();
16377
16378        // If the caller is restarting this app, then leave it in its
16379        // current lists and let the caller take care of it.
16380        if (restarting) {
16381            return false;
16382        }
16383
16384        if (!app.persistent || app.isolated) {
16385            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16386                    "Removing non-persistent process during cleanup: " + app);
16387            removeProcessNameLocked(app.processName, app.uid);
16388            if (mHeavyWeightProcess == app) {
16389                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16390                        mHeavyWeightProcess.userId, 0));
16391                mHeavyWeightProcess = null;
16392            }
16393        } else if (!app.removed) {
16394            // This app is persistent, so we need to keep its record around.
16395            // If it is not already on the pending app list, add it there
16396            // and start a new process for it.
16397            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16398                mPersistentStartingProcesses.add(app);
16399                restart = true;
16400            }
16401        }
16402        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16403                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16404        mProcessesOnHold.remove(app);
16405
16406        if (app == mHomeProcess) {
16407            mHomeProcess = null;
16408        }
16409        if (app == mPreviousProcess) {
16410            mPreviousProcess = null;
16411        }
16412
16413        if (restart && !app.isolated) {
16414            // We have components that still need to be running in the
16415            // process, so re-launch it.
16416            if (index < 0) {
16417                ProcessList.remove(app.pid);
16418            }
16419            addProcessNameLocked(app);
16420            startProcessLocked(app, "restart", app.processName);
16421            return true;
16422        } else if (app.pid > 0 && app.pid != MY_PID) {
16423            // Goodbye!
16424            boolean removed;
16425            synchronized (mPidsSelfLocked) {
16426                mPidsSelfLocked.remove(app.pid);
16427                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16428            }
16429            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16430            if (app.isolated) {
16431                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16432            }
16433            app.setPid(0);
16434        }
16435        return false;
16436    }
16437
16438    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16439        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16440            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16441            if (cpr.launchingApp == app) {
16442                return true;
16443            }
16444        }
16445        return false;
16446    }
16447
16448    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16449        // Look through the content providers we are waiting to have launched,
16450        // and if any run in this process then either schedule a restart of
16451        // the process or kill the client waiting for it if this process has
16452        // gone bad.
16453        boolean restart = false;
16454        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16455            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16456            if (cpr.launchingApp == app) {
16457                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16458                    restart = true;
16459                } else {
16460                    removeDyingProviderLocked(app, cpr, true);
16461                }
16462            }
16463        }
16464        return restart;
16465    }
16466
16467    // =========================================================
16468    // SERVICES
16469    // =========================================================
16470
16471    @Override
16472    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16473            int flags) {
16474        enforceNotIsolatedCaller("getServices");
16475        synchronized (this) {
16476            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16477        }
16478    }
16479
16480    @Override
16481    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16482        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16483        synchronized (this) {
16484            return mServices.getRunningServiceControlPanelLocked(name);
16485        }
16486    }
16487
16488    @Override
16489    public ComponentName startService(IApplicationThread caller, Intent service,
16490            String resolvedType, String callingPackage, int userId)
16491            throws TransactionTooLargeException {
16492        enforceNotIsolatedCaller("startService");
16493        // Refuse possible leaked file descriptors
16494        if (service != null && service.hasFileDescriptors() == true) {
16495            throw new IllegalArgumentException("File descriptors passed in Intent");
16496        }
16497
16498        if (callingPackage == null) {
16499            throw new IllegalArgumentException("callingPackage cannot be null");
16500        }
16501
16502        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16503                "startService: " + service + " type=" + resolvedType);
16504        synchronized(this) {
16505            final int callingPid = Binder.getCallingPid();
16506            final int callingUid = Binder.getCallingUid();
16507            final long origId = Binder.clearCallingIdentity();
16508            ComponentName res = mServices.startServiceLocked(caller, service,
16509                    resolvedType, callingPid, callingUid, callingPackage, userId);
16510            Binder.restoreCallingIdentity(origId);
16511            return res;
16512        }
16513    }
16514
16515    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16516            String callingPackage, int userId)
16517            throws TransactionTooLargeException {
16518        synchronized(this) {
16519            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16520                    "startServiceInPackage: " + service + " type=" + resolvedType);
16521            final long origId = Binder.clearCallingIdentity();
16522            ComponentName res = mServices.startServiceLocked(null, service,
16523                    resolvedType, -1, uid, callingPackage, userId);
16524            Binder.restoreCallingIdentity(origId);
16525            return res;
16526        }
16527    }
16528
16529    @Override
16530    public int stopService(IApplicationThread caller, Intent service,
16531            String resolvedType, int userId) {
16532        enforceNotIsolatedCaller("stopService");
16533        // Refuse possible leaked file descriptors
16534        if (service != null && service.hasFileDescriptors() == true) {
16535            throw new IllegalArgumentException("File descriptors passed in Intent");
16536        }
16537
16538        synchronized(this) {
16539            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16540        }
16541    }
16542
16543    @Override
16544    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16545        enforceNotIsolatedCaller("peekService");
16546        // Refuse possible leaked file descriptors
16547        if (service != null && service.hasFileDescriptors() == true) {
16548            throw new IllegalArgumentException("File descriptors passed in Intent");
16549        }
16550
16551        if (callingPackage == null) {
16552            throw new IllegalArgumentException("callingPackage cannot be null");
16553        }
16554
16555        synchronized(this) {
16556            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16557        }
16558    }
16559
16560    @Override
16561    public boolean stopServiceToken(ComponentName className, IBinder token,
16562            int startId) {
16563        synchronized(this) {
16564            return mServices.stopServiceTokenLocked(className, token, startId);
16565        }
16566    }
16567
16568    @Override
16569    public void setServiceForeground(ComponentName className, IBinder token,
16570            int id, Notification notification, int flags) {
16571        synchronized(this) {
16572            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16573        }
16574    }
16575
16576    @Override
16577    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16578            boolean requireFull, String name, String callerPackage) {
16579        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16580                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16581    }
16582
16583    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16584            String className, int flags) {
16585        boolean result = false;
16586        // For apps that don't have pre-defined UIDs, check for permission
16587        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16588            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16589                if (ActivityManager.checkUidPermission(
16590                        INTERACT_ACROSS_USERS,
16591                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16592                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16593                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16594                            + " requests FLAG_SINGLE_USER, but app does not hold "
16595                            + INTERACT_ACROSS_USERS;
16596                    Slog.w(TAG, msg);
16597                    throw new SecurityException(msg);
16598                }
16599                // Permission passed
16600                result = true;
16601            }
16602        } else if ("system".equals(componentProcessName)) {
16603            result = true;
16604        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16605            // Phone app and persistent apps are allowed to export singleuser providers.
16606            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16607                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16608        }
16609        if (DEBUG_MU) Slog.v(TAG_MU,
16610                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16611                + Integer.toHexString(flags) + ") = " + result);
16612        return result;
16613    }
16614
16615    /**
16616     * Checks to see if the caller is in the same app as the singleton
16617     * component, or the component is in a special app. It allows special apps
16618     * to export singleton components but prevents exporting singleton
16619     * components for regular apps.
16620     */
16621    boolean isValidSingletonCall(int callingUid, int componentUid) {
16622        int componentAppId = UserHandle.getAppId(componentUid);
16623        return UserHandle.isSameApp(callingUid, componentUid)
16624                || componentAppId == Process.SYSTEM_UID
16625                || componentAppId == Process.PHONE_UID
16626                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16627                        == PackageManager.PERMISSION_GRANTED;
16628    }
16629
16630    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16631            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16632            int userId) throws TransactionTooLargeException {
16633        enforceNotIsolatedCaller("bindService");
16634
16635        // Refuse possible leaked file descriptors
16636        if (service != null && service.hasFileDescriptors() == true) {
16637            throw new IllegalArgumentException("File descriptors passed in Intent");
16638        }
16639
16640        if (callingPackage == null) {
16641            throw new IllegalArgumentException("callingPackage cannot be null");
16642        }
16643
16644        synchronized(this) {
16645            return mServices.bindServiceLocked(caller, token, service,
16646                    resolvedType, connection, flags, callingPackage, userId);
16647        }
16648    }
16649
16650    public boolean unbindService(IServiceConnection connection) {
16651        synchronized (this) {
16652            return mServices.unbindServiceLocked(connection);
16653        }
16654    }
16655
16656    public void publishService(IBinder token, Intent intent, IBinder service) {
16657        // Refuse possible leaked file descriptors
16658        if (intent != null && intent.hasFileDescriptors() == true) {
16659            throw new IllegalArgumentException("File descriptors passed in Intent");
16660        }
16661
16662        synchronized(this) {
16663            if (!(token instanceof ServiceRecord)) {
16664                throw new IllegalArgumentException("Invalid service token");
16665            }
16666            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16667        }
16668    }
16669
16670    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16671        // Refuse possible leaked file descriptors
16672        if (intent != null && intent.hasFileDescriptors() == true) {
16673            throw new IllegalArgumentException("File descriptors passed in Intent");
16674        }
16675
16676        synchronized(this) {
16677            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16678        }
16679    }
16680
16681    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16682        synchronized(this) {
16683            if (!(token instanceof ServiceRecord)) {
16684                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16685                throw new IllegalArgumentException("Invalid service token");
16686            }
16687            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16688        }
16689    }
16690
16691    // =========================================================
16692    // BACKUP AND RESTORE
16693    // =========================================================
16694
16695    // Cause the target app to be launched if necessary and its backup agent
16696    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16697    // activity manager to announce its creation.
16698    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16699        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16700                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16701        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16702
16703        synchronized(this) {
16704            // !!! TODO: currently no check here that we're already bound
16705            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16706            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16707            synchronized (stats) {
16708                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16709            }
16710
16711            // Backup agent is now in use, its package can't be stopped.
16712            try {
16713                AppGlobals.getPackageManager().setPackageStoppedState(
16714                        app.packageName, false, UserHandle.getUserId(app.uid));
16715            } catch (RemoteException e) {
16716            } catch (IllegalArgumentException e) {
16717                Slog.w(TAG, "Failed trying to unstop package "
16718                        + app.packageName + ": " + e);
16719            }
16720
16721            BackupRecord r = new BackupRecord(ss, app, backupMode);
16722            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16723                    ? new ComponentName(app.packageName, app.backupAgentName)
16724                    : new ComponentName("android", "FullBackupAgent");
16725            // startProcessLocked() returns existing proc's record if it's already running
16726            ProcessRecord proc = startProcessLocked(app.processName, app,
16727                    false, 0, "backup", hostingName, false, false, false);
16728            if (proc == null) {
16729                Slog.e(TAG, "Unable to start backup agent process " + r);
16730                return false;
16731            }
16732
16733            r.app = proc;
16734            mBackupTarget = r;
16735            mBackupAppName = app.packageName;
16736
16737            // Try not to kill the process during backup
16738            updateOomAdjLocked(proc);
16739
16740            // If the process is already attached, schedule the creation of the backup agent now.
16741            // If it is not yet live, this will be done when it attaches to the framework.
16742            if (proc.thread != null) {
16743                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16744                try {
16745                    proc.thread.scheduleCreateBackupAgent(app,
16746                            compatibilityInfoForPackageLocked(app), backupMode);
16747                } catch (RemoteException e) {
16748                    // Will time out on the backup manager side
16749                }
16750            } else {
16751                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16752            }
16753            // Invariants: at this point, the target app process exists and the application
16754            // is either already running or in the process of coming up.  mBackupTarget and
16755            // mBackupAppName describe the app, so that when it binds back to the AM we
16756            // know that it's scheduled for a backup-agent operation.
16757        }
16758
16759        return true;
16760    }
16761
16762    @Override
16763    public void clearPendingBackup() {
16764        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16765        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16766
16767        synchronized (this) {
16768            mBackupTarget = null;
16769            mBackupAppName = null;
16770        }
16771    }
16772
16773    // A backup agent has just come up
16774    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16775        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16776                + " = " + agent);
16777
16778        synchronized(this) {
16779            if (!agentPackageName.equals(mBackupAppName)) {
16780                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16781                return;
16782            }
16783        }
16784
16785        long oldIdent = Binder.clearCallingIdentity();
16786        try {
16787            IBackupManager bm = IBackupManager.Stub.asInterface(
16788                    ServiceManager.getService(Context.BACKUP_SERVICE));
16789            bm.agentConnected(agentPackageName, agent);
16790        } catch (RemoteException e) {
16791            // can't happen; the backup manager service is local
16792        } catch (Exception e) {
16793            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16794            e.printStackTrace();
16795        } finally {
16796            Binder.restoreCallingIdentity(oldIdent);
16797        }
16798    }
16799
16800    // done with this agent
16801    public void unbindBackupAgent(ApplicationInfo appInfo) {
16802        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16803        if (appInfo == null) {
16804            Slog.w(TAG, "unbind backup agent for null app");
16805            return;
16806        }
16807
16808        synchronized(this) {
16809            try {
16810                if (mBackupAppName == null) {
16811                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16812                    return;
16813                }
16814
16815                if (!mBackupAppName.equals(appInfo.packageName)) {
16816                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16817                    return;
16818                }
16819
16820                // Not backing this app up any more; reset its OOM adjustment
16821                final ProcessRecord proc = mBackupTarget.app;
16822                updateOomAdjLocked(proc);
16823
16824                // If the app crashed during backup, 'thread' will be null here
16825                if (proc.thread != null) {
16826                    try {
16827                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16828                                compatibilityInfoForPackageLocked(appInfo));
16829                    } catch (Exception e) {
16830                        Slog.e(TAG, "Exception when unbinding backup agent:");
16831                        e.printStackTrace();
16832                    }
16833                }
16834            } finally {
16835                mBackupTarget = null;
16836                mBackupAppName = null;
16837            }
16838        }
16839    }
16840    // =========================================================
16841    // BROADCASTS
16842    // =========================================================
16843
16844    boolean isPendingBroadcastProcessLocked(int pid) {
16845        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16846                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16847    }
16848
16849    void skipPendingBroadcastLocked(int pid) {
16850            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16851            for (BroadcastQueue queue : mBroadcastQueues) {
16852                queue.skipPendingBroadcastLocked(pid);
16853            }
16854    }
16855
16856    // The app just attached; send any pending broadcasts that it should receive
16857    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16858        boolean didSomething = false;
16859        for (BroadcastQueue queue : mBroadcastQueues) {
16860            didSomething |= queue.sendPendingBroadcastsLocked(app);
16861        }
16862        return didSomething;
16863    }
16864
16865    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16866            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16867        enforceNotIsolatedCaller("registerReceiver");
16868        ArrayList<Intent> stickyIntents = null;
16869        ProcessRecord callerApp = null;
16870        int callingUid;
16871        int callingPid;
16872        synchronized(this) {
16873            if (caller != null) {
16874                callerApp = getRecordForAppLocked(caller);
16875                if (callerApp == null) {
16876                    throw new SecurityException(
16877                            "Unable to find app for caller " + caller
16878                            + " (pid=" + Binder.getCallingPid()
16879                            + ") when registering receiver " + receiver);
16880                }
16881                if (callerApp.info.uid != Process.SYSTEM_UID &&
16882                        !callerApp.pkgList.containsKey(callerPackage) &&
16883                        !"android".equals(callerPackage)) {
16884                    throw new SecurityException("Given caller package " + callerPackage
16885                            + " is not running in process " + callerApp);
16886                }
16887                callingUid = callerApp.info.uid;
16888                callingPid = callerApp.pid;
16889            } else {
16890                callerPackage = null;
16891                callingUid = Binder.getCallingUid();
16892                callingPid = Binder.getCallingPid();
16893            }
16894
16895            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16896                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16897
16898            Iterator<String> actions = filter.actionsIterator();
16899            if (actions == null) {
16900                ArrayList<String> noAction = new ArrayList<String>(1);
16901                noAction.add(null);
16902                actions = noAction.iterator();
16903            }
16904
16905            // Collect stickies of users
16906            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16907            while (actions.hasNext()) {
16908                String action = actions.next();
16909                for (int id : userIds) {
16910                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16911                    if (stickies != null) {
16912                        ArrayList<Intent> intents = stickies.get(action);
16913                        if (intents != null) {
16914                            if (stickyIntents == null) {
16915                                stickyIntents = new ArrayList<Intent>();
16916                            }
16917                            stickyIntents.addAll(intents);
16918                        }
16919                    }
16920                }
16921            }
16922        }
16923
16924        ArrayList<Intent> allSticky = null;
16925        if (stickyIntents != null) {
16926            final ContentResolver resolver = mContext.getContentResolver();
16927            // Look for any matching sticky broadcasts...
16928            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16929                Intent intent = stickyIntents.get(i);
16930                // If intent has scheme "content", it will need to acccess
16931                // provider that needs to lock mProviderMap in ActivityThread
16932                // and also it may need to wait application response, so we
16933                // cannot lock ActivityManagerService here.
16934                if (filter.match(resolver, intent, true, TAG) >= 0) {
16935                    if (allSticky == null) {
16936                        allSticky = new ArrayList<Intent>();
16937                    }
16938                    allSticky.add(intent);
16939                }
16940            }
16941        }
16942
16943        // The first sticky in the list is returned directly back to the client.
16944        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16945        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16946        if (receiver == null) {
16947            return sticky;
16948        }
16949
16950        synchronized (this) {
16951            if (callerApp != null && (callerApp.thread == null
16952                    || callerApp.thread.asBinder() != caller.asBinder())) {
16953                // Original caller already died
16954                return null;
16955            }
16956            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16957            if (rl == null) {
16958                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16959                        userId, receiver);
16960                if (rl.app != null) {
16961                    rl.app.receivers.add(rl);
16962                } else {
16963                    try {
16964                        receiver.asBinder().linkToDeath(rl, 0);
16965                    } catch (RemoteException e) {
16966                        return sticky;
16967                    }
16968                    rl.linkedToDeath = true;
16969                }
16970                mRegisteredReceivers.put(receiver.asBinder(), rl);
16971            } else if (rl.uid != callingUid) {
16972                throw new IllegalArgumentException(
16973                        "Receiver requested to register for uid " + callingUid
16974                        + " was previously registered for uid " + rl.uid);
16975            } else if (rl.pid != callingPid) {
16976                throw new IllegalArgumentException(
16977                        "Receiver requested to register for pid " + callingPid
16978                        + " was previously registered for pid " + rl.pid);
16979            } else if (rl.userId != userId) {
16980                throw new IllegalArgumentException(
16981                        "Receiver requested to register for user " + userId
16982                        + " was previously registered for user " + rl.userId);
16983            }
16984            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16985                    permission, callingUid, userId);
16986            rl.add(bf);
16987            if (!bf.debugCheck()) {
16988                Slog.w(TAG, "==> For Dynamic broadcast");
16989            }
16990            mReceiverResolver.addFilter(bf);
16991
16992            // Enqueue broadcasts for all existing stickies that match
16993            // this filter.
16994            if (allSticky != null) {
16995                ArrayList receivers = new ArrayList();
16996                receivers.add(bf);
16997
16998                final int stickyCount = allSticky.size();
16999                for (int i = 0; i < stickyCount; i++) {
17000                    Intent intent = allSticky.get(i);
17001                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17002                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17003                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17004                            null, 0, null, null, false, true, true, -1);
17005                    queue.enqueueParallelBroadcastLocked(r);
17006                    queue.scheduleBroadcastsLocked();
17007                }
17008            }
17009
17010            return sticky;
17011        }
17012    }
17013
17014    public void unregisterReceiver(IIntentReceiver receiver) {
17015        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17016
17017        final long origId = Binder.clearCallingIdentity();
17018        try {
17019            boolean doTrim = false;
17020
17021            synchronized(this) {
17022                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17023                if (rl != null) {
17024                    final BroadcastRecord r = rl.curBroadcast;
17025                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17026                        final boolean doNext = r.queue.finishReceiverLocked(
17027                                r, r.resultCode, r.resultData, r.resultExtras,
17028                                r.resultAbort, false);
17029                        if (doNext) {
17030                            doTrim = true;
17031                            r.queue.processNextBroadcast(false);
17032                        }
17033                    }
17034
17035                    if (rl.app != null) {
17036                        rl.app.receivers.remove(rl);
17037                    }
17038                    removeReceiverLocked(rl);
17039                    if (rl.linkedToDeath) {
17040                        rl.linkedToDeath = false;
17041                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17042                    }
17043                }
17044            }
17045
17046            // If we actually concluded any broadcasts, we might now be able
17047            // to trim the recipients' apps from our working set
17048            if (doTrim) {
17049                trimApplications();
17050                return;
17051            }
17052
17053        } finally {
17054            Binder.restoreCallingIdentity(origId);
17055        }
17056    }
17057
17058    void removeReceiverLocked(ReceiverList rl) {
17059        mRegisteredReceivers.remove(rl.receiver.asBinder());
17060        for (int i = rl.size() - 1; i >= 0; i--) {
17061            mReceiverResolver.removeFilter(rl.get(i));
17062        }
17063    }
17064
17065    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17066        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17067            ProcessRecord r = mLruProcesses.get(i);
17068            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17069                try {
17070                    r.thread.dispatchPackageBroadcast(cmd, packages);
17071                } catch (RemoteException ex) {
17072                }
17073            }
17074        }
17075    }
17076
17077    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17078            int callingUid, int[] users) {
17079        // TODO: come back and remove this assumption to triage all broadcasts
17080        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17081
17082        List<ResolveInfo> receivers = null;
17083        try {
17084            HashSet<ComponentName> singleUserReceivers = null;
17085            boolean scannedFirstReceivers = false;
17086            for (int user : users) {
17087                // Skip users that have Shell restrictions, with exception of always permitted
17088                // Shell broadcasts
17089                if (callingUid == Process.SHELL_UID
17090                        && mUserController.hasUserRestriction(
17091                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17092                        && !isPermittedShellBroadcast(intent)) {
17093                    continue;
17094                }
17095                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17096                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17097                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17098                    // If this is not the system user, we need to check for
17099                    // any receivers that should be filtered out.
17100                    for (int i=0; i<newReceivers.size(); i++) {
17101                        ResolveInfo ri = newReceivers.get(i);
17102                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17103                            newReceivers.remove(i);
17104                            i--;
17105                        }
17106                    }
17107                }
17108                if (newReceivers != null && newReceivers.size() == 0) {
17109                    newReceivers = null;
17110                }
17111                if (receivers == null) {
17112                    receivers = newReceivers;
17113                } else if (newReceivers != null) {
17114                    // We need to concatenate the additional receivers
17115                    // found with what we have do far.  This would be easy,
17116                    // but we also need to de-dup any receivers that are
17117                    // singleUser.
17118                    if (!scannedFirstReceivers) {
17119                        // Collect any single user receivers we had already retrieved.
17120                        scannedFirstReceivers = true;
17121                        for (int i=0; i<receivers.size(); i++) {
17122                            ResolveInfo ri = receivers.get(i);
17123                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17124                                ComponentName cn = new ComponentName(
17125                                        ri.activityInfo.packageName, ri.activityInfo.name);
17126                                if (singleUserReceivers == null) {
17127                                    singleUserReceivers = new HashSet<ComponentName>();
17128                                }
17129                                singleUserReceivers.add(cn);
17130                            }
17131                        }
17132                    }
17133                    // Add the new results to the existing results, tracking
17134                    // and de-dupping single user receivers.
17135                    for (int i=0; i<newReceivers.size(); i++) {
17136                        ResolveInfo ri = newReceivers.get(i);
17137                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17138                            ComponentName cn = new ComponentName(
17139                                    ri.activityInfo.packageName, ri.activityInfo.name);
17140                            if (singleUserReceivers == null) {
17141                                singleUserReceivers = new HashSet<ComponentName>();
17142                            }
17143                            if (!singleUserReceivers.contains(cn)) {
17144                                singleUserReceivers.add(cn);
17145                                receivers.add(ri);
17146                            }
17147                        } else {
17148                            receivers.add(ri);
17149                        }
17150                    }
17151                }
17152            }
17153        } catch (RemoteException ex) {
17154            // pm is in same process, this will never happen.
17155        }
17156        return receivers;
17157    }
17158
17159    private boolean isPermittedShellBroadcast(Intent intent) {
17160        // remote bugreport should always be allowed to be taken
17161        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17162    }
17163
17164    final int broadcastIntentLocked(ProcessRecord callerApp,
17165            String callerPackage, Intent intent, String resolvedType,
17166            IIntentReceiver resultTo, int resultCode, String resultData,
17167            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17168            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17169        intent = new Intent(intent);
17170
17171        // By default broadcasts do not go to stopped apps.
17172        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17173
17174        // If we have not finished booting, don't allow this to launch new processes.
17175        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17176            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17177        }
17178
17179        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17180                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17181                + " ordered=" + ordered + " userid=" + userId);
17182        if ((resultTo != null) && !ordered) {
17183            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17184        }
17185
17186        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17187                ALLOW_NON_FULL, "broadcast", callerPackage);
17188
17189        // Make sure that the user who is receiving this broadcast is running.
17190        // If not, we will just skip it. Make an exception for shutdown broadcasts
17191        // and upgrade steps.
17192
17193        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17194            if ((callingUid != Process.SYSTEM_UID
17195                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17196                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17197                Slog.w(TAG, "Skipping broadcast of " + intent
17198                        + ": user " + userId + " is stopped");
17199                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17200            }
17201        }
17202
17203        BroadcastOptions brOptions = null;
17204        if (bOptions != null) {
17205            brOptions = new BroadcastOptions(bOptions);
17206            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17207                // See if the caller is allowed to do this.  Note we are checking against
17208                // the actual real caller (not whoever provided the operation as say a
17209                // PendingIntent), because that who is actually supplied the arguments.
17210                if (checkComponentPermission(
17211                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17212                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17213                        != PackageManager.PERMISSION_GRANTED) {
17214                    String msg = "Permission Denial: " + intent.getAction()
17215                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17216                            + ", uid=" + callingUid + ")"
17217                            + " requires "
17218                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17219                    Slog.w(TAG, msg);
17220                    throw new SecurityException(msg);
17221                }
17222            }
17223        }
17224
17225        // Verify that protected broadcasts are only being sent by system code,
17226        // and that system code is only sending protected broadcasts.
17227        final String action = intent.getAction();
17228        final boolean isProtectedBroadcast;
17229        try {
17230            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17231        } catch (RemoteException e) {
17232            Slog.w(TAG, "Remote exception", e);
17233            return ActivityManager.BROADCAST_SUCCESS;
17234        }
17235
17236        final boolean isCallerSystem;
17237        switch (UserHandle.getAppId(callingUid)) {
17238            case Process.ROOT_UID:
17239            case Process.SYSTEM_UID:
17240            case Process.PHONE_UID:
17241            case Process.BLUETOOTH_UID:
17242            case Process.NFC_UID:
17243                isCallerSystem = true;
17244                break;
17245            default:
17246                isCallerSystem = (callerApp != null) && callerApp.persistent;
17247                break;
17248        }
17249
17250        if (isCallerSystem) {
17251            if (isProtectedBroadcast
17252                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17253                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17254                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17255                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17256                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17257                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17258                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17259                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17260                // Broadcast is either protected, or it's a public action that
17261                // we've relaxed, so it's fine for system internals to send.
17262            } else {
17263                // The vast majority of broadcasts sent from system internals
17264                // should be protected to avoid security holes, so yell loudly
17265                // to ensure we examine these cases.
17266                Log.wtf(TAG, "Sending non-protected broadcast " + action
17267                        + " from system", new Throwable());
17268            }
17269
17270        } else {
17271            if (isProtectedBroadcast) {
17272                String msg = "Permission Denial: not allowed to send broadcast "
17273                        + action + " from pid="
17274                        + callingPid + ", uid=" + callingUid;
17275                Slog.w(TAG, msg);
17276                throw new SecurityException(msg);
17277
17278            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17279                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17280                // Special case for compatibility: we don't want apps to send this,
17281                // but historically it has not been protected and apps may be using it
17282                // to poke their own app widget.  So, instead of making it protected,
17283                // just limit it to the caller.
17284                if (callerPackage == null) {
17285                    String msg = "Permission Denial: not allowed to send broadcast "
17286                            + action + " from unknown caller.";
17287                    Slog.w(TAG, msg);
17288                    throw new SecurityException(msg);
17289                } else if (intent.getComponent() != null) {
17290                    // They are good enough to send to an explicit component...  verify
17291                    // it is being sent to the calling app.
17292                    if (!intent.getComponent().getPackageName().equals(
17293                            callerPackage)) {
17294                        String msg = "Permission Denial: not allowed to send broadcast "
17295                                + action + " to "
17296                                + intent.getComponent().getPackageName() + " from "
17297                                + callerPackage;
17298                        Slog.w(TAG, msg);
17299                        throw new SecurityException(msg);
17300                    }
17301                } else {
17302                    // Limit broadcast to their own package.
17303                    intent.setPackage(callerPackage);
17304                }
17305            }
17306        }
17307
17308        if (action != null) {
17309            switch (action) {
17310                case Intent.ACTION_UID_REMOVED:
17311                case Intent.ACTION_PACKAGE_REMOVED:
17312                case Intent.ACTION_PACKAGE_CHANGED:
17313                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17314                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17315                case Intent.ACTION_PACKAGES_SUSPENDED:
17316                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17317                    // Handle special intents: if this broadcast is from the package
17318                    // manager about a package being removed, we need to remove all of
17319                    // its activities from the history stack.
17320                    if (checkComponentPermission(
17321                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17322                            callingPid, callingUid, -1, true)
17323                            != PackageManager.PERMISSION_GRANTED) {
17324                        String msg = "Permission Denial: " + intent.getAction()
17325                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17326                                + ", uid=" + callingUid + ")"
17327                                + " requires "
17328                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17329                        Slog.w(TAG, msg);
17330                        throw new SecurityException(msg);
17331                    }
17332                    switch (action) {
17333                        case Intent.ACTION_UID_REMOVED:
17334                            final Bundle intentExtras = intent.getExtras();
17335                            final int uid = intentExtras != null
17336                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17337                            if (uid >= 0) {
17338                                mBatteryStatsService.removeUid(uid);
17339                                mAppOpsService.uidRemoved(uid);
17340                            }
17341                            break;
17342                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17343                            // If resources are unavailable just force stop all those packages
17344                            // and flush the attribute cache as well.
17345                            String list[] =
17346                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17347                            if (list != null && list.length > 0) {
17348                                for (int i = 0; i < list.length; i++) {
17349                                    forceStopPackageLocked(list[i], -1, false, true, true,
17350                                            false, false, userId, "storage unmount");
17351                                }
17352                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17353                                sendPackageBroadcastLocked(
17354                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17355                                        userId);
17356                            }
17357                            break;
17358                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17359                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17360                            break;
17361                        case Intent.ACTION_PACKAGE_REMOVED:
17362                        case Intent.ACTION_PACKAGE_CHANGED:
17363                            Uri data = intent.getData();
17364                            String ssp;
17365                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17366                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17367                                final boolean replacing =
17368                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17369                                final boolean killProcess =
17370                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17371                                final boolean fullUninstall = removed && !replacing;
17372                                if (killProcess) {
17373                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17374                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17375                                            false, true, true, false, fullUninstall, userId,
17376                                            removed ? "pkg removed" : "pkg changed");
17377                                }
17378                                if (removed) {
17379                                    final int cmd = killProcess
17380                                            ? IApplicationThread.PACKAGE_REMOVED
17381                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17382                                    sendPackageBroadcastLocked(cmd,
17383                                            new String[] {ssp}, userId);
17384                                    if (fullUninstall) {
17385                                        mAppOpsService.packageRemoved(
17386                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17387
17388                                        // Remove all permissions granted from/to this package
17389                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17390
17391                                        removeTasksByPackageNameLocked(ssp, userId);
17392                                        mBatteryStatsService.notePackageUninstalled(ssp);
17393                                    }
17394                                } else {
17395                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17396                                            intent.getStringArrayExtra(
17397                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17398                                }
17399                            }
17400                            break;
17401                        case Intent.ACTION_PACKAGES_SUSPENDED:
17402                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17403                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17404                                    intent.getAction());
17405                            final String[] packageNames = intent.getStringArrayExtra(
17406                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17407                            final int userHandle = intent.getIntExtra(
17408                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17409
17410                            synchronized(ActivityManagerService.this) {
17411                                mRecentTasks.onPackagesSuspendedChanged(
17412                                        packageNames, suspended, userHandle);
17413                            }
17414                            break;
17415                    }
17416                    break;
17417                case Intent.ACTION_PACKAGE_REPLACED:
17418                {
17419                    final Uri data = intent.getData();
17420                    final String ssp;
17421                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17422                        final ApplicationInfo aInfo =
17423                                getPackageManagerInternalLocked().getApplicationInfo(
17424                                        ssp,
17425                                        userId);
17426                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17427                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17428                                new String[] {ssp}, userId);
17429                    }
17430                    break;
17431                }
17432                case Intent.ACTION_PACKAGE_ADDED:
17433                {
17434                    // Special case for adding a package: by default turn on compatibility mode.
17435                    Uri data = intent.getData();
17436                    String ssp;
17437                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17438                        final boolean replacing =
17439                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17440                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17441
17442                        try {
17443                            ApplicationInfo ai = AppGlobals.getPackageManager().
17444                                    getApplicationInfo(ssp, 0, 0);
17445                            mBatteryStatsService.notePackageInstalled(ssp,
17446                                    ai != null ? ai.versionCode : 0);
17447                        } catch (RemoteException e) {
17448                        }
17449                    }
17450                    break;
17451                }
17452                case Intent.ACTION_TIMEZONE_CHANGED:
17453                    // If this is the time zone changed action, queue up a message that will reset
17454                    // the timezone of all currently running processes. This message will get
17455                    // queued up before the broadcast happens.
17456                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17457                    break;
17458                case Intent.ACTION_TIME_CHANGED:
17459                    // If the user set the time, let all running processes know.
17460                    final int is24Hour =
17461                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17462                                    : 0;
17463                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17464                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17465                    synchronized (stats) {
17466                        stats.noteCurrentTimeChangedLocked();
17467                    }
17468                    break;
17469                case Intent.ACTION_CLEAR_DNS_CACHE:
17470                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17471                    break;
17472                case Proxy.PROXY_CHANGE_ACTION:
17473                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17474                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17475                    break;
17476                case android.hardware.Camera.ACTION_NEW_PICTURE:
17477                case android.hardware.Camera.ACTION_NEW_VIDEO:
17478                    // These broadcasts are no longer allowed by the system, since they can
17479                    // cause significant thrashing at a crictical point (using the camera).
17480                    // Apps should use JobScehduler to monitor for media provider changes.
17481                    Slog.w(TAG, action + " no longer allowed; dropping from "
17482                            + UserHandle.formatUid(callingUid));
17483                    // Lie; we don't want to crash the app.
17484                    return ActivityManager.BROADCAST_SUCCESS;
17485            }
17486        }
17487
17488        // Add to the sticky list if requested.
17489        if (sticky) {
17490            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17491                    callingPid, callingUid)
17492                    != PackageManager.PERMISSION_GRANTED) {
17493                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17494                        + callingPid + ", uid=" + callingUid
17495                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17496                Slog.w(TAG, msg);
17497                throw new SecurityException(msg);
17498            }
17499            if (requiredPermissions != null && requiredPermissions.length > 0) {
17500                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17501                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17502                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17503            }
17504            if (intent.getComponent() != null) {
17505                throw new SecurityException(
17506                        "Sticky broadcasts can't target a specific component");
17507            }
17508            // We use userId directly here, since the "all" target is maintained
17509            // as a separate set of sticky broadcasts.
17510            if (userId != UserHandle.USER_ALL) {
17511                // But first, if this is not a broadcast to all users, then
17512                // make sure it doesn't conflict with an existing broadcast to
17513                // all users.
17514                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17515                        UserHandle.USER_ALL);
17516                if (stickies != null) {
17517                    ArrayList<Intent> list = stickies.get(intent.getAction());
17518                    if (list != null) {
17519                        int N = list.size();
17520                        int i;
17521                        for (i=0; i<N; i++) {
17522                            if (intent.filterEquals(list.get(i))) {
17523                                throw new IllegalArgumentException(
17524                                        "Sticky broadcast " + intent + " for user "
17525                                        + userId + " conflicts with existing global broadcast");
17526                            }
17527                        }
17528                    }
17529                }
17530            }
17531            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17532            if (stickies == null) {
17533                stickies = new ArrayMap<>();
17534                mStickyBroadcasts.put(userId, stickies);
17535            }
17536            ArrayList<Intent> list = stickies.get(intent.getAction());
17537            if (list == null) {
17538                list = new ArrayList<>();
17539                stickies.put(intent.getAction(), list);
17540            }
17541            final int stickiesCount = list.size();
17542            int i;
17543            for (i = 0; i < stickiesCount; i++) {
17544                if (intent.filterEquals(list.get(i))) {
17545                    // This sticky already exists, replace it.
17546                    list.set(i, new Intent(intent));
17547                    break;
17548                }
17549            }
17550            if (i >= stickiesCount) {
17551                list.add(new Intent(intent));
17552            }
17553        }
17554
17555        int[] users;
17556        if (userId == UserHandle.USER_ALL) {
17557            // Caller wants broadcast to go to all started users.
17558            users = mUserController.getStartedUserArrayLocked();
17559        } else {
17560            // Caller wants broadcast to go to one specific user.
17561            users = new int[] {userId};
17562        }
17563
17564        // Figure out who all will receive this broadcast.
17565        List receivers = null;
17566        List<BroadcastFilter> registeredReceivers = null;
17567        // Need to resolve the intent to interested receivers...
17568        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17569                 == 0) {
17570            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17571        }
17572        if (intent.getComponent() == null) {
17573            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17574                // Query one target user at a time, excluding shell-restricted users
17575                for (int i = 0; i < users.length; i++) {
17576                    if (mUserController.hasUserRestriction(
17577                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17578                        continue;
17579                    }
17580                    List<BroadcastFilter> registeredReceiversForUser =
17581                            mReceiverResolver.queryIntent(intent,
17582                                    resolvedType, false, users[i]);
17583                    if (registeredReceivers == null) {
17584                        registeredReceivers = registeredReceiversForUser;
17585                    } else if (registeredReceiversForUser != null) {
17586                        registeredReceivers.addAll(registeredReceiversForUser);
17587                    }
17588                }
17589            } else {
17590                registeredReceivers = mReceiverResolver.queryIntent(intent,
17591                        resolvedType, false, userId);
17592            }
17593        }
17594
17595        final boolean replacePending =
17596                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17597
17598        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17599                + " replacePending=" + replacePending);
17600
17601        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17602        if (!ordered && NR > 0) {
17603            // If we are not serializing this broadcast, then send the
17604            // registered receivers separately so they don't wait for the
17605            // components to be launched.
17606            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17607            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17608                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17609                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17610                    resultExtras, ordered, sticky, false, userId);
17611            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17612            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17613            if (!replaced) {
17614                queue.enqueueParallelBroadcastLocked(r);
17615                queue.scheduleBroadcastsLocked();
17616            }
17617            registeredReceivers = null;
17618            NR = 0;
17619        }
17620
17621        // Merge into one list.
17622        int ir = 0;
17623        if (receivers != null) {
17624            // A special case for PACKAGE_ADDED: do not allow the package
17625            // being added to see this broadcast.  This prevents them from
17626            // using this as a back door to get run as soon as they are
17627            // installed.  Maybe in the future we want to have a special install
17628            // broadcast or such for apps, but we'd like to deliberately make
17629            // this decision.
17630            String skipPackages[] = null;
17631            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17632                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17633                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17634                Uri data = intent.getData();
17635                if (data != null) {
17636                    String pkgName = data.getSchemeSpecificPart();
17637                    if (pkgName != null) {
17638                        skipPackages = new String[] { pkgName };
17639                    }
17640                }
17641            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17642                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17643            }
17644            if (skipPackages != null && (skipPackages.length > 0)) {
17645                for (String skipPackage : skipPackages) {
17646                    if (skipPackage != null) {
17647                        int NT = receivers.size();
17648                        for (int it=0; it<NT; it++) {
17649                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17650                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17651                                receivers.remove(it);
17652                                it--;
17653                                NT--;
17654                            }
17655                        }
17656                    }
17657                }
17658            }
17659
17660            int NT = receivers != null ? receivers.size() : 0;
17661            int it = 0;
17662            ResolveInfo curt = null;
17663            BroadcastFilter curr = null;
17664            while (it < NT && ir < NR) {
17665                if (curt == null) {
17666                    curt = (ResolveInfo)receivers.get(it);
17667                }
17668                if (curr == null) {
17669                    curr = registeredReceivers.get(ir);
17670                }
17671                if (curr.getPriority() >= curt.priority) {
17672                    // Insert this broadcast record into the final list.
17673                    receivers.add(it, curr);
17674                    ir++;
17675                    curr = null;
17676                    it++;
17677                    NT++;
17678                } else {
17679                    // Skip to the next ResolveInfo in the final list.
17680                    it++;
17681                    curt = null;
17682                }
17683            }
17684        }
17685        while (ir < NR) {
17686            if (receivers == null) {
17687                receivers = new ArrayList();
17688            }
17689            receivers.add(registeredReceivers.get(ir));
17690            ir++;
17691        }
17692
17693        if ((receivers != null && receivers.size() > 0)
17694                || resultTo != null) {
17695            BroadcastQueue queue = broadcastQueueForIntent(intent);
17696            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17697                    callerPackage, callingPid, callingUid, resolvedType,
17698                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17699                    resultData, resultExtras, ordered, sticky, false, userId);
17700
17701            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17702                    + ": prev had " + queue.mOrderedBroadcasts.size());
17703            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17704                    "Enqueueing broadcast " + r.intent.getAction());
17705
17706            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17707            if (!replaced) {
17708                queue.enqueueOrderedBroadcastLocked(r);
17709                queue.scheduleBroadcastsLocked();
17710            }
17711        }
17712
17713        return ActivityManager.BROADCAST_SUCCESS;
17714    }
17715
17716    final Intent verifyBroadcastLocked(Intent intent) {
17717        // Refuse possible leaked file descriptors
17718        if (intent != null && intent.hasFileDescriptors() == true) {
17719            throw new IllegalArgumentException("File descriptors passed in Intent");
17720        }
17721
17722        int flags = intent.getFlags();
17723
17724        if (!mProcessesReady) {
17725            // if the caller really truly claims to know what they're doing, go
17726            // ahead and allow the broadcast without launching any receivers
17727            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17728                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17729            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17730                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17731                        + " before boot completion");
17732                throw new IllegalStateException("Cannot broadcast before boot completed");
17733            }
17734        }
17735
17736        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17737            throw new IllegalArgumentException(
17738                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17739        }
17740
17741        return intent;
17742    }
17743
17744    public final int broadcastIntent(IApplicationThread caller,
17745            Intent intent, String resolvedType, IIntentReceiver resultTo,
17746            int resultCode, String resultData, Bundle resultExtras,
17747            String[] requiredPermissions, int appOp, Bundle bOptions,
17748            boolean serialized, boolean sticky, int userId) {
17749        enforceNotIsolatedCaller("broadcastIntent");
17750        synchronized(this) {
17751            intent = verifyBroadcastLocked(intent);
17752
17753            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17754            final int callingPid = Binder.getCallingPid();
17755            final int callingUid = Binder.getCallingUid();
17756            final long origId = Binder.clearCallingIdentity();
17757            int res = broadcastIntentLocked(callerApp,
17758                    callerApp != null ? callerApp.info.packageName : null,
17759                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17760                    requiredPermissions, appOp, bOptions, serialized, sticky,
17761                    callingPid, callingUid, userId);
17762            Binder.restoreCallingIdentity(origId);
17763            return res;
17764        }
17765    }
17766
17767
17768    int broadcastIntentInPackage(String packageName, int uid,
17769            Intent intent, String resolvedType, IIntentReceiver resultTo,
17770            int resultCode, String resultData, Bundle resultExtras,
17771            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17772            int userId) {
17773        synchronized(this) {
17774            intent = verifyBroadcastLocked(intent);
17775
17776            final long origId = Binder.clearCallingIdentity();
17777            String[] requiredPermissions = requiredPermission == null ? null
17778                    : new String[] {requiredPermission};
17779            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17780                    resultTo, resultCode, resultData, resultExtras,
17781                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17782                    sticky, -1, uid, userId);
17783            Binder.restoreCallingIdentity(origId);
17784            return res;
17785        }
17786    }
17787
17788    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17789        // Refuse possible leaked file descriptors
17790        if (intent != null && intent.hasFileDescriptors() == true) {
17791            throw new IllegalArgumentException("File descriptors passed in Intent");
17792        }
17793
17794        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17795                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17796
17797        synchronized(this) {
17798            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17799                    != PackageManager.PERMISSION_GRANTED) {
17800                String msg = "Permission Denial: unbroadcastIntent() from pid="
17801                        + Binder.getCallingPid()
17802                        + ", uid=" + Binder.getCallingUid()
17803                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17804                Slog.w(TAG, msg);
17805                throw new SecurityException(msg);
17806            }
17807            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17808            if (stickies != null) {
17809                ArrayList<Intent> list = stickies.get(intent.getAction());
17810                if (list != null) {
17811                    int N = list.size();
17812                    int i;
17813                    for (i=0; i<N; i++) {
17814                        if (intent.filterEquals(list.get(i))) {
17815                            list.remove(i);
17816                            break;
17817                        }
17818                    }
17819                    if (list.size() <= 0) {
17820                        stickies.remove(intent.getAction());
17821                    }
17822                }
17823                if (stickies.size() <= 0) {
17824                    mStickyBroadcasts.remove(userId);
17825                }
17826            }
17827        }
17828    }
17829
17830    void backgroundServicesFinishedLocked(int userId) {
17831        for (BroadcastQueue queue : mBroadcastQueues) {
17832            queue.backgroundServicesFinishedLocked(userId);
17833        }
17834    }
17835
17836    public void finishReceiver(IBinder who, int resultCode, String resultData,
17837            Bundle resultExtras, boolean resultAbort, int flags) {
17838        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17839
17840        // Refuse possible leaked file descriptors
17841        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17842            throw new IllegalArgumentException("File descriptors passed in Bundle");
17843        }
17844
17845        final long origId = Binder.clearCallingIdentity();
17846        try {
17847            boolean doNext = false;
17848            BroadcastRecord r;
17849
17850            synchronized(this) {
17851                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17852                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17853                r = queue.getMatchingOrderedReceiver(who);
17854                if (r != null) {
17855                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17856                        resultData, resultExtras, resultAbort, true);
17857                }
17858            }
17859
17860            if (doNext) {
17861                r.queue.processNextBroadcast(false);
17862            }
17863            trimApplications();
17864        } finally {
17865            Binder.restoreCallingIdentity(origId);
17866        }
17867    }
17868
17869    // =========================================================
17870    // INSTRUMENTATION
17871    // =========================================================
17872
17873    public boolean startInstrumentation(ComponentName className,
17874            String profileFile, int flags, Bundle arguments,
17875            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17876            int userId, String abiOverride) {
17877        enforceNotIsolatedCaller("startInstrumentation");
17878        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17879                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17880        // Refuse possible leaked file descriptors
17881        if (arguments != null && arguments.hasFileDescriptors()) {
17882            throw new IllegalArgumentException("File descriptors passed in Bundle");
17883        }
17884
17885        synchronized(this) {
17886            InstrumentationInfo ii = null;
17887            ApplicationInfo ai = null;
17888            try {
17889                ii = mContext.getPackageManager().getInstrumentationInfo(
17890                    className, STOCK_PM_FLAGS);
17891                ai = AppGlobals.getPackageManager().getApplicationInfo(
17892                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17893            } catch (PackageManager.NameNotFoundException e) {
17894            } catch (RemoteException e) {
17895            }
17896            if (ii == null) {
17897                reportStartInstrumentationFailureLocked(watcher, className,
17898                        "Unable to find instrumentation info for: " + className);
17899                return false;
17900            }
17901            if (ai == null) {
17902                reportStartInstrumentationFailureLocked(watcher, className,
17903                        "Unable to find instrumentation target package: " + ii.targetPackage);
17904                return false;
17905            }
17906            if (!ai.hasCode()) {
17907                reportStartInstrumentationFailureLocked(watcher, className,
17908                        "Instrumentation target has no code: " + ii.targetPackage);
17909                return false;
17910            }
17911
17912            int match = mContext.getPackageManager().checkSignatures(
17913                    ii.targetPackage, ii.packageName);
17914            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17915                String msg = "Permission Denial: starting instrumentation "
17916                        + className + " from pid="
17917                        + Binder.getCallingPid()
17918                        + ", uid=" + Binder.getCallingPid()
17919                        + " not allowed because package " + ii.packageName
17920                        + " does not have a signature matching the target "
17921                        + ii.targetPackage;
17922                reportStartInstrumentationFailureLocked(watcher, className, msg);
17923                throw new SecurityException(msg);
17924            }
17925
17926            final long origId = Binder.clearCallingIdentity();
17927            // Instrumentation can kill and relaunch even persistent processes
17928            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17929                    "start instr");
17930            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17931            app.instrumentationClass = className;
17932            app.instrumentationInfo = ai;
17933            app.instrumentationProfileFile = profileFile;
17934            app.instrumentationArguments = arguments;
17935            app.instrumentationWatcher = watcher;
17936            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17937            app.instrumentationResultClass = className;
17938            Binder.restoreCallingIdentity(origId);
17939        }
17940
17941        return true;
17942    }
17943
17944    /**
17945     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17946     * error to the logs, but if somebody is watching, send the report there too.  This enables
17947     * the "am" command to report errors with more information.
17948     *
17949     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17950     * @param cn The component name of the instrumentation.
17951     * @param report The error report.
17952     */
17953    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17954            ComponentName cn, String report) {
17955        Slog.w(TAG, report);
17956        if (watcher != null) {
17957            Bundle results = new Bundle();
17958            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17959            results.putString("Error", report);
17960            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17961        }
17962    }
17963
17964    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17965        if (app.instrumentationWatcher != null) {
17966            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17967                    app.instrumentationClass, resultCode, results);
17968        }
17969
17970        // Can't call out of the system process with a lock held, so post a message.
17971        if (app.instrumentationUiAutomationConnection != null) {
17972            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17973                    app.instrumentationUiAutomationConnection).sendToTarget();
17974        }
17975
17976        app.instrumentationWatcher = null;
17977        app.instrumentationUiAutomationConnection = null;
17978        app.instrumentationClass = null;
17979        app.instrumentationInfo = null;
17980        app.instrumentationProfileFile = null;
17981        app.instrumentationArguments = null;
17982
17983        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17984                "finished inst");
17985    }
17986
17987    public void finishInstrumentation(IApplicationThread target,
17988            int resultCode, Bundle results) {
17989        int userId = UserHandle.getCallingUserId();
17990        // Refuse possible leaked file descriptors
17991        if (results != null && results.hasFileDescriptors()) {
17992            throw new IllegalArgumentException("File descriptors passed in Intent");
17993        }
17994
17995        synchronized(this) {
17996            ProcessRecord app = getRecordForAppLocked(target);
17997            if (app == null) {
17998                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17999                return;
18000            }
18001            final long origId = Binder.clearCallingIdentity();
18002            finishInstrumentationLocked(app, resultCode, results);
18003            Binder.restoreCallingIdentity(origId);
18004        }
18005    }
18006
18007    // =========================================================
18008    // CONFIGURATION
18009    // =========================================================
18010
18011    public ConfigurationInfo getDeviceConfigurationInfo() {
18012        ConfigurationInfo config = new ConfigurationInfo();
18013        synchronized (this) {
18014            config.reqTouchScreen = mConfiguration.touchscreen;
18015            config.reqKeyboardType = mConfiguration.keyboard;
18016            config.reqNavigation = mConfiguration.navigation;
18017            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18018                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18019                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18020            }
18021            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18022                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18023                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18024            }
18025            config.reqGlEsVersion = GL_ES_VERSION;
18026        }
18027        return config;
18028    }
18029
18030    ActivityStack getFocusedStack() {
18031        return mStackSupervisor.getFocusedStack();
18032    }
18033
18034    @Override
18035    public int getFocusedStackId() throws RemoteException {
18036        ActivityStack focusedStack = getFocusedStack();
18037        if (focusedStack != null) {
18038            return focusedStack.getStackId();
18039        }
18040        return -1;
18041    }
18042
18043    public Configuration getConfiguration() {
18044        Configuration ci;
18045        synchronized(this) {
18046            ci = new Configuration(mConfiguration);
18047            ci.userSetLocale = false;
18048        }
18049        return ci;
18050    }
18051
18052    @Override
18053    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18054        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18055        synchronized (this) {
18056            mSuppressResizeConfigChanges = suppress;
18057        }
18058    }
18059
18060    @Override
18061    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18062        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18063        if (fromStackId == HOME_STACK_ID) {
18064            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18065        }
18066        synchronized (this) {
18067            final long origId = Binder.clearCallingIdentity();
18068            try {
18069                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18070            } finally {
18071                Binder.restoreCallingIdentity(origId);
18072            }
18073        }
18074    }
18075
18076    @Override
18077    public void updatePersistentConfiguration(Configuration values) {
18078        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18079                "updateConfiguration()");
18080        enforceWriteSettingsPermission("updateConfiguration()");
18081        if (values == null) {
18082            throw new NullPointerException("Configuration must not be null");
18083        }
18084
18085        int userId = UserHandle.getCallingUserId();
18086
18087        synchronized(this) {
18088            final long origId = Binder.clearCallingIdentity();
18089            updateConfigurationLocked(values, null, false, true, userId);
18090            Binder.restoreCallingIdentity(origId);
18091        }
18092    }
18093
18094    private void updateFontScaleIfNeeded() {
18095        final int currentUserId;
18096        synchronized(this) {
18097            currentUserId = mUserController.getCurrentUserIdLocked();
18098        }
18099        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18100                FONT_SCALE, 1.0f, currentUserId);
18101        if (mConfiguration.fontScale != scaleFactor) {
18102            final Configuration configuration = mWindowManager.computeNewConfiguration();
18103            configuration.fontScale = scaleFactor;
18104            updatePersistentConfiguration(configuration);
18105        }
18106    }
18107
18108    private void enforceWriteSettingsPermission(String func) {
18109        int uid = Binder.getCallingUid();
18110        if (uid == Process.ROOT_UID) {
18111            return;
18112        }
18113
18114        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18115                Settings.getPackageNameForUid(mContext, uid), false)) {
18116            return;
18117        }
18118
18119        String msg = "Permission Denial: " + func + " from pid="
18120                + Binder.getCallingPid()
18121                + ", uid=" + uid
18122                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18123        Slog.w(TAG, msg);
18124        throw new SecurityException(msg);
18125    }
18126
18127    public void updateConfiguration(Configuration values) {
18128        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18129                "updateConfiguration()");
18130
18131        synchronized(this) {
18132            if (values == null && mWindowManager != null) {
18133                // sentinel: fetch the current configuration from the window manager
18134                values = mWindowManager.computeNewConfiguration();
18135            }
18136
18137            if (mWindowManager != null) {
18138                mProcessList.applyDisplaySize(mWindowManager);
18139            }
18140
18141            final long origId = Binder.clearCallingIdentity();
18142            if (values != null) {
18143                Settings.System.clearConfiguration(values);
18144            }
18145            updateConfigurationLocked(values, null, false);
18146            Binder.restoreCallingIdentity(origId);
18147        }
18148    }
18149
18150    void updateUserConfigurationLocked() {
18151        Configuration configuration = new Configuration(mConfiguration);
18152        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18153                mUserController.getCurrentUserIdLocked());
18154        updateConfigurationLocked(configuration, null, false);
18155    }
18156
18157    boolean updateConfigurationLocked(Configuration values,
18158            ActivityRecord starting, boolean initLocale) {
18159        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18160        return updateConfigurationLocked(values, starting, initLocale, false,
18161                UserHandle.USER_NULL);
18162    }
18163
18164    // To cache the list of supported system locales
18165    private String[] mSupportedSystemLocales = null;
18166
18167    /**
18168     * Do either or both things: (1) change the current configuration, and (2)
18169     * make sure the given activity is running with the (now) current
18170     * configuration.  Returns true if the activity has been left running, or
18171     * false if <var>starting</var> is being destroyed to match the new
18172     * configuration.
18173     *
18174     * @param userId is only used when persistent parameter is set to true to persist configuration
18175     *               for that particular user
18176     */
18177    private boolean updateConfigurationLocked(Configuration values,
18178            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18179        int changes = 0;
18180
18181        if (mWindowManager != null) {
18182            mWindowManager.deferSurfaceLayout();
18183        }
18184        if (values != null) {
18185            Configuration newConfig = new Configuration(mConfiguration);
18186            changes = newConfig.updateFrom(values);
18187            if (changes != 0) {
18188                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18189                        "Updating configuration to: " + values);
18190
18191                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18192
18193                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18194                    final Locale locale;
18195                    if (values.getLocales().size() == 1) {
18196                        // This is an optimization to avoid the JNI call when the result of
18197                        // getFirstMatch() does not depend on the supported locales.
18198                        locale = values.getLocales().get(0);
18199                    } else {
18200                        if (mSupportedSystemLocales == null) {
18201                            mSupportedSystemLocales =
18202                                    Resources.getSystem().getAssets().getLocales();
18203                        }
18204                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18205                    }
18206                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18207                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18208                            locale));
18209                }
18210
18211                mConfigurationSeq++;
18212                if (mConfigurationSeq <= 0) {
18213                    mConfigurationSeq = 1;
18214                }
18215                newConfig.seq = mConfigurationSeq;
18216                mConfiguration = newConfig;
18217                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18218                mUsageStatsService.reportConfigurationChange(newConfig,
18219                        mUserController.getCurrentUserIdLocked());
18220                //mUsageStatsService.noteStartConfig(newConfig);
18221
18222                final Configuration configCopy = new Configuration(mConfiguration);
18223
18224                // TODO: If our config changes, should we auto dismiss any currently
18225                // showing dialogs?
18226                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18227
18228                AttributeCache ac = AttributeCache.instance();
18229                if (ac != null) {
18230                    ac.updateConfiguration(configCopy);
18231                }
18232
18233                // Make sure all resources in our process are updated
18234                // right now, so that anyone who is going to retrieve
18235                // resource values after we return will be sure to get
18236                // the new ones.  This is especially important during
18237                // boot, where the first config change needs to guarantee
18238                // all resources have that config before following boot
18239                // code is executed.
18240                mSystemThread.applyConfigurationToResources(configCopy);
18241
18242                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18243                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18244                    msg.obj = new Configuration(configCopy);
18245                    msg.arg1 = userId;
18246                    mHandler.sendMessage(msg);
18247                }
18248
18249                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18250                if (isDensityChange) {
18251                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18252                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18253                }
18254
18255                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18256                    ProcessRecord app = mLruProcesses.get(i);
18257                    try {
18258                        if (app.thread != null) {
18259                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18260                                    + app.processName + " new config " + mConfiguration);
18261                            app.thread.scheduleConfigurationChanged(configCopy);
18262                        }
18263                    } catch (Exception e) {
18264                    }
18265                }
18266                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18267                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18268                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18269                        | Intent.FLAG_RECEIVER_FOREGROUND);
18270                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18271                        null, AppOpsManager.OP_NONE, null, false, false,
18272                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18273                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18274                    // Tell the shortcut manager that the system locale changed.  It needs to know
18275                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18276                    // we "push" from here, rather than having the service listen to the broadcast.
18277                    final ShortcutServiceInternal shortcutService =
18278                            LocalServices.getService(ShortcutServiceInternal.class);
18279                    if (shortcutService != null) {
18280                        shortcutService.onSystemLocaleChangedNoLock();
18281                    }
18282
18283                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18284                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18285                    if (!mProcessesReady) {
18286                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18287                    }
18288                    broadcastIntentLocked(null, null, intent,
18289                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18290                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18291                }
18292            }
18293            // Update the configuration with WM first and check if any of the stacks need to be
18294            // resized due to the configuration change. If so, resize the stacks now and do any
18295            // relaunches if necessary. This way we don't need to relaunch again below in
18296            // ensureActivityConfigurationLocked().
18297            if (mWindowManager != null) {
18298                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18299                if (resizedStacks != null) {
18300                    for (int stackId : resizedStacks) {
18301                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18302                        mStackSupervisor.resizeStackLocked(
18303                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18304                    }
18305                }
18306            }
18307        }
18308
18309        boolean kept = true;
18310        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18311        // mainStack is null during startup.
18312        if (mainStack != null) {
18313            if (changes != 0 && starting == null) {
18314                // If the configuration changed, and the caller is not already
18315                // in the process of starting an activity, then find the top
18316                // activity to check if its configuration needs to change.
18317                starting = mainStack.topRunningActivityLocked();
18318            }
18319
18320            if (starting != null) {
18321                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18322                // And we need to make sure at this point that all other activities
18323                // are made visible with the correct configuration.
18324                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18325                        !PRESERVE_WINDOWS);
18326            }
18327        }
18328        if (mWindowManager != null) {
18329            mWindowManager.continueSurfaceLayout();
18330        }
18331        return kept;
18332    }
18333
18334    /**
18335     * Decide based on the configuration whether we should shouw the ANR,
18336     * crash, etc dialogs.  The idea is that if there is no affordence to
18337     * press the on-screen buttons, or the user experience would be more
18338     * greatly impacted than the crash itself, we shouldn't show the dialog.
18339     *
18340     * A thought: SystemUI might also want to get told about this, the Power
18341     * dialog / global actions also might want different behaviors.
18342     */
18343    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18344        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18345                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18346                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18347        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
18348        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
18349                && (modeType != Configuration.UI_MODE_TYPE_WATCH || "eng".equals(Build.TYPE)));
18350        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
18351    }
18352
18353    @Override
18354    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18355        synchronized (this) {
18356            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18357            if (srec != null) {
18358                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18359            }
18360        }
18361        return false;
18362    }
18363
18364    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18365            Intent resultData) {
18366
18367        synchronized (this) {
18368            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18369            if (r != null) {
18370                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18371            }
18372            return false;
18373        }
18374    }
18375
18376    public int getLaunchedFromUid(IBinder activityToken) {
18377        ActivityRecord srec;
18378        synchronized (this) {
18379            srec = ActivityRecord.forTokenLocked(activityToken);
18380        }
18381        if (srec == null) {
18382            return -1;
18383        }
18384        return srec.launchedFromUid;
18385    }
18386
18387    public String getLaunchedFromPackage(IBinder activityToken) {
18388        ActivityRecord srec;
18389        synchronized (this) {
18390            srec = ActivityRecord.forTokenLocked(activityToken);
18391        }
18392        if (srec == null) {
18393            return null;
18394        }
18395        return srec.launchedFromPackage;
18396    }
18397
18398    // =========================================================
18399    // LIFETIME MANAGEMENT
18400    // =========================================================
18401
18402    // Returns which broadcast queue the app is the current [or imminent] receiver
18403    // on, or 'null' if the app is not an active broadcast recipient.
18404    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18405        BroadcastRecord r = app.curReceiver;
18406        if (r != null) {
18407            return r.queue;
18408        }
18409
18410        // It's not the current receiver, but it might be starting up to become one
18411        synchronized (this) {
18412            for (BroadcastQueue queue : mBroadcastQueues) {
18413                r = queue.mPendingBroadcast;
18414                if (r != null && r.curApp == app) {
18415                    // found it; report which queue it's in
18416                    return queue;
18417                }
18418            }
18419        }
18420
18421        return null;
18422    }
18423
18424    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18425            int targetUid, ComponentName targetComponent, String targetProcess) {
18426        if (!mTrackingAssociations) {
18427            return null;
18428        }
18429        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18430                = mAssociations.get(targetUid);
18431        if (components == null) {
18432            components = new ArrayMap<>();
18433            mAssociations.put(targetUid, components);
18434        }
18435        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18436        if (sourceUids == null) {
18437            sourceUids = new SparseArray<>();
18438            components.put(targetComponent, sourceUids);
18439        }
18440        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18441        if (sourceProcesses == null) {
18442            sourceProcesses = new ArrayMap<>();
18443            sourceUids.put(sourceUid, sourceProcesses);
18444        }
18445        Association ass = sourceProcesses.get(sourceProcess);
18446        if (ass == null) {
18447            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18448                    targetProcess);
18449            sourceProcesses.put(sourceProcess, ass);
18450        }
18451        ass.mCount++;
18452        ass.mNesting++;
18453        if (ass.mNesting == 1) {
18454            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18455            ass.mLastState = sourceState;
18456        }
18457        return ass;
18458    }
18459
18460    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18461            ComponentName targetComponent) {
18462        if (!mTrackingAssociations) {
18463            return;
18464        }
18465        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18466                = mAssociations.get(targetUid);
18467        if (components == null) {
18468            return;
18469        }
18470        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18471        if (sourceUids == null) {
18472            return;
18473        }
18474        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18475        if (sourceProcesses == null) {
18476            return;
18477        }
18478        Association ass = sourceProcesses.get(sourceProcess);
18479        if (ass == null || ass.mNesting <= 0) {
18480            return;
18481        }
18482        ass.mNesting--;
18483        if (ass.mNesting == 0) {
18484            long uptime = SystemClock.uptimeMillis();
18485            ass.mTime += uptime - ass.mStartTime;
18486            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18487                    += uptime - ass.mLastStateUptime;
18488            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18489        }
18490    }
18491
18492    private void noteUidProcessState(final int uid, final int state) {
18493        mBatteryStatsService.noteUidProcessState(uid, state);
18494        if (mTrackingAssociations) {
18495            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18496                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18497                        = mAssociations.valueAt(i1);
18498                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18499                    SparseArray<ArrayMap<String, Association>> sourceUids
18500                            = targetComponents.valueAt(i2);
18501                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18502                    if (sourceProcesses != null) {
18503                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18504                            Association ass = sourceProcesses.valueAt(i4);
18505                            if (ass.mNesting >= 1) {
18506                                // currently associated
18507                                long uptime = SystemClock.uptimeMillis();
18508                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18509                                        += uptime - ass.mLastStateUptime;
18510                                ass.mLastState = state;
18511                                ass.mLastStateUptime = uptime;
18512                            }
18513                        }
18514                    }
18515                }
18516            }
18517        }
18518    }
18519
18520    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18521            boolean doingAll, long now) {
18522        if (mAdjSeq == app.adjSeq) {
18523            // This adjustment has already been computed.
18524            return app.curRawAdj;
18525        }
18526
18527        if (app.thread == null) {
18528            app.adjSeq = mAdjSeq;
18529            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18530            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18531            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18532        }
18533
18534        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18535        app.adjSource = null;
18536        app.adjTarget = null;
18537        app.empty = false;
18538        app.cached = false;
18539
18540        final int activitiesSize = app.activities.size();
18541
18542        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18543            // The max adjustment doesn't allow this app to be anything
18544            // below foreground, so it is not worth doing work for it.
18545            app.adjType = "fixed";
18546            app.adjSeq = mAdjSeq;
18547            app.curRawAdj = app.maxAdj;
18548            app.foregroundActivities = false;
18549            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18550            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18551            // System processes can do UI, and when they do we want to have
18552            // them trim their memory after the user leaves the UI.  To
18553            // facilitate this, here we need to determine whether or not it
18554            // is currently showing UI.
18555            app.systemNoUi = true;
18556            if (app == TOP_APP) {
18557                app.systemNoUi = false;
18558            } else if (activitiesSize > 0) {
18559                for (int j = 0; j < activitiesSize; j++) {
18560                    final ActivityRecord r = app.activities.get(j);
18561                    if (r.visible) {
18562                        app.systemNoUi = false;
18563                    }
18564                }
18565            }
18566            if (!app.systemNoUi) {
18567                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18568            }
18569            return (app.curAdj=app.maxAdj);
18570        }
18571
18572        app.systemNoUi = false;
18573
18574        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18575
18576        // Determine the importance of the process, starting with most
18577        // important to least, and assign an appropriate OOM adjustment.
18578        int adj;
18579        int schedGroup;
18580        int procState;
18581        boolean foregroundActivities = false;
18582        BroadcastQueue queue;
18583        if (app == TOP_APP) {
18584            // The last app on the list is the foreground app.
18585            adj = ProcessList.FOREGROUND_APP_ADJ;
18586            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18587            app.adjType = "top-activity";
18588            foregroundActivities = true;
18589            procState = PROCESS_STATE_CUR_TOP;
18590        } else if (app.instrumentationClass != null) {
18591            // Don't want to kill running instrumentation.
18592            adj = ProcessList.FOREGROUND_APP_ADJ;
18593            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18594            app.adjType = "instrumentation";
18595            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18596        } else if ((queue = isReceivingBroadcast(app)) != null) {
18597            // An app that is currently receiving a broadcast also
18598            // counts as being in the foreground for OOM killer purposes.
18599            // It's placed in a sched group based on the nature of the
18600            // broadcast as reflected by which queue it's active in.
18601            adj = ProcessList.FOREGROUND_APP_ADJ;
18602            schedGroup = (queue == mFgBroadcastQueue)
18603                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18604            app.adjType = "broadcast";
18605            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18606        } else if (app.executingServices.size() > 0) {
18607            // An app that is currently executing a service callback also
18608            // counts as being in the foreground.
18609            adj = ProcessList.FOREGROUND_APP_ADJ;
18610            schedGroup = app.execServicesFg ?
18611                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18612            app.adjType = "exec-service";
18613            procState = ActivityManager.PROCESS_STATE_SERVICE;
18614            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18615        } else {
18616            // As far as we know the process is empty.  We may change our mind later.
18617            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18618            // At this point we don't actually know the adjustment.  Use the cached adj
18619            // value that the caller wants us to.
18620            adj = cachedAdj;
18621            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18622            app.cached = true;
18623            app.empty = true;
18624            app.adjType = "cch-empty";
18625        }
18626
18627        // Examine all activities if not already foreground.
18628        if (!foregroundActivities && activitiesSize > 0) {
18629            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18630            for (int j = 0; j < activitiesSize; j++) {
18631                final ActivityRecord r = app.activities.get(j);
18632                if (r.app != app) {
18633                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18634                            + " instead of expected " + app);
18635                    if (r.app == null || (r.app.uid == app.uid)) {
18636                        // Only fix things up when they look sane
18637                        r.app = app;
18638                    } else {
18639                        continue;
18640                    }
18641                }
18642                if (r.visible) {
18643                    // App has a visible activity; only upgrade adjustment.
18644                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18645                        adj = ProcessList.VISIBLE_APP_ADJ;
18646                        app.adjType = "visible";
18647                    }
18648                    if (procState > PROCESS_STATE_CUR_TOP) {
18649                        procState = PROCESS_STATE_CUR_TOP;
18650                    }
18651                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18652                    app.cached = false;
18653                    app.empty = false;
18654                    foregroundActivities = true;
18655                    if (r.task != null && minLayer > 0) {
18656                        final int layer = r.task.mLayerRank;
18657                        if (layer >= 0 && minLayer > layer) {
18658                            minLayer = layer;
18659                        }
18660                    }
18661                    break;
18662                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18663                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18664                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18665                        app.adjType = "pausing";
18666                    }
18667                    if (procState > PROCESS_STATE_CUR_TOP) {
18668                        procState = PROCESS_STATE_CUR_TOP;
18669                    }
18670                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18671                    app.cached = false;
18672                    app.empty = false;
18673                    foregroundActivities = true;
18674                } else if (r.state == ActivityState.STOPPING) {
18675                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18676                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18677                        app.adjType = "stopping";
18678                    }
18679                    // For the process state, we will at this point consider the
18680                    // process to be cached.  It will be cached either as an activity
18681                    // or empty depending on whether the activity is finishing.  We do
18682                    // this so that we can treat the process as cached for purposes of
18683                    // memory trimming (determing current memory level, trim command to
18684                    // send to process) since there can be an arbitrary number of stopping
18685                    // processes and they should soon all go into the cached state.
18686                    if (!r.finishing) {
18687                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18688                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18689                        }
18690                    }
18691                    app.cached = false;
18692                    app.empty = false;
18693                    foregroundActivities = true;
18694                } else {
18695                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18696                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18697                        app.adjType = "cch-act";
18698                    }
18699                }
18700            }
18701            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18702                adj += minLayer;
18703            }
18704        }
18705
18706        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18707                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18708            if (app.foregroundServices) {
18709                // The user is aware of this app, so make it visible.
18710                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18711                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18712                app.cached = false;
18713                app.adjType = "fg-service";
18714                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18715            } else if (app.forcingToForeground != null) {
18716                // The user is aware of this app, so make it visible.
18717                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18718                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18719                app.cached = false;
18720                app.adjType = "force-fg";
18721                app.adjSource = app.forcingToForeground;
18722                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18723            }
18724        }
18725
18726        if (app == mHeavyWeightProcess) {
18727            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18728                // We don't want to kill the current heavy-weight process.
18729                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18730                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18731                app.cached = false;
18732                app.adjType = "heavy";
18733            }
18734            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18735                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18736            }
18737        }
18738
18739        if (app == mHomeProcess) {
18740            if (adj > ProcessList.HOME_APP_ADJ) {
18741                // This process is hosting what we currently consider to be the
18742                // home app, so we don't want to let it go into the background.
18743                adj = ProcessList.HOME_APP_ADJ;
18744                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18745                app.cached = false;
18746                app.adjType = "home";
18747            }
18748            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18749                procState = ActivityManager.PROCESS_STATE_HOME;
18750            }
18751        }
18752
18753        if (app == mPreviousProcess && app.activities.size() > 0) {
18754            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18755                // This was the previous process that showed UI to the user.
18756                // We want to try to keep it around more aggressively, to give
18757                // a good experience around switching between two apps.
18758                adj = ProcessList.PREVIOUS_APP_ADJ;
18759                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18760                app.cached = false;
18761                app.adjType = "previous";
18762            }
18763            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18764                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18765            }
18766        }
18767
18768        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18769                + " reason=" + app.adjType);
18770
18771        // By default, we use the computed adjustment.  It may be changed if
18772        // there are applications dependent on our services or providers, but
18773        // this gives us a baseline and makes sure we don't get into an
18774        // infinite recursion.
18775        app.adjSeq = mAdjSeq;
18776        app.curRawAdj = adj;
18777        app.hasStartedServices = false;
18778
18779        if (mBackupTarget != null && app == mBackupTarget.app) {
18780            // If possible we want to avoid killing apps while they're being backed up
18781            if (adj > ProcessList.BACKUP_APP_ADJ) {
18782                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18783                adj = ProcessList.BACKUP_APP_ADJ;
18784                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18785                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18786                }
18787                app.adjType = "backup";
18788                app.cached = false;
18789            }
18790            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18791                procState = ActivityManager.PROCESS_STATE_BACKUP;
18792            }
18793        }
18794
18795        boolean mayBeTop = false;
18796
18797        for (int is = app.services.size()-1;
18798                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18799                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18800                        || procState > ActivityManager.PROCESS_STATE_TOP);
18801                is--) {
18802            ServiceRecord s = app.services.valueAt(is);
18803            if (s.startRequested) {
18804                app.hasStartedServices = true;
18805                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18806                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18807                }
18808                if (app.hasShownUi && app != mHomeProcess) {
18809                    // If this process has shown some UI, let it immediately
18810                    // go to the LRU list because it may be pretty heavy with
18811                    // UI stuff.  We'll tag it with a label just to help
18812                    // debug and understand what is going on.
18813                    if (adj > ProcessList.SERVICE_ADJ) {
18814                        app.adjType = "cch-started-ui-services";
18815                    }
18816                } else {
18817                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18818                        // This service has seen some activity within
18819                        // recent memory, so we will keep its process ahead
18820                        // of the background processes.
18821                        if (adj > ProcessList.SERVICE_ADJ) {
18822                            adj = ProcessList.SERVICE_ADJ;
18823                            app.adjType = "started-services";
18824                            app.cached = false;
18825                        }
18826                    }
18827                    // If we have let the service slide into the background
18828                    // state, still have some text describing what it is doing
18829                    // even though the service no longer has an impact.
18830                    if (adj > ProcessList.SERVICE_ADJ) {
18831                        app.adjType = "cch-started-services";
18832                    }
18833                }
18834            }
18835            for (int conni = s.connections.size()-1;
18836                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18837                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18838                            || procState > ActivityManager.PROCESS_STATE_TOP);
18839                    conni--) {
18840                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18841                for (int i = 0;
18842                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18843                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18844                                || procState > ActivityManager.PROCESS_STATE_TOP);
18845                        i++) {
18846                    // XXX should compute this based on the max of
18847                    // all connected clients.
18848                    ConnectionRecord cr = clist.get(i);
18849                    if (cr.binding.client == app) {
18850                        // Binding to ourself is not interesting.
18851                        continue;
18852                    }
18853                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18854                        ProcessRecord client = cr.binding.client;
18855                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18856                                TOP_APP, doingAll, now);
18857                        int clientProcState = client.curProcState;
18858                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18859                            // If the other app is cached for any reason, for purposes here
18860                            // we are going to consider it empty.  The specific cached state
18861                            // doesn't propagate except under certain conditions.
18862                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18863                        }
18864                        String adjType = null;
18865                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18866                            // Not doing bind OOM management, so treat
18867                            // this guy more like a started service.
18868                            if (app.hasShownUi && app != mHomeProcess) {
18869                                // If this process has shown some UI, let it immediately
18870                                // go to the LRU list because it may be pretty heavy with
18871                                // UI stuff.  We'll tag it with a label just to help
18872                                // debug and understand what is going on.
18873                                if (adj > clientAdj) {
18874                                    adjType = "cch-bound-ui-services";
18875                                }
18876                                app.cached = false;
18877                                clientAdj = adj;
18878                                clientProcState = procState;
18879                            } else {
18880                                if (now >= (s.lastActivity
18881                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18882                                    // This service has not seen activity within
18883                                    // recent memory, so allow it to drop to the
18884                                    // LRU list if there is no other reason to keep
18885                                    // it around.  We'll also tag it with a label just
18886                                    // to help debug and undertand what is going on.
18887                                    if (adj > clientAdj) {
18888                                        adjType = "cch-bound-services";
18889                                    }
18890                                    clientAdj = adj;
18891                                }
18892                            }
18893                        }
18894                        if (adj > clientAdj) {
18895                            // If this process has recently shown UI, and
18896                            // the process that is binding to it is less
18897                            // important than being visible, then we don't
18898                            // care about the binding as much as we care
18899                            // about letting this process get into the LRU
18900                            // list to be killed and restarted if needed for
18901                            // memory.
18902                            if (app.hasShownUi && app != mHomeProcess
18903                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18904                                adjType = "cch-bound-ui-services";
18905                            } else {
18906                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18907                                        |Context.BIND_IMPORTANT)) != 0) {
18908                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18909                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18910                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18911                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18912                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18913                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18914                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18915                                    adj = clientAdj;
18916                                } else {
18917                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18918                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18919                                    }
18920                                }
18921                                if (!client.cached) {
18922                                    app.cached = false;
18923                                }
18924                                adjType = "service";
18925                            }
18926                        }
18927                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18928                            // This will treat important bound services identically to
18929                            // the top app, which may behave differently than generic
18930                            // foreground work.
18931                            if (client.curSchedGroup > schedGroup) {
18932                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18933                                    schedGroup = client.curSchedGroup;
18934                                } else {
18935                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18936                                }
18937                            }
18938                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18939                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18940                                    // Special handling of clients who are in the top state.
18941                                    // We *may* want to consider this process to be in the
18942                                    // top state as well, but only if there is not another
18943                                    // reason for it to be running.  Being on the top is a
18944                                    // special state, meaning you are specifically running
18945                                    // for the current top app.  If the process is already
18946                                    // running in the background for some other reason, it
18947                                    // is more important to continue considering it to be
18948                                    // in the background state.
18949                                    mayBeTop = true;
18950                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18951                                } else {
18952                                    // Special handling for above-top states (persistent
18953                                    // processes).  These should not bring the current process
18954                                    // into the top state, since they are not on top.  Instead
18955                                    // give them the best state after that.
18956                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18957                                        clientProcState =
18958                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18959                                    } else if (mWakefulness
18960                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18961                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18962                                                    != 0) {
18963                                        clientProcState =
18964                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18965                                    } else {
18966                                        clientProcState =
18967                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18968                                    }
18969                                }
18970                            }
18971                        } else {
18972                            if (clientProcState <
18973                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18974                                clientProcState =
18975                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18976                            }
18977                        }
18978                        if (procState > clientProcState) {
18979                            procState = clientProcState;
18980                        }
18981                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18982                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18983                            app.pendingUiClean = true;
18984                        }
18985                        if (adjType != null) {
18986                            app.adjType = adjType;
18987                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18988                                    .REASON_SERVICE_IN_USE;
18989                            app.adjSource = cr.binding.client;
18990                            app.adjSourceProcState = clientProcState;
18991                            app.adjTarget = s.name;
18992                        }
18993                    }
18994                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18995                        app.treatLikeActivity = true;
18996                    }
18997                    final ActivityRecord a = cr.activity;
18998                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18999                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19000                            (a.visible || a.state == ActivityState.RESUMED ||
19001                             a.state == ActivityState.PAUSING)) {
19002                            adj = ProcessList.FOREGROUND_APP_ADJ;
19003                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19004                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19005                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19006                                } else {
19007                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19008                                }
19009                            }
19010                            app.cached = false;
19011                            app.adjType = "service";
19012                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19013                                    .REASON_SERVICE_IN_USE;
19014                            app.adjSource = a;
19015                            app.adjSourceProcState = procState;
19016                            app.adjTarget = s.name;
19017                        }
19018                    }
19019                }
19020            }
19021        }
19022
19023        for (int provi = app.pubProviders.size()-1;
19024                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19025                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19026                        || procState > ActivityManager.PROCESS_STATE_TOP);
19027                provi--) {
19028            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19029            for (int i = cpr.connections.size()-1;
19030                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19031                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19032                            || procState > ActivityManager.PROCESS_STATE_TOP);
19033                    i--) {
19034                ContentProviderConnection conn = cpr.connections.get(i);
19035                ProcessRecord client = conn.client;
19036                if (client == app) {
19037                    // Being our own client is not interesting.
19038                    continue;
19039                }
19040                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19041                int clientProcState = client.curProcState;
19042                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19043                    // If the other app is cached for any reason, for purposes here
19044                    // we are going to consider it empty.
19045                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19046                }
19047                if (adj > clientAdj) {
19048                    if (app.hasShownUi && app != mHomeProcess
19049                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19050                        app.adjType = "cch-ui-provider";
19051                    } else {
19052                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19053                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19054                        app.adjType = "provider";
19055                    }
19056                    app.cached &= client.cached;
19057                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19058                            .REASON_PROVIDER_IN_USE;
19059                    app.adjSource = client;
19060                    app.adjSourceProcState = clientProcState;
19061                    app.adjTarget = cpr.name;
19062                }
19063                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19064                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19065                        // Special handling of clients who are in the top state.
19066                        // We *may* want to consider this process to be in the
19067                        // top state as well, but only if there is not another
19068                        // reason for it to be running.  Being on the top is a
19069                        // special state, meaning you are specifically running
19070                        // for the current top app.  If the process is already
19071                        // running in the background for some other reason, it
19072                        // is more important to continue considering it to be
19073                        // in the background state.
19074                        mayBeTop = true;
19075                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19076                    } else {
19077                        // Special handling for above-top states (persistent
19078                        // processes).  These should not bring the current process
19079                        // into the top state, since they are not on top.  Instead
19080                        // give them the best state after that.
19081                        clientProcState =
19082                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19083                    }
19084                }
19085                if (procState > clientProcState) {
19086                    procState = clientProcState;
19087                }
19088                if (client.curSchedGroup > schedGroup) {
19089                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19090                }
19091            }
19092            // If the provider has external (non-framework) process
19093            // dependencies, ensure that its adjustment is at least
19094            // FOREGROUND_APP_ADJ.
19095            if (cpr.hasExternalProcessHandles()) {
19096                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19097                    adj = ProcessList.FOREGROUND_APP_ADJ;
19098                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19099                    app.cached = false;
19100                    app.adjType = "provider";
19101                    app.adjTarget = cpr.name;
19102                }
19103                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19104                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19105                }
19106            }
19107        }
19108
19109        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19110            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19111                adj = ProcessList.PREVIOUS_APP_ADJ;
19112                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19113                app.cached = false;
19114                app.adjType = "provider";
19115            }
19116            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19117                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19118            }
19119        }
19120
19121        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19122            // A client of one of our services or providers is in the top state.  We
19123            // *may* want to be in the top state, but not if we are already running in
19124            // the background for some other reason.  For the decision here, we are going
19125            // to pick out a few specific states that we want to remain in when a client
19126            // is top (states that tend to be longer-term) and otherwise allow it to go
19127            // to the top state.
19128            switch (procState) {
19129                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19130                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19131                case ActivityManager.PROCESS_STATE_SERVICE:
19132                    // These all are longer-term states, so pull them up to the top
19133                    // of the background states, but not all the way to the top state.
19134                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19135                    break;
19136                default:
19137                    // Otherwise, top is a better choice, so take it.
19138                    procState = ActivityManager.PROCESS_STATE_TOP;
19139                    break;
19140            }
19141        }
19142
19143        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19144            if (app.hasClientActivities) {
19145                // This is a cached process, but with client activities.  Mark it so.
19146                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19147                app.adjType = "cch-client-act";
19148            } else if (app.treatLikeActivity) {
19149                // This is a cached process, but somebody wants us to treat it like it has
19150                // an activity, okay!
19151                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19152                app.adjType = "cch-as-act";
19153            }
19154        }
19155
19156        if (adj == ProcessList.SERVICE_ADJ) {
19157            if (doingAll) {
19158                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19159                mNewNumServiceProcs++;
19160                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19161                if (!app.serviceb) {
19162                    // This service isn't far enough down on the LRU list to
19163                    // normally be a B service, but if we are low on RAM and it
19164                    // is large we want to force it down since we would prefer to
19165                    // keep launcher over it.
19166                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19167                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19168                        app.serviceHighRam = true;
19169                        app.serviceb = true;
19170                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19171                    } else {
19172                        mNewNumAServiceProcs++;
19173                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19174                    }
19175                } else {
19176                    app.serviceHighRam = false;
19177                }
19178            }
19179            if (app.serviceb) {
19180                adj = ProcessList.SERVICE_B_ADJ;
19181            }
19182        }
19183
19184        app.curRawAdj = adj;
19185
19186        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19187        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19188        if (adj > app.maxAdj) {
19189            adj = app.maxAdj;
19190            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19191                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19192            }
19193        }
19194
19195        // Do final modification to adj.  Everything we do between here and applying
19196        // the final setAdj must be done in this function, because we will also use
19197        // it when computing the final cached adj later.  Note that we don't need to
19198        // worry about this for max adj above, since max adj will always be used to
19199        // keep it out of the cached vaues.
19200        app.curAdj = app.modifyRawOomAdj(adj);
19201        app.curSchedGroup = schedGroup;
19202        app.curProcState = procState;
19203        app.foregroundActivities = foregroundActivities;
19204
19205        return app.curRawAdj;
19206    }
19207
19208    /**
19209     * Record new PSS sample for a process.
19210     */
19211    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19212            long now) {
19213        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19214                swapPss * 1024);
19215        proc.lastPssTime = now;
19216        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19217        if (DEBUG_PSS) Slog.d(TAG_PSS,
19218                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19219                + " state=" + ProcessList.makeProcStateString(procState));
19220        if (proc.initialIdlePss == 0) {
19221            proc.initialIdlePss = pss;
19222        }
19223        proc.lastPss = pss;
19224        proc.lastSwapPss = swapPss;
19225        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19226            proc.lastCachedPss = pss;
19227            proc.lastCachedSwapPss = swapPss;
19228        }
19229
19230        final SparseArray<Pair<Long, String>> watchUids
19231                = mMemWatchProcesses.getMap().get(proc.processName);
19232        Long check = null;
19233        if (watchUids != null) {
19234            Pair<Long, String> val = watchUids.get(proc.uid);
19235            if (val == null) {
19236                val = watchUids.get(0);
19237            }
19238            if (val != null) {
19239                check = val.first;
19240            }
19241        }
19242        if (check != null) {
19243            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19244                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19245                if (!isDebuggable) {
19246                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19247                        isDebuggable = true;
19248                    }
19249                }
19250                if (isDebuggable) {
19251                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19252                    final ProcessRecord myProc = proc;
19253                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19254                    mMemWatchDumpProcName = proc.processName;
19255                    mMemWatchDumpFile = heapdumpFile.toString();
19256                    mMemWatchDumpPid = proc.pid;
19257                    mMemWatchDumpUid = proc.uid;
19258                    BackgroundThread.getHandler().post(new Runnable() {
19259                        @Override
19260                        public void run() {
19261                            revokeUriPermission(ActivityThread.currentActivityThread()
19262                                            .getApplicationThread(),
19263                                    DumpHeapActivity.JAVA_URI,
19264                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19265                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19266                                    UserHandle.myUserId());
19267                            ParcelFileDescriptor fd = null;
19268                            try {
19269                                heapdumpFile.delete();
19270                                fd = ParcelFileDescriptor.open(heapdumpFile,
19271                                        ParcelFileDescriptor.MODE_CREATE |
19272                                                ParcelFileDescriptor.MODE_TRUNCATE |
19273                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19274                                                ParcelFileDescriptor.MODE_APPEND);
19275                                IApplicationThread thread = myProc.thread;
19276                                if (thread != null) {
19277                                    try {
19278                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19279                                                "Requesting dump heap from "
19280                                                + myProc + " to " + heapdumpFile);
19281                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19282                                    } catch (RemoteException e) {
19283                                    }
19284                                }
19285                            } catch (FileNotFoundException e) {
19286                                e.printStackTrace();
19287                            } finally {
19288                                if (fd != null) {
19289                                    try {
19290                                        fd.close();
19291                                    } catch (IOException e) {
19292                                    }
19293                                }
19294                            }
19295                        }
19296                    });
19297                } else {
19298                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19299                            + ", but debugging not enabled");
19300                }
19301            }
19302        }
19303    }
19304
19305    /**
19306     * Schedule PSS collection of a process.
19307     */
19308    void requestPssLocked(ProcessRecord proc, int procState) {
19309        if (mPendingPssProcesses.contains(proc)) {
19310            return;
19311        }
19312        if (mPendingPssProcesses.size() == 0) {
19313            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19314        }
19315        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19316        proc.pssProcState = procState;
19317        mPendingPssProcesses.add(proc);
19318    }
19319
19320    /**
19321     * Schedule PSS collection of all processes.
19322     */
19323    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19324        if (!always) {
19325            if (now < (mLastFullPssTime +
19326                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19327                return;
19328            }
19329        }
19330        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19331        mLastFullPssTime = now;
19332        mFullPssPending = true;
19333        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19334        mPendingPssProcesses.clear();
19335        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19336            ProcessRecord app = mLruProcesses.get(i);
19337            if (app.thread == null
19338                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19339                continue;
19340            }
19341            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19342                app.pssProcState = app.setProcState;
19343                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19344                        mTestPssMode, isSleeping(), now);
19345                mPendingPssProcesses.add(app);
19346            }
19347        }
19348        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19349    }
19350
19351    public void setTestPssMode(boolean enabled) {
19352        synchronized (this) {
19353            mTestPssMode = enabled;
19354            if (enabled) {
19355                // Whenever we enable the mode, we want to take a snapshot all of current
19356                // process mem use.
19357                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19358            }
19359        }
19360    }
19361
19362    /**
19363     * Ask a given process to GC right now.
19364     */
19365    final void performAppGcLocked(ProcessRecord app) {
19366        try {
19367            app.lastRequestedGc = SystemClock.uptimeMillis();
19368            if (app.thread != null) {
19369                if (app.reportLowMemory) {
19370                    app.reportLowMemory = false;
19371                    app.thread.scheduleLowMemory();
19372                } else {
19373                    app.thread.processInBackground();
19374                }
19375            }
19376        } catch (Exception e) {
19377            // whatever.
19378        }
19379    }
19380
19381    /**
19382     * Returns true if things are idle enough to perform GCs.
19383     */
19384    private final boolean canGcNowLocked() {
19385        boolean processingBroadcasts = false;
19386        for (BroadcastQueue q : mBroadcastQueues) {
19387            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19388                processingBroadcasts = true;
19389            }
19390        }
19391        return !processingBroadcasts
19392                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19393    }
19394
19395    /**
19396     * Perform GCs on all processes that are waiting for it, but only
19397     * if things are idle.
19398     */
19399    final void performAppGcsLocked() {
19400        final int N = mProcessesToGc.size();
19401        if (N <= 0) {
19402            return;
19403        }
19404        if (canGcNowLocked()) {
19405            while (mProcessesToGc.size() > 0) {
19406                ProcessRecord proc = mProcessesToGc.remove(0);
19407                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19408                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19409                            <= SystemClock.uptimeMillis()) {
19410                        // To avoid spamming the system, we will GC processes one
19411                        // at a time, waiting a few seconds between each.
19412                        performAppGcLocked(proc);
19413                        scheduleAppGcsLocked();
19414                        return;
19415                    } else {
19416                        // It hasn't been long enough since we last GCed this
19417                        // process...  put it in the list to wait for its time.
19418                        addProcessToGcListLocked(proc);
19419                        break;
19420                    }
19421                }
19422            }
19423
19424            scheduleAppGcsLocked();
19425        }
19426    }
19427
19428    /**
19429     * If all looks good, perform GCs on all processes waiting for them.
19430     */
19431    final void performAppGcsIfAppropriateLocked() {
19432        if (canGcNowLocked()) {
19433            performAppGcsLocked();
19434            return;
19435        }
19436        // Still not idle, wait some more.
19437        scheduleAppGcsLocked();
19438    }
19439
19440    /**
19441     * Schedule the execution of all pending app GCs.
19442     */
19443    final void scheduleAppGcsLocked() {
19444        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19445
19446        if (mProcessesToGc.size() > 0) {
19447            // Schedule a GC for the time to the next process.
19448            ProcessRecord proc = mProcessesToGc.get(0);
19449            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19450
19451            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19452            long now = SystemClock.uptimeMillis();
19453            if (when < (now+GC_TIMEOUT)) {
19454                when = now + GC_TIMEOUT;
19455            }
19456            mHandler.sendMessageAtTime(msg, when);
19457        }
19458    }
19459
19460    /**
19461     * Add a process to the array of processes waiting to be GCed.  Keeps the
19462     * list in sorted order by the last GC time.  The process can't already be
19463     * on the list.
19464     */
19465    final void addProcessToGcListLocked(ProcessRecord proc) {
19466        boolean added = false;
19467        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19468            if (mProcessesToGc.get(i).lastRequestedGc <
19469                    proc.lastRequestedGc) {
19470                added = true;
19471                mProcessesToGc.add(i+1, proc);
19472                break;
19473            }
19474        }
19475        if (!added) {
19476            mProcessesToGc.add(0, proc);
19477        }
19478    }
19479
19480    /**
19481     * Set up to ask a process to GC itself.  This will either do it
19482     * immediately, or put it on the list of processes to gc the next
19483     * time things are idle.
19484     */
19485    final void scheduleAppGcLocked(ProcessRecord app) {
19486        long now = SystemClock.uptimeMillis();
19487        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19488            return;
19489        }
19490        if (!mProcessesToGc.contains(app)) {
19491            addProcessToGcListLocked(app);
19492            scheduleAppGcsLocked();
19493        }
19494    }
19495
19496    final void checkExcessivePowerUsageLocked(boolean doKills) {
19497        updateCpuStatsNow();
19498
19499        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19500        boolean doWakeKills = doKills;
19501        boolean doCpuKills = doKills;
19502        if (mLastPowerCheckRealtime == 0) {
19503            doWakeKills = false;
19504        }
19505        if (mLastPowerCheckUptime == 0) {
19506            doCpuKills = false;
19507        }
19508        if (stats.isScreenOn()) {
19509            doWakeKills = false;
19510        }
19511        final long curRealtime = SystemClock.elapsedRealtime();
19512        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19513        final long curUptime = SystemClock.uptimeMillis();
19514        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19515        mLastPowerCheckRealtime = curRealtime;
19516        mLastPowerCheckUptime = curUptime;
19517        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19518            doWakeKills = false;
19519        }
19520        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19521            doCpuKills = false;
19522        }
19523        int i = mLruProcesses.size();
19524        while (i > 0) {
19525            i--;
19526            ProcessRecord app = mLruProcesses.get(i);
19527            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19528                long wtime;
19529                synchronized (stats) {
19530                    wtime = stats.getProcessWakeTime(app.info.uid,
19531                            app.pid, curRealtime);
19532                }
19533                long wtimeUsed = wtime - app.lastWakeTime;
19534                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19535                if (DEBUG_POWER) {
19536                    StringBuilder sb = new StringBuilder(128);
19537                    sb.append("Wake for ");
19538                    app.toShortString(sb);
19539                    sb.append(": over ");
19540                    TimeUtils.formatDuration(realtimeSince, sb);
19541                    sb.append(" used ");
19542                    TimeUtils.formatDuration(wtimeUsed, sb);
19543                    sb.append(" (");
19544                    sb.append((wtimeUsed*100)/realtimeSince);
19545                    sb.append("%)");
19546                    Slog.i(TAG_POWER, sb.toString());
19547                    sb.setLength(0);
19548                    sb.append("CPU for ");
19549                    app.toShortString(sb);
19550                    sb.append(": over ");
19551                    TimeUtils.formatDuration(uptimeSince, sb);
19552                    sb.append(" used ");
19553                    TimeUtils.formatDuration(cputimeUsed, sb);
19554                    sb.append(" (");
19555                    sb.append((cputimeUsed*100)/uptimeSince);
19556                    sb.append("%)");
19557                    Slog.i(TAG_POWER, sb.toString());
19558                }
19559                // If a process has held a wake lock for more
19560                // than 50% of the time during this period,
19561                // that sounds bad.  Kill!
19562                if (doWakeKills && realtimeSince > 0
19563                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19564                    synchronized (stats) {
19565                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19566                                realtimeSince, wtimeUsed);
19567                    }
19568                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19569                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19570                } else if (doCpuKills && uptimeSince > 0
19571                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19572                    synchronized (stats) {
19573                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19574                                uptimeSince, cputimeUsed);
19575                    }
19576                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19577                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19578                } else {
19579                    app.lastWakeTime = wtime;
19580                    app.lastCpuTime = app.curCpuTime;
19581                }
19582            }
19583        }
19584    }
19585
19586    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19587            long nowElapsed) {
19588        boolean success = true;
19589
19590        if (app.curRawAdj != app.setRawAdj) {
19591            app.setRawAdj = app.curRawAdj;
19592        }
19593
19594        int changes = 0;
19595
19596        if (app.curAdj != app.setAdj) {
19597            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19598            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19599                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19600                    + app.adjType);
19601            app.setAdj = app.curAdj;
19602        }
19603
19604        if (app.setSchedGroup != app.curSchedGroup) {
19605            app.setSchedGroup = app.curSchedGroup;
19606            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19607                    "Setting sched group of " + app.processName
19608                    + " to " + app.curSchedGroup);
19609            if (app.waitingToKill != null && app.curReceiver == null
19610                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19611                app.kill(app.waitingToKill, true);
19612                success = false;
19613            } else {
19614                int processGroup;
19615                switch (app.curSchedGroup) {
19616                    case ProcessList.SCHED_GROUP_BACKGROUND:
19617                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19618                        break;
19619                    case ProcessList.SCHED_GROUP_TOP_APP:
19620                        processGroup = Process.THREAD_GROUP_TOP_APP;
19621                        break;
19622                    default:
19623                        processGroup = Process.THREAD_GROUP_DEFAULT;
19624                        break;
19625                }
19626                if (true) {
19627                    long oldId = Binder.clearCallingIdentity();
19628                    try {
19629                        Process.setProcessGroup(app.pid, processGroup);
19630                    } catch (Exception e) {
19631                        Slog.w(TAG, "Failed setting process group of " + app.pid
19632                                + " to " + app.curSchedGroup);
19633                        e.printStackTrace();
19634                    } finally {
19635                        Binder.restoreCallingIdentity(oldId);
19636                    }
19637                } else {
19638                    if (app.thread != null) {
19639                        try {
19640                            app.thread.setSchedulingGroup(processGroup);
19641                        } catch (RemoteException e) {
19642                        }
19643                    }
19644                }
19645            }
19646        }
19647        if (app.repForegroundActivities != app.foregroundActivities) {
19648            app.repForegroundActivities = app.foregroundActivities;
19649            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19650        }
19651        if (app.repProcState != app.curProcState) {
19652            app.repProcState = app.curProcState;
19653            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19654            if (app.thread != null) {
19655                try {
19656                    if (false) {
19657                        //RuntimeException h = new RuntimeException("here");
19658                        Slog.i(TAG, "Sending new process state " + app.repProcState
19659                                + " to " + app /*, h*/);
19660                    }
19661                    app.thread.setProcessState(app.repProcState);
19662                } catch (RemoteException e) {
19663                }
19664            }
19665        }
19666        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19667                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19668            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19669                // Experimental code to more aggressively collect pss while
19670                // running test...  the problem is that this tends to collect
19671                // the data right when a process is transitioning between process
19672                // states, which well tend to give noisy data.
19673                long start = SystemClock.uptimeMillis();
19674                long pss = Debug.getPss(app.pid, mTmpLong, null);
19675                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19676                mPendingPssProcesses.remove(app);
19677                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19678                        + " to " + app.curProcState + ": "
19679                        + (SystemClock.uptimeMillis()-start) + "ms");
19680            }
19681            app.lastStateTime = now;
19682            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19683                    mTestPssMode, isSleeping(), now);
19684            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19685                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19686                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19687                    + (app.nextPssTime-now) + ": " + app);
19688        } else {
19689            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19690                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19691                    mTestPssMode)))) {
19692                requestPssLocked(app, app.setProcState);
19693                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19694                        mTestPssMode, isSleeping(), now);
19695            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19696                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19697        }
19698        if (app.setProcState != app.curProcState) {
19699            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19700                    "Proc state change of " + app.processName
19701                            + " to " + app.curProcState);
19702            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19703            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19704            if (setImportant && !curImportant) {
19705                // This app is no longer something we consider important enough to allow to
19706                // use arbitrary amounts of battery power.  Note
19707                // its current wake lock time to later know to kill it if
19708                // it is not behaving well.
19709                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19710                synchronized (stats) {
19711                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19712                            app.pid, nowElapsed);
19713                }
19714                app.lastCpuTime = app.curCpuTime;
19715
19716            }
19717            // Inform UsageStats of important process state change
19718            // Must be called before updating setProcState
19719            maybeUpdateUsageStatsLocked(app, nowElapsed);
19720
19721            app.setProcState = app.curProcState;
19722            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19723                app.notCachedSinceIdle = false;
19724            }
19725            if (!doingAll) {
19726                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19727            } else {
19728                app.procStateChanged = true;
19729            }
19730        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19731                > USAGE_STATS_INTERACTION_INTERVAL) {
19732            // For apps that sit around for a long time in the interactive state, we need
19733            // to report this at least once a day so they don't go idle.
19734            maybeUpdateUsageStatsLocked(app, nowElapsed);
19735        }
19736
19737        if (changes != 0) {
19738            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19739                    "Changes in " + app + ": " + changes);
19740            int i = mPendingProcessChanges.size()-1;
19741            ProcessChangeItem item = null;
19742            while (i >= 0) {
19743                item = mPendingProcessChanges.get(i);
19744                if (item.pid == app.pid) {
19745                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19746                            "Re-using existing item: " + item);
19747                    break;
19748                }
19749                i--;
19750            }
19751            if (i < 0) {
19752                // No existing item in pending changes; need a new one.
19753                final int NA = mAvailProcessChanges.size();
19754                if (NA > 0) {
19755                    item = mAvailProcessChanges.remove(NA-1);
19756                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19757                            "Retrieving available item: " + item);
19758                } else {
19759                    item = new ProcessChangeItem();
19760                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19761                            "Allocating new item: " + item);
19762                }
19763                item.changes = 0;
19764                item.pid = app.pid;
19765                item.uid = app.info.uid;
19766                if (mPendingProcessChanges.size() == 0) {
19767                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19768                            "*** Enqueueing dispatch processes changed!");
19769                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19770                }
19771                mPendingProcessChanges.add(item);
19772            }
19773            item.changes |= changes;
19774            item.processState = app.repProcState;
19775            item.foregroundActivities = app.repForegroundActivities;
19776            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19777                    "Item " + Integer.toHexString(System.identityHashCode(item))
19778                    + " " + app.toShortString() + ": changes=" + item.changes
19779                    + " procState=" + item.processState
19780                    + " foreground=" + item.foregroundActivities
19781                    + " type=" + app.adjType + " source=" + app.adjSource
19782                    + " target=" + app.adjTarget);
19783        }
19784
19785        return success;
19786    }
19787
19788    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19789        final UidRecord.ChangeItem pendingChange;
19790        if (uidRec == null || uidRec.pendingChange == null) {
19791            if (mPendingUidChanges.size() == 0) {
19792                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19793                        "*** Enqueueing dispatch uid changed!");
19794                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19795            }
19796            final int NA = mAvailUidChanges.size();
19797            if (NA > 0) {
19798                pendingChange = mAvailUidChanges.remove(NA-1);
19799                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19800                        "Retrieving available item: " + pendingChange);
19801            } else {
19802                pendingChange = new UidRecord.ChangeItem();
19803                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19804                        "Allocating new item: " + pendingChange);
19805            }
19806            if (uidRec != null) {
19807                uidRec.pendingChange = pendingChange;
19808                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19809                    // If this uid is going away, and we haven't yet reported it is gone,
19810                    // then do so now.
19811                    change = UidRecord.CHANGE_GONE_IDLE;
19812                }
19813            } else if (uid < 0) {
19814                throw new IllegalArgumentException("No UidRecord or uid");
19815            }
19816            pendingChange.uidRecord = uidRec;
19817            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19818            mPendingUidChanges.add(pendingChange);
19819        } else {
19820            pendingChange = uidRec.pendingChange;
19821            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19822                change = UidRecord.CHANGE_GONE_IDLE;
19823            }
19824        }
19825        pendingChange.change = change;
19826        pendingChange.processState = uidRec != null
19827                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19828    }
19829
19830    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19831            String authority) {
19832        if (app == null) return;
19833        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19834            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19835            if (userState == null) return;
19836            final long now = SystemClock.elapsedRealtime();
19837            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19838            if (lastReported == null || lastReported < now - 60 * 1000L) {
19839                mUsageStatsService.reportContentProviderUsage(
19840                        authority, providerPkgName, app.userId);
19841                userState.mProviderLastReportedFg.put(authority, now);
19842            }
19843        }
19844    }
19845
19846    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19847        if (DEBUG_USAGE_STATS) {
19848            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19849                    + "] state changes: old = " + app.setProcState + ", new = "
19850                    + app.curProcState);
19851        }
19852        if (mUsageStatsService == null) {
19853            return;
19854        }
19855        boolean isInteraction;
19856        // To avoid some abuse patterns, we are going to be careful about what we consider
19857        // to be an app interaction.  Being the top activity doesn't count while the display
19858        // is sleeping, nor do short foreground services.
19859        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19860            isInteraction = true;
19861            app.fgInteractionTime = 0;
19862        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19863            if (app.fgInteractionTime == 0) {
19864                app.fgInteractionTime = nowElapsed;
19865                isInteraction = false;
19866            } else {
19867                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19868            }
19869        } else {
19870            isInteraction = app.curProcState
19871                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19872            app.fgInteractionTime = 0;
19873        }
19874        if (isInteraction && (!app.reportedInteraction
19875                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19876            app.interactionEventTime = nowElapsed;
19877            String[] packages = app.getPackageList();
19878            if (packages != null) {
19879                for (int i = 0; i < packages.length; i++) {
19880                    mUsageStatsService.reportEvent(packages[i], app.userId,
19881                            UsageEvents.Event.SYSTEM_INTERACTION);
19882                }
19883            }
19884        }
19885        app.reportedInteraction = isInteraction;
19886        if (!isInteraction) {
19887            app.interactionEventTime = 0;
19888        }
19889    }
19890
19891    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19892        if (proc.thread != null) {
19893            if (proc.baseProcessTracker != null) {
19894                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19895            }
19896        }
19897    }
19898
19899    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19900            ProcessRecord TOP_APP, boolean doingAll, long now) {
19901        if (app.thread == null) {
19902            return false;
19903        }
19904
19905        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19906
19907        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19908    }
19909
19910    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19911            boolean oomAdj) {
19912        if (isForeground != proc.foregroundServices) {
19913            proc.foregroundServices = isForeground;
19914            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19915                    proc.info.uid);
19916            if (isForeground) {
19917                if (curProcs == null) {
19918                    curProcs = new ArrayList<ProcessRecord>();
19919                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19920                }
19921                if (!curProcs.contains(proc)) {
19922                    curProcs.add(proc);
19923                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19924                            proc.info.packageName, proc.info.uid);
19925                }
19926            } else {
19927                if (curProcs != null) {
19928                    if (curProcs.remove(proc)) {
19929                        mBatteryStatsService.noteEvent(
19930                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19931                                proc.info.packageName, proc.info.uid);
19932                        if (curProcs.size() <= 0) {
19933                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19934                        }
19935                    }
19936                }
19937            }
19938            if (oomAdj) {
19939                updateOomAdjLocked();
19940            }
19941        }
19942    }
19943
19944    private final ActivityRecord resumedAppLocked() {
19945        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19946        String pkg;
19947        int uid;
19948        if (act != null) {
19949            pkg = act.packageName;
19950            uid = act.info.applicationInfo.uid;
19951        } else {
19952            pkg = null;
19953            uid = -1;
19954        }
19955        // Has the UID or resumed package name changed?
19956        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19957                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19958            if (mCurResumedPackage != null) {
19959                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19960                        mCurResumedPackage, mCurResumedUid);
19961            }
19962            mCurResumedPackage = pkg;
19963            mCurResumedUid = uid;
19964            if (mCurResumedPackage != null) {
19965                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19966                        mCurResumedPackage, mCurResumedUid);
19967            }
19968        }
19969        return act;
19970    }
19971
19972    final boolean updateOomAdjLocked(ProcessRecord app) {
19973        final ActivityRecord TOP_ACT = resumedAppLocked();
19974        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19975        final boolean wasCached = app.cached;
19976
19977        mAdjSeq++;
19978
19979        // This is the desired cached adjusment we want to tell it to use.
19980        // If our app is currently cached, we know it, and that is it.  Otherwise,
19981        // we don't know it yet, and it needs to now be cached we will then
19982        // need to do a complete oom adj.
19983        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19984                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19985        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19986                SystemClock.uptimeMillis());
19987        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19988            // Changed to/from cached state, so apps after it in the LRU
19989            // list may also be changed.
19990            updateOomAdjLocked();
19991        }
19992        return success;
19993    }
19994
19995    final void updateOomAdjLocked() {
19996        final ActivityRecord TOP_ACT = resumedAppLocked();
19997        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19998        final long now = SystemClock.uptimeMillis();
19999        final long nowElapsed = SystemClock.elapsedRealtime();
20000        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20001        final int N = mLruProcesses.size();
20002
20003        if (false) {
20004            RuntimeException e = new RuntimeException();
20005            e.fillInStackTrace();
20006            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20007        }
20008
20009        // Reset state in all uid records.
20010        for (int i=mActiveUids.size()-1; i>=0; i--) {
20011            final UidRecord uidRec = mActiveUids.valueAt(i);
20012            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20013                    "Starting update of " + uidRec);
20014            uidRec.reset();
20015        }
20016
20017        mStackSupervisor.rankTaskLayersIfNeeded();
20018
20019        mAdjSeq++;
20020        mNewNumServiceProcs = 0;
20021        mNewNumAServiceProcs = 0;
20022
20023        final int emptyProcessLimit;
20024        final int cachedProcessLimit;
20025        if (mProcessLimit <= 0) {
20026            emptyProcessLimit = cachedProcessLimit = 0;
20027        } else if (mProcessLimit == 1) {
20028            emptyProcessLimit = 1;
20029            cachedProcessLimit = 0;
20030        } else {
20031            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20032            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20033        }
20034
20035        // Let's determine how many processes we have running vs.
20036        // how many slots we have for background processes; we may want
20037        // to put multiple processes in a slot of there are enough of
20038        // them.
20039        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20040                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20041        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20042        if (numEmptyProcs > cachedProcessLimit) {
20043            // If there are more empty processes than our limit on cached
20044            // processes, then use the cached process limit for the factor.
20045            // This ensures that the really old empty processes get pushed
20046            // down to the bottom, so if we are running low on memory we will
20047            // have a better chance at keeping around more cached processes
20048            // instead of a gazillion empty processes.
20049            numEmptyProcs = cachedProcessLimit;
20050        }
20051        int emptyFactor = numEmptyProcs/numSlots;
20052        if (emptyFactor < 1) emptyFactor = 1;
20053        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20054        if (cachedFactor < 1) cachedFactor = 1;
20055        int stepCached = 0;
20056        int stepEmpty = 0;
20057        int numCached = 0;
20058        int numEmpty = 0;
20059        int numTrimming = 0;
20060
20061        mNumNonCachedProcs = 0;
20062        mNumCachedHiddenProcs = 0;
20063
20064        // First update the OOM adjustment for each of the
20065        // application processes based on their current state.
20066        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20067        int nextCachedAdj = curCachedAdj+1;
20068        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20069        int nextEmptyAdj = curEmptyAdj+2;
20070        for (int i=N-1; i>=0; i--) {
20071            ProcessRecord app = mLruProcesses.get(i);
20072            if (!app.killedByAm && app.thread != null) {
20073                app.procStateChanged = false;
20074                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20075
20076                // If we haven't yet assigned the final cached adj
20077                // to the process, do that now.
20078                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20079                    switch (app.curProcState) {
20080                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20081                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20082                            // This process is a cached process holding activities...
20083                            // assign it the next cached value for that type, and then
20084                            // step that cached level.
20085                            app.curRawAdj = curCachedAdj;
20086                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20087                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20088                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20089                                    + ")");
20090                            if (curCachedAdj != nextCachedAdj) {
20091                                stepCached++;
20092                                if (stepCached >= cachedFactor) {
20093                                    stepCached = 0;
20094                                    curCachedAdj = nextCachedAdj;
20095                                    nextCachedAdj += 2;
20096                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20097                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20098                                    }
20099                                }
20100                            }
20101                            break;
20102                        default:
20103                            // For everything else, assign next empty cached process
20104                            // level and bump that up.  Note that this means that
20105                            // long-running services that have dropped down to the
20106                            // cached level will be treated as empty (since their process
20107                            // state is still as a service), which is what we want.
20108                            app.curRawAdj = curEmptyAdj;
20109                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20110                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20111                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20112                                    + ")");
20113                            if (curEmptyAdj != nextEmptyAdj) {
20114                                stepEmpty++;
20115                                if (stepEmpty >= emptyFactor) {
20116                                    stepEmpty = 0;
20117                                    curEmptyAdj = nextEmptyAdj;
20118                                    nextEmptyAdj += 2;
20119                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20120                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20121                                    }
20122                                }
20123                            }
20124                            break;
20125                    }
20126                }
20127
20128                applyOomAdjLocked(app, true, now, nowElapsed);
20129
20130                // Count the number of process types.
20131                switch (app.curProcState) {
20132                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20133                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20134                        mNumCachedHiddenProcs++;
20135                        numCached++;
20136                        if (numCached > cachedProcessLimit) {
20137                            app.kill("cached #" + numCached, true);
20138                        }
20139                        break;
20140                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20141                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20142                                && app.lastActivityTime < oldTime) {
20143                            app.kill("empty for "
20144                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20145                                    / 1000) + "s", true);
20146                        } else {
20147                            numEmpty++;
20148                            if (numEmpty > emptyProcessLimit) {
20149                                app.kill("empty #" + numEmpty, true);
20150                            }
20151                        }
20152                        break;
20153                    default:
20154                        mNumNonCachedProcs++;
20155                        break;
20156                }
20157
20158                if (app.isolated && app.services.size() <= 0) {
20159                    // If this is an isolated process, and there are no
20160                    // services running in it, then the process is no longer
20161                    // needed.  We agressively kill these because we can by
20162                    // definition not re-use the same process again, and it is
20163                    // good to avoid having whatever code was running in them
20164                    // left sitting around after no longer needed.
20165                    app.kill("isolated not needed", true);
20166                } else {
20167                    // Keeping this process, update its uid.
20168                    final UidRecord uidRec = app.uidRecord;
20169                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20170                        uidRec.curProcState = app.curProcState;
20171                    }
20172                }
20173
20174                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20175                        && !app.killedByAm) {
20176                    numTrimming++;
20177                }
20178            }
20179        }
20180
20181        mNumServiceProcs = mNewNumServiceProcs;
20182
20183        // Now determine the memory trimming level of background processes.
20184        // Unfortunately we need to start at the back of the list to do this
20185        // properly.  We only do this if the number of background apps we
20186        // are managing to keep around is less than half the maximum we desire;
20187        // if we are keeping a good number around, we'll let them use whatever
20188        // memory they want.
20189        final int numCachedAndEmpty = numCached + numEmpty;
20190        int memFactor;
20191        if (numCached <= ProcessList.TRIM_CACHED_APPS
20192                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20193            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20194                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20195            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20196                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20197            } else {
20198                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20199            }
20200        } else {
20201            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20202        }
20203        // We always allow the memory level to go up (better).  We only allow it to go
20204        // down if we are in a state where that is allowed, *and* the total number of processes
20205        // has gone down since last time.
20206        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20207                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20208                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20209        if (memFactor > mLastMemoryLevel) {
20210            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20211                memFactor = mLastMemoryLevel;
20212                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20213            }
20214        }
20215        if (memFactor != mLastMemoryLevel) {
20216            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20217        }
20218        mLastMemoryLevel = memFactor;
20219        mLastNumProcesses = mLruProcesses.size();
20220        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20221        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20222        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20223            if (mLowRamStartTime == 0) {
20224                mLowRamStartTime = now;
20225            }
20226            int step = 0;
20227            int fgTrimLevel;
20228            switch (memFactor) {
20229                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20230                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20231                    break;
20232                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20233                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20234                    break;
20235                default:
20236                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20237                    break;
20238            }
20239            int factor = numTrimming/3;
20240            int minFactor = 2;
20241            if (mHomeProcess != null) minFactor++;
20242            if (mPreviousProcess != null) minFactor++;
20243            if (factor < minFactor) factor = minFactor;
20244            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20245            for (int i=N-1; i>=0; i--) {
20246                ProcessRecord app = mLruProcesses.get(i);
20247                if (allChanged || app.procStateChanged) {
20248                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20249                    app.procStateChanged = false;
20250                }
20251                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20252                        && !app.killedByAm) {
20253                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20254                        try {
20255                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20256                                    "Trimming memory of " + app.processName + " to " + curLevel);
20257                            app.thread.scheduleTrimMemory(curLevel);
20258                        } catch (RemoteException e) {
20259                        }
20260                        if (false) {
20261                            // For now we won't do this; our memory trimming seems
20262                            // to be good enough at this point that destroying
20263                            // activities causes more harm than good.
20264                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20265                                    && app != mHomeProcess && app != mPreviousProcess) {
20266                                // Need to do this on its own message because the stack may not
20267                                // be in a consistent state at this point.
20268                                // For these apps we will also finish their activities
20269                                // to help them free memory.
20270                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20271                            }
20272                        }
20273                    }
20274                    app.trimMemoryLevel = curLevel;
20275                    step++;
20276                    if (step >= factor) {
20277                        step = 0;
20278                        switch (curLevel) {
20279                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20280                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20281                                break;
20282                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20283                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20284                                break;
20285                        }
20286                    }
20287                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20288                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20289                            && app.thread != null) {
20290                        try {
20291                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20292                                    "Trimming memory of heavy-weight " + app.processName
20293                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20294                            app.thread.scheduleTrimMemory(
20295                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20296                        } catch (RemoteException e) {
20297                        }
20298                    }
20299                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20300                } else {
20301                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20302                            || app.systemNoUi) && app.pendingUiClean) {
20303                        // If this application is now in the background and it
20304                        // had done UI, then give it the special trim level to
20305                        // have it free UI resources.
20306                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20307                        if (app.trimMemoryLevel < level && app.thread != null) {
20308                            try {
20309                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20310                                        "Trimming memory of bg-ui " + app.processName
20311                                        + " to " + level);
20312                                app.thread.scheduleTrimMemory(level);
20313                            } catch (RemoteException e) {
20314                            }
20315                        }
20316                        app.pendingUiClean = false;
20317                    }
20318                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20319                        try {
20320                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20321                                    "Trimming memory of fg " + app.processName
20322                                    + " to " + fgTrimLevel);
20323                            app.thread.scheduleTrimMemory(fgTrimLevel);
20324                        } catch (RemoteException e) {
20325                        }
20326                    }
20327                    app.trimMemoryLevel = fgTrimLevel;
20328                }
20329            }
20330        } else {
20331            if (mLowRamStartTime != 0) {
20332                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20333                mLowRamStartTime = 0;
20334            }
20335            for (int i=N-1; i>=0; i--) {
20336                ProcessRecord app = mLruProcesses.get(i);
20337                if (allChanged || app.procStateChanged) {
20338                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20339                    app.procStateChanged = false;
20340                }
20341                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20342                        || app.systemNoUi) && app.pendingUiClean) {
20343                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20344                            && app.thread != null) {
20345                        try {
20346                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20347                                    "Trimming memory of ui hidden " + app.processName
20348                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20349                            app.thread.scheduleTrimMemory(
20350                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20351                        } catch (RemoteException e) {
20352                        }
20353                    }
20354                    app.pendingUiClean = false;
20355                }
20356                app.trimMemoryLevel = 0;
20357            }
20358        }
20359
20360        if (mAlwaysFinishActivities) {
20361            // Need to do this on its own message because the stack may not
20362            // be in a consistent state at this point.
20363            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20364        }
20365
20366        if (allChanged) {
20367            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20368        }
20369
20370        // Update from any uid changes.
20371        for (int i=mActiveUids.size()-1; i>=0; i--) {
20372            final UidRecord uidRec = mActiveUids.valueAt(i);
20373            int uidChange = UidRecord.CHANGE_PROCSTATE;
20374            if (uidRec.setProcState != uidRec.curProcState) {
20375                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20376                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20377                        + " to " + uidRec.curProcState);
20378                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20379                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20380                        uidRec.lastBackgroundTime = nowElapsed;
20381                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20382                            // Note: the background settle time is in elapsed realtime, while
20383                            // the handler time base is uptime.  All this means is that we may
20384                            // stop background uids later than we had intended, but that only
20385                            // happens because the device was sleeping so we are okay anyway.
20386                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20387                        }
20388                    }
20389                } else {
20390                    if (uidRec.idle) {
20391                        uidChange = UidRecord.CHANGE_ACTIVE;
20392                        uidRec.idle = false;
20393                    }
20394                    uidRec.lastBackgroundTime = 0;
20395                }
20396                uidRec.setProcState = uidRec.curProcState;
20397                enqueueUidChangeLocked(uidRec, -1, uidChange);
20398                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20399            }
20400        }
20401
20402        if (mProcessStats.shouldWriteNowLocked(now)) {
20403            mHandler.post(new Runnable() {
20404                @Override public void run() {
20405                    synchronized (ActivityManagerService.this) {
20406                        mProcessStats.writeStateAsyncLocked();
20407                    }
20408                }
20409            });
20410        }
20411
20412        if (DEBUG_OOM_ADJ) {
20413            final long duration = SystemClock.uptimeMillis() - now;
20414            if (false) {
20415                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20416                        new RuntimeException("here").fillInStackTrace());
20417            } else {
20418                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20419            }
20420        }
20421    }
20422
20423    final void idleUids() {
20424        synchronized (this) {
20425            final long nowElapsed = SystemClock.elapsedRealtime();
20426            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20427            long nextTime = 0;
20428            for (int i=mActiveUids.size()-1; i>=0; i--) {
20429                final UidRecord uidRec = mActiveUids.valueAt(i);
20430                final long bgTime = uidRec.lastBackgroundTime;
20431                if (bgTime > 0 && !uidRec.idle) {
20432                    if (bgTime <= maxBgTime) {
20433                        uidRec.idle = true;
20434                        doStopUidLocked(uidRec.uid, uidRec);
20435                    } else {
20436                        if (nextTime == 0 || nextTime > bgTime) {
20437                            nextTime = bgTime;
20438                        }
20439                    }
20440                }
20441            }
20442            if (nextTime > 0) {
20443                mHandler.removeMessages(IDLE_UIDS_MSG);
20444                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20445                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20446            }
20447        }
20448    }
20449
20450    final void runInBackgroundDisabled(int uid) {
20451        synchronized (this) {
20452            UidRecord uidRec = mActiveUids.get(uid);
20453            if (uidRec != null) {
20454                // This uid is actually running...  should it be considered background now?
20455                if (uidRec.idle) {
20456                    doStopUidLocked(uidRec.uid, uidRec);
20457                }
20458            } else {
20459                // This uid isn't actually running...  still send a report about it being "stopped".
20460                doStopUidLocked(uid, null);
20461            }
20462        }
20463    }
20464
20465    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20466        mServices.stopInBackgroundLocked(uid);
20467        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20468    }
20469
20470    final void trimApplications() {
20471        synchronized (this) {
20472            int i;
20473
20474            // First remove any unused application processes whose package
20475            // has been removed.
20476            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20477                final ProcessRecord app = mRemovedProcesses.get(i);
20478                if (app.activities.size() == 0
20479                        && app.curReceiver == null && app.services.size() == 0) {
20480                    Slog.i(
20481                        TAG, "Exiting empty application process "
20482                        + app.toShortString() + " ("
20483                        + (app.thread != null ? app.thread.asBinder() : null)
20484                        + ")\n");
20485                    if (app.pid > 0 && app.pid != MY_PID) {
20486                        app.kill("empty", false);
20487                    } else {
20488                        try {
20489                            app.thread.scheduleExit();
20490                        } catch (Exception e) {
20491                            // Ignore exceptions.
20492                        }
20493                    }
20494                    cleanUpApplicationRecordLocked(app, false, true, -1);
20495                    mRemovedProcesses.remove(i);
20496
20497                    if (app.persistent) {
20498                        addAppLocked(app.info, false, null /* ABI override */);
20499                    }
20500                }
20501            }
20502
20503            // Now update the oom adj for all processes.
20504            updateOomAdjLocked();
20505        }
20506    }
20507
20508    /** This method sends the specified signal to each of the persistent apps */
20509    public void signalPersistentProcesses(int sig) throws RemoteException {
20510        if (sig != Process.SIGNAL_USR1) {
20511            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20512        }
20513
20514        synchronized (this) {
20515            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20516                    != PackageManager.PERMISSION_GRANTED) {
20517                throw new SecurityException("Requires permission "
20518                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20519            }
20520
20521            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20522                ProcessRecord r = mLruProcesses.get(i);
20523                if (r.thread != null && r.persistent) {
20524                    Process.sendSignal(r.pid, sig);
20525                }
20526            }
20527        }
20528    }
20529
20530    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20531        if (proc == null || proc == mProfileProc) {
20532            proc = mProfileProc;
20533            profileType = mProfileType;
20534            clearProfilerLocked();
20535        }
20536        if (proc == null) {
20537            return;
20538        }
20539        try {
20540            proc.thread.profilerControl(false, null, profileType);
20541        } catch (RemoteException e) {
20542            throw new IllegalStateException("Process disappeared");
20543        }
20544    }
20545
20546    private void clearProfilerLocked() {
20547        if (mProfileFd != null) {
20548            try {
20549                mProfileFd.close();
20550            } catch (IOException e) {
20551            }
20552        }
20553        mProfileApp = null;
20554        mProfileProc = null;
20555        mProfileFile = null;
20556        mProfileType = 0;
20557        mAutoStopProfiler = false;
20558        mSamplingInterval = 0;
20559    }
20560
20561    public boolean profileControl(String process, int userId, boolean start,
20562            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20563
20564        try {
20565            synchronized (this) {
20566                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20567                // its own permission.
20568                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20569                        != PackageManager.PERMISSION_GRANTED) {
20570                    throw new SecurityException("Requires permission "
20571                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20572                }
20573
20574                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20575                    throw new IllegalArgumentException("null profile info or fd");
20576                }
20577
20578                ProcessRecord proc = null;
20579                if (process != null) {
20580                    proc = findProcessLocked(process, userId, "profileControl");
20581                }
20582
20583                if (start && (proc == null || proc.thread == null)) {
20584                    throw new IllegalArgumentException("Unknown process: " + process);
20585                }
20586
20587                if (start) {
20588                    stopProfilerLocked(null, 0);
20589                    setProfileApp(proc.info, proc.processName, profilerInfo);
20590                    mProfileProc = proc;
20591                    mProfileType = profileType;
20592                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20593                    try {
20594                        fd = fd.dup();
20595                    } catch (IOException e) {
20596                        fd = null;
20597                    }
20598                    profilerInfo.profileFd = fd;
20599                    proc.thread.profilerControl(start, profilerInfo, profileType);
20600                    fd = null;
20601                    mProfileFd = null;
20602                } else {
20603                    stopProfilerLocked(proc, profileType);
20604                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20605                        try {
20606                            profilerInfo.profileFd.close();
20607                        } catch (IOException e) {
20608                        }
20609                    }
20610                }
20611
20612                return true;
20613            }
20614        } catch (RemoteException e) {
20615            throw new IllegalStateException("Process disappeared");
20616        } finally {
20617            if (profilerInfo != null && profilerInfo.profileFd != null) {
20618                try {
20619                    profilerInfo.profileFd.close();
20620                } catch (IOException e) {
20621                }
20622            }
20623        }
20624    }
20625
20626    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20627        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20628                userId, true, ALLOW_FULL_ONLY, callName, null);
20629        ProcessRecord proc = null;
20630        try {
20631            int pid = Integer.parseInt(process);
20632            synchronized (mPidsSelfLocked) {
20633                proc = mPidsSelfLocked.get(pid);
20634            }
20635        } catch (NumberFormatException e) {
20636        }
20637
20638        if (proc == null) {
20639            ArrayMap<String, SparseArray<ProcessRecord>> all
20640                    = mProcessNames.getMap();
20641            SparseArray<ProcessRecord> procs = all.get(process);
20642            if (procs != null && procs.size() > 0) {
20643                proc = procs.valueAt(0);
20644                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20645                    for (int i=1; i<procs.size(); i++) {
20646                        ProcessRecord thisProc = procs.valueAt(i);
20647                        if (thisProc.userId == userId) {
20648                            proc = thisProc;
20649                            break;
20650                        }
20651                    }
20652                }
20653            }
20654        }
20655
20656        return proc;
20657    }
20658
20659    public boolean dumpHeap(String process, int userId, boolean managed,
20660            String path, ParcelFileDescriptor fd) throws RemoteException {
20661
20662        try {
20663            synchronized (this) {
20664                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20665                // its own permission (same as profileControl).
20666                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20667                        != PackageManager.PERMISSION_GRANTED) {
20668                    throw new SecurityException("Requires permission "
20669                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20670                }
20671
20672                if (fd == null) {
20673                    throw new IllegalArgumentException("null fd");
20674                }
20675
20676                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20677                if (proc == null || proc.thread == null) {
20678                    throw new IllegalArgumentException("Unknown process: " + process);
20679                }
20680
20681                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20682                if (!isDebuggable) {
20683                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20684                        throw new SecurityException("Process not debuggable: " + proc);
20685                    }
20686                }
20687
20688                proc.thread.dumpHeap(managed, path, fd);
20689                fd = null;
20690                return true;
20691            }
20692        } catch (RemoteException e) {
20693            throw new IllegalStateException("Process disappeared");
20694        } finally {
20695            if (fd != null) {
20696                try {
20697                    fd.close();
20698                } catch (IOException e) {
20699                }
20700            }
20701        }
20702    }
20703
20704    @Override
20705    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20706            String reportPackage) {
20707        if (processName != null) {
20708            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20709                    "setDumpHeapDebugLimit()");
20710        } else {
20711            synchronized (mPidsSelfLocked) {
20712                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20713                if (proc == null) {
20714                    throw new SecurityException("No process found for calling pid "
20715                            + Binder.getCallingPid());
20716                }
20717                if (!Build.IS_DEBUGGABLE
20718                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20719                    throw new SecurityException("Not running a debuggable build");
20720                }
20721                processName = proc.processName;
20722                uid = proc.uid;
20723                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20724                    throw new SecurityException("Package " + reportPackage + " is not running in "
20725                            + proc);
20726                }
20727            }
20728        }
20729        synchronized (this) {
20730            if (maxMemSize > 0) {
20731                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20732            } else {
20733                if (uid != 0) {
20734                    mMemWatchProcesses.remove(processName, uid);
20735                } else {
20736                    mMemWatchProcesses.getMap().remove(processName);
20737                }
20738            }
20739        }
20740    }
20741
20742    @Override
20743    public void dumpHeapFinished(String path) {
20744        synchronized (this) {
20745            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20746                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20747                        + " does not match last pid " + mMemWatchDumpPid);
20748                return;
20749            }
20750            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20751                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20752                        + " does not match last path " + mMemWatchDumpFile);
20753                return;
20754            }
20755            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20756            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20757        }
20758    }
20759
20760    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20761    public void monitor() {
20762        synchronized (this) { }
20763    }
20764
20765    void onCoreSettingsChange(Bundle settings) {
20766        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20767            ProcessRecord processRecord = mLruProcesses.get(i);
20768            try {
20769                if (processRecord.thread != null) {
20770                    processRecord.thread.setCoreSettings(settings);
20771                }
20772            } catch (RemoteException re) {
20773                /* ignore */
20774            }
20775        }
20776    }
20777
20778    // Multi-user methods
20779
20780    /**
20781     * Start user, if its not already running, but don't bring it to foreground.
20782     */
20783    @Override
20784    public boolean startUserInBackground(final int userId) {
20785        return mUserController.startUser(userId, /* foreground */ false);
20786    }
20787
20788    @Override
20789    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20790        return mUserController.unlockUser(userId, token, secret, listener);
20791    }
20792
20793    @Override
20794    public boolean switchUser(final int targetUserId) {
20795        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20796        UserInfo currentUserInfo;
20797        UserInfo targetUserInfo;
20798        synchronized (this) {
20799            int currentUserId = mUserController.getCurrentUserIdLocked();
20800            currentUserInfo = mUserController.getUserInfo(currentUserId);
20801            targetUserInfo = mUserController.getUserInfo(targetUserId);
20802            if (targetUserInfo == null) {
20803                Slog.w(TAG, "No user info for user #" + targetUserId);
20804                return false;
20805            }
20806            if (!targetUserInfo.supportsSwitchTo()) {
20807                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20808                return false;
20809            }
20810            if (targetUserInfo.isManagedProfile()) {
20811                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20812                return false;
20813            }
20814            mUserController.setTargetUserIdLocked(targetUserId);
20815        }
20816        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20817        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20818        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20819        return true;
20820    }
20821
20822    void scheduleStartProfilesLocked() {
20823        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20824            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20825                    DateUtils.SECOND_IN_MILLIS);
20826        }
20827    }
20828
20829    @Override
20830    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20831        return mUserController.stopUser(userId, force, callback);
20832    }
20833
20834    @Override
20835    public UserInfo getCurrentUser() {
20836        return mUserController.getCurrentUser();
20837    }
20838
20839    @Override
20840    public boolean isUserRunning(int userId, int flags) {
20841        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20842                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20843            String msg = "Permission Denial: isUserRunning() from pid="
20844                    + Binder.getCallingPid()
20845                    + ", uid=" + Binder.getCallingUid()
20846                    + " requires " + INTERACT_ACROSS_USERS;
20847            Slog.w(TAG, msg);
20848            throw new SecurityException(msg);
20849        }
20850        synchronized (this) {
20851            return mUserController.isUserRunningLocked(userId, flags);
20852        }
20853    }
20854
20855    @Override
20856    public int[] getRunningUserIds() {
20857        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20858                != PackageManager.PERMISSION_GRANTED) {
20859            String msg = "Permission Denial: isUserRunning() from pid="
20860                    + Binder.getCallingPid()
20861                    + ", uid=" + Binder.getCallingUid()
20862                    + " requires " + INTERACT_ACROSS_USERS;
20863            Slog.w(TAG, msg);
20864            throw new SecurityException(msg);
20865        }
20866        synchronized (this) {
20867            return mUserController.getStartedUserArrayLocked();
20868        }
20869    }
20870
20871    @Override
20872    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20873        mUserController.registerUserSwitchObserver(observer);
20874    }
20875
20876    @Override
20877    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20878        mUserController.unregisterUserSwitchObserver(observer);
20879    }
20880
20881    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20882        if (info == null) return null;
20883        ApplicationInfo newInfo = new ApplicationInfo(info);
20884        newInfo.initForUser(userId);
20885        return newInfo;
20886    }
20887
20888    public boolean isUserStopped(int userId) {
20889        synchronized (this) {
20890            return mUserController.getStartedUserStateLocked(userId) == null;
20891        }
20892    }
20893
20894    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20895        if (aInfo == null
20896                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20897            return aInfo;
20898        }
20899
20900        ActivityInfo info = new ActivityInfo(aInfo);
20901        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20902        return info;
20903    }
20904
20905    private boolean processSanityChecksLocked(ProcessRecord process) {
20906        if (process == null || process.thread == null) {
20907            return false;
20908        }
20909
20910        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20911        if (!isDebuggable) {
20912            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20913                return false;
20914            }
20915        }
20916
20917        return true;
20918    }
20919
20920    public boolean startBinderTracking() throws RemoteException {
20921        synchronized (this) {
20922            mBinderTransactionTrackingEnabled = true;
20923            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20924            // permission (same as profileControl).
20925            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20926                    != PackageManager.PERMISSION_GRANTED) {
20927                throw new SecurityException("Requires permission "
20928                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20929            }
20930
20931            for (int i = 0; i < mLruProcesses.size(); i++) {
20932                ProcessRecord process = mLruProcesses.get(i);
20933                if (!processSanityChecksLocked(process)) {
20934                    continue;
20935                }
20936                try {
20937                    process.thread.startBinderTracking();
20938                } catch (RemoteException e) {
20939                    Log.v(TAG, "Process disappared");
20940                }
20941            }
20942            return true;
20943        }
20944    }
20945
20946    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20947        try {
20948            synchronized (this) {
20949                mBinderTransactionTrackingEnabled = false;
20950                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20951                // permission (same as profileControl).
20952                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20953                        != PackageManager.PERMISSION_GRANTED) {
20954                    throw new SecurityException("Requires permission "
20955                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20956                }
20957
20958                if (fd == null) {
20959                    throw new IllegalArgumentException("null fd");
20960                }
20961
20962                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20963                pw.println("Binder transaction traces for all processes.\n");
20964                for (ProcessRecord process : mLruProcesses) {
20965                    if (!processSanityChecksLocked(process)) {
20966                        continue;
20967                    }
20968
20969                    pw.println("Traces for process: " + process.processName);
20970                    pw.flush();
20971                    try {
20972                        TransferPipe tp = new TransferPipe();
20973                        try {
20974                            process.thread.stopBinderTrackingAndDump(
20975                                    tp.getWriteFd().getFileDescriptor());
20976                            tp.go(fd.getFileDescriptor());
20977                        } finally {
20978                            tp.kill();
20979                        }
20980                    } catch (IOException e) {
20981                        pw.println("Failure while dumping IPC traces from " + process +
20982                                ".  Exception: " + e);
20983                        pw.flush();
20984                    } catch (RemoteException e) {
20985                        pw.println("Got a RemoteException while dumping IPC traces from " +
20986                                process + ".  Exception: " + e);
20987                        pw.flush();
20988                    }
20989                }
20990                fd = null;
20991                return true;
20992            }
20993        } finally {
20994            if (fd != null) {
20995                try {
20996                    fd.close();
20997                } catch (IOException e) {
20998                }
20999            }
21000        }
21001    }
21002
21003    private final class LocalService extends ActivityManagerInternal {
21004        @Override
21005        public void onWakefulnessChanged(int wakefulness) {
21006            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21007        }
21008
21009        @Override
21010        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21011                String processName, String abiOverride, int uid, Runnable crashHandler) {
21012            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21013                    processName, abiOverride, uid, crashHandler);
21014        }
21015
21016        @Override
21017        public SleepToken acquireSleepToken(String tag) {
21018            Preconditions.checkNotNull(tag);
21019
21020            synchronized (ActivityManagerService.this) {
21021                SleepTokenImpl token = new SleepTokenImpl(tag);
21022                mSleepTokens.add(token);
21023                updateSleepIfNeededLocked();
21024                applyVrModeIfNeededLocked(mFocusedActivity, false);
21025                return token;
21026            }
21027        }
21028
21029        @Override
21030        public ComponentName getHomeActivityForUser(int userId) {
21031            synchronized (ActivityManagerService.this) {
21032                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21033                return homeActivity == null ? null : homeActivity.realActivity;
21034            }
21035        }
21036
21037        @Override
21038        public void onUserRemoved(int userId) {
21039            synchronized (ActivityManagerService.this) {
21040                ActivityManagerService.this.onUserStoppedLocked(userId);
21041            }
21042        }
21043
21044        @Override
21045        public void onLocalVoiceInteractionStarted(IBinder activity,
21046                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21047            synchronized (ActivityManagerService.this) {
21048                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21049                        voiceSession, voiceInteractor);
21050            }
21051        }
21052
21053        @Override
21054        public void notifyStartingWindowDrawn() {
21055            synchronized (ActivityManagerService.this) {
21056                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21057            }
21058        }
21059
21060        @Override
21061        public void notifyAppTransitionStarting(int reason) {
21062            synchronized (ActivityManagerService.this) {
21063                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21064            }
21065        }
21066
21067        @Override
21068        public void notifyAppTransitionFinished() {
21069            synchronized (ActivityManagerService.this) {
21070                mStackSupervisor.notifyAppTransitionDone();
21071            }
21072        }
21073
21074        @Override
21075        public void notifyAppTransitionCancelled() {
21076            synchronized (ActivityManagerService.this) {
21077                mStackSupervisor.notifyAppTransitionDone();
21078            }
21079        }
21080
21081        @Override
21082        public List<IBinder> getTopVisibleActivities() {
21083            synchronized (ActivityManagerService.this) {
21084                return mStackSupervisor.getTopVisibleActivities();
21085            }
21086        }
21087
21088        @Override
21089        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21090            synchronized (ActivityManagerService.this) {
21091                mStackSupervisor.setDockedStackMinimized(minimized);
21092            }
21093        }
21094
21095        @Override
21096        public void killForegroundAppsForUser(int userHandle) {
21097            synchronized (ActivityManagerService.this) {
21098                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21099                final int NP = mProcessNames.getMap().size();
21100                for (int ip = 0; ip < NP; ip++) {
21101                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21102                    final int NA = apps.size();
21103                    for (int ia = 0; ia < NA; ia++) {
21104                        final ProcessRecord app = apps.valueAt(ia);
21105                        if (app.persistent) {
21106                            // We don't kill persistent processes.
21107                            continue;
21108                        }
21109                        if (app.removed) {
21110                            procs.add(app);
21111                        } else if (app.userId == userHandle && app.foregroundActivities) {
21112                            app.removed = true;
21113                            procs.add(app);
21114                        }
21115                    }
21116                }
21117
21118                final int N = procs.size();
21119                for (int i = 0; i < N; i++) {
21120                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21121                }
21122            }
21123        }
21124    }
21125
21126    private final class SleepTokenImpl extends SleepToken {
21127        private final String mTag;
21128        private final long mAcquireTime;
21129
21130        public SleepTokenImpl(String tag) {
21131            mTag = tag;
21132            mAcquireTime = SystemClock.uptimeMillis();
21133        }
21134
21135        @Override
21136        public void release() {
21137            synchronized (ActivityManagerService.this) {
21138                if (mSleepTokens.remove(this)) {
21139                    updateSleepIfNeededLocked();
21140                }
21141            }
21142        }
21143
21144        @Override
21145        public String toString() {
21146            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21147        }
21148    }
21149
21150    /**
21151     * An implementation of IAppTask, that allows an app to manage its own tasks via
21152     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21153     * only the process that calls getAppTasks() can call the AppTask methods.
21154     */
21155    class AppTaskImpl extends IAppTask.Stub {
21156        private int mTaskId;
21157        private int mCallingUid;
21158
21159        public AppTaskImpl(int taskId, int callingUid) {
21160            mTaskId = taskId;
21161            mCallingUid = callingUid;
21162        }
21163
21164        private void checkCaller() {
21165            if (mCallingUid != Binder.getCallingUid()) {
21166                throw new SecurityException("Caller " + mCallingUid
21167                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21168            }
21169        }
21170
21171        @Override
21172        public void finishAndRemoveTask() {
21173            checkCaller();
21174
21175            synchronized (ActivityManagerService.this) {
21176                long origId = Binder.clearCallingIdentity();
21177                try {
21178                    // We remove the task from recents to preserve backwards
21179                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21180                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21181                    }
21182                } finally {
21183                    Binder.restoreCallingIdentity(origId);
21184                }
21185            }
21186        }
21187
21188        @Override
21189        public ActivityManager.RecentTaskInfo getTaskInfo() {
21190            checkCaller();
21191
21192            synchronized (ActivityManagerService.this) {
21193                long origId = Binder.clearCallingIdentity();
21194                try {
21195                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21196                    if (tr == null) {
21197                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21198                    }
21199                    return createRecentTaskInfoFromTaskRecord(tr);
21200                } finally {
21201                    Binder.restoreCallingIdentity(origId);
21202                }
21203            }
21204        }
21205
21206        @Override
21207        public void moveToFront() {
21208            checkCaller();
21209            // Will bring task to front if it already has a root activity.
21210            final long origId = Binder.clearCallingIdentity();
21211            try {
21212                synchronized (this) {
21213                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21214                }
21215            } finally {
21216                Binder.restoreCallingIdentity(origId);
21217            }
21218        }
21219
21220        @Override
21221        public int startActivity(IBinder whoThread, String callingPackage,
21222                Intent intent, String resolvedType, Bundle bOptions) {
21223            checkCaller();
21224
21225            int callingUser = UserHandle.getCallingUserId();
21226            TaskRecord tr;
21227            IApplicationThread appThread;
21228            synchronized (ActivityManagerService.this) {
21229                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21230                if (tr == null) {
21231                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21232                }
21233                appThread = ApplicationThreadNative.asInterface(whoThread);
21234                if (appThread == null) {
21235                    throw new IllegalArgumentException("Bad app thread " + appThread);
21236                }
21237            }
21238            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21239                    resolvedType, null, null, null, null, 0, 0, null, null,
21240                    null, bOptions, false, callingUser, null, tr);
21241        }
21242
21243        @Override
21244        public void setExcludeFromRecents(boolean exclude) {
21245            checkCaller();
21246
21247            synchronized (ActivityManagerService.this) {
21248                long origId = Binder.clearCallingIdentity();
21249                try {
21250                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21251                    if (tr == null) {
21252                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21253                    }
21254                    Intent intent = tr.getBaseIntent();
21255                    if (exclude) {
21256                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21257                    } else {
21258                        intent.setFlags(intent.getFlags()
21259                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21260                    }
21261                } finally {
21262                    Binder.restoreCallingIdentity(origId);
21263                }
21264            }
21265        }
21266    }
21267
21268    /**
21269     * Kill processes for the user with id userId and that depend on the package named packageName
21270     */
21271    @Override
21272    public void killPackageDependents(String packageName, int userId) {
21273        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21274        if (packageName == null) {
21275            throw new NullPointerException(
21276                    "Cannot kill the dependents of a package without its name.");
21277        }
21278
21279        long callingId = Binder.clearCallingIdentity();
21280        IPackageManager pm = AppGlobals.getPackageManager();
21281        int pkgUid = -1;
21282        try {
21283            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21284        } catch (RemoteException e) {
21285        }
21286        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21287            throw new IllegalArgumentException(
21288                    "Cannot kill dependents of non-existing package " + packageName);
21289        }
21290        try {
21291            synchronized(this) {
21292                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21293                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21294                        "dep: " + packageName);
21295            }
21296        } finally {
21297            Binder.restoreCallingIdentity(callingId);
21298        }
21299    }
21300}
21301