ActivityManagerService.java revision 4502ce2d498e6173f69b5af88cb2b81b76de990f
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
12886            if (UserManager.isSplitSystemUser()) {
12887                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12888                try {
12889                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12890                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12891                            UserHandle.USER_SYSTEM);
12892                } catch (RemoteException e) {
12893                    throw e.rethrowAsRuntimeException();
12894                }
12895            }
12896            startHomeActivityLocked(currentUserId, "systemReady");
12897
12898            try {
12899                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12900                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12901                            + " data partition or your device will be unstable.");
12902                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12903                }
12904            } catch (RemoteException e) {
12905            }
12906
12907            if (!Build.isBuildConsistent()) {
12908                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12909                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12910            }
12911
12912            long ident = Binder.clearCallingIdentity();
12913            try {
12914                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12915                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12916                        | Intent.FLAG_RECEIVER_FOREGROUND);
12917                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12918                broadcastIntentLocked(null, null, intent,
12919                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12920                        null, false, false, MY_PID, Process.SYSTEM_UID,
12921                        currentUserId);
12922                intent = new Intent(Intent.ACTION_USER_STARTING);
12923                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12924                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12925                broadcastIntentLocked(null, null, intent,
12926                        null, new IIntentReceiver.Stub() {
12927                            @Override
12928                            public void performReceive(Intent intent, int resultCode, String data,
12929                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12930                                    throws RemoteException {
12931                            }
12932                        }, 0, null, null,
12933                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12934                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12935            } catch (Throwable t) {
12936                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12937            } finally {
12938                Binder.restoreCallingIdentity(ident);
12939            }
12940            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12941            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12942        }
12943    }
12944
12945    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12946        synchronized (this) {
12947            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12948        }
12949    }
12950
12951    void skipCurrentReceiverLocked(ProcessRecord app) {
12952        for (BroadcastQueue queue : mBroadcastQueues) {
12953            queue.skipCurrentReceiverLocked(app);
12954        }
12955    }
12956
12957    /**
12958     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12959     * The application process will exit immediately after this call returns.
12960     * @param app object of the crashing app, null for the system server
12961     * @param crashInfo describing the exception
12962     */
12963    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12964        ProcessRecord r = findAppProcess(app, "Crash");
12965        final String processName = app == null ? "system_server"
12966                : (r == null ? "unknown" : r.processName);
12967
12968        handleApplicationCrashInner("crash", r, processName, crashInfo);
12969    }
12970
12971    /* Native crash reporting uses this inner version because it needs to be somewhat
12972     * decoupled from the AM-managed cleanup lifecycle
12973     */
12974    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12975            ApplicationErrorReport.CrashInfo crashInfo) {
12976        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12977                UserHandle.getUserId(Binder.getCallingUid()), processName,
12978                r == null ? -1 : r.info.flags,
12979                crashInfo.exceptionClassName,
12980                crashInfo.exceptionMessage,
12981                crashInfo.throwFileName,
12982                crashInfo.throwLineNumber);
12983
12984        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12985
12986        mAppErrors.crashApplication(r, crashInfo);
12987    }
12988
12989    public void handleApplicationStrictModeViolation(
12990            IBinder app,
12991            int violationMask,
12992            StrictMode.ViolationInfo info) {
12993        ProcessRecord r = findAppProcess(app, "StrictMode");
12994        if (r == null) {
12995            return;
12996        }
12997
12998        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12999            Integer stackFingerprint = info.hashCode();
13000            boolean logIt = true;
13001            synchronized (mAlreadyLoggedViolatedStacks) {
13002                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13003                    logIt = false;
13004                    // TODO: sub-sample into EventLog for these, with
13005                    // the info.durationMillis?  Then we'd get
13006                    // the relative pain numbers, without logging all
13007                    // the stack traces repeatedly.  We'd want to do
13008                    // likewise in the client code, which also does
13009                    // dup suppression, before the Binder call.
13010                } else {
13011                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13012                        mAlreadyLoggedViolatedStacks.clear();
13013                    }
13014                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13015                }
13016            }
13017            if (logIt) {
13018                logStrictModeViolationToDropBox(r, info);
13019            }
13020        }
13021
13022        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13023            AppErrorResult result = new AppErrorResult();
13024            synchronized (this) {
13025                final long origId = Binder.clearCallingIdentity();
13026
13027                Message msg = Message.obtain();
13028                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13029                HashMap<String, Object> data = new HashMap<String, Object>();
13030                data.put("result", result);
13031                data.put("app", r);
13032                data.put("violationMask", violationMask);
13033                data.put("info", info);
13034                msg.obj = data;
13035                mUiHandler.sendMessage(msg);
13036
13037                Binder.restoreCallingIdentity(origId);
13038            }
13039            int res = result.get();
13040            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13041        }
13042    }
13043
13044    // Depending on the policy in effect, there could be a bunch of
13045    // these in quick succession so we try to batch these together to
13046    // minimize disk writes, number of dropbox entries, and maximize
13047    // compression, by having more fewer, larger records.
13048    private void logStrictModeViolationToDropBox(
13049            ProcessRecord process,
13050            StrictMode.ViolationInfo info) {
13051        if (info == null) {
13052            return;
13053        }
13054        final boolean isSystemApp = process == null ||
13055                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13056                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13057        final String processName = process == null ? "unknown" : process.processName;
13058        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13059        final DropBoxManager dbox = (DropBoxManager)
13060                mContext.getSystemService(Context.DROPBOX_SERVICE);
13061
13062        // Exit early if the dropbox isn't configured to accept this report type.
13063        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13064
13065        boolean bufferWasEmpty;
13066        boolean needsFlush;
13067        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13068        synchronized (sb) {
13069            bufferWasEmpty = sb.length() == 0;
13070            appendDropBoxProcessHeaders(process, processName, sb);
13071            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13072            sb.append("System-App: ").append(isSystemApp).append("\n");
13073            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13074            if (info.violationNumThisLoop != 0) {
13075                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13076            }
13077            if (info.numAnimationsRunning != 0) {
13078                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13079            }
13080            if (info.broadcastIntentAction != null) {
13081                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13082            }
13083            if (info.durationMillis != -1) {
13084                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13085            }
13086            if (info.numInstances != -1) {
13087                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13088            }
13089            if (info.tags != null) {
13090                for (String tag : info.tags) {
13091                    sb.append("Span-Tag: ").append(tag).append("\n");
13092                }
13093            }
13094            sb.append("\n");
13095            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13096                sb.append(info.crashInfo.stackTrace);
13097                sb.append("\n");
13098            }
13099            if (info.message != null) {
13100                sb.append(info.message);
13101                sb.append("\n");
13102            }
13103
13104            // Only buffer up to ~64k.  Various logging bits truncate
13105            // things at 128k.
13106            needsFlush = (sb.length() > 64 * 1024);
13107        }
13108
13109        // Flush immediately if the buffer's grown too large, or this
13110        // is a non-system app.  Non-system apps are isolated with a
13111        // different tag & policy and not batched.
13112        //
13113        // Batching is useful during internal testing with
13114        // StrictMode settings turned up high.  Without batching,
13115        // thousands of separate files could be created on boot.
13116        if (!isSystemApp || needsFlush) {
13117            new Thread("Error dump: " + dropboxTag) {
13118                @Override
13119                public void run() {
13120                    String report;
13121                    synchronized (sb) {
13122                        report = sb.toString();
13123                        sb.delete(0, sb.length());
13124                        sb.trimToSize();
13125                    }
13126                    if (report.length() != 0) {
13127                        dbox.addText(dropboxTag, report);
13128                    }
13129                }
13130            }.start();
13131            return;
13132        }
13133
13134        // System app batching:
13135        if (!bufferWasEmpty) {
13136            // An existing dropbox-writing thread is outstanding, so
13137            // we don't need to start it up.  The existing thread will
13138            // catch the buffer appends we just did.
13139            return;
13140        }
13141
13142        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13143        // (After this point, we shouldn't access AMS internal data structures.)
13144        new Thread("Error dump: " + dropboxTag) {
13145            @Override
13146            public void run() {
13147                // 5 second sleep to let stacks arrive and be batched together
13148                try {
13149                    Thread.sleep(5000);  // 5 seconds
13150                } catch (InterruptedException e) {}
13151
13152                String errorReport;
13153                synchronized (mStrictModeBuffer) {
13154                    errorReport = mStrictModeBuffer.toString();
13155                    if (errorReport.length() == 0) {
13156                        return;
13157                    }
13158                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13159                    mStrictModeBuffer.trimToSize();
13160                }
13161                dbox.addText(dropboxTag, errorReport);
13162            }
13163        }.start();
13164    }
13165
13166    /**
13167     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13168     * @param app object of the crashing app, null for the system server
13169     * @param tag reported by the caller
13170     * @param system whether this wtf is coming from the system
13171     * @param crashInfo describing the context of the error
13172     * @return true if the process should exit immediately (WTF is fatal)
13173     */
13174    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13175            final ApplicationErrorReport.CrashInfo crashInfo) {
13176        final int callingUid = Binder.getCallingUid();
13177        final int callingPid = Binder.getCallingPid();
13178
13179        if (system) {
13180            // If this is coming from the system, we could very well have low-level
13181            // system locks held, so we want to do this all asynchronously.  And we
13182            // never want this to become fatal, so there is that too.
13183            mHandler.post(new Runnable() {
13184                @Override public void run() {
13185                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13186                }
13187            });
13188            return false;
13189        }
13190
13191        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13192                crashInfo);
13193
13194        if (r != null && r.pid != Process.myPid() &&
13195                Settings.Global.getInt(mContext.getContentResolver(),
13196                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13197            mAppErrors.crashApplication(r, crashInfo);
13198            return true;
13199        } else {
13200            return false;
13201        }
13202    }
13203
13204    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13205            final ApplicationErrorReport.CrashInfo crashInfo) {
13206        final ProcessRecord r = findAppProcess(app, "WTF");
13207        final String processName = app == null ? "system_server"
13208                : (r == null ? "unknown" : r.processName);
13209
13210        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13211                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13212
13213        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13214
13215        return r;
13216    }
13217
13218    /**
13219     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13220     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13221     */
13222    private ProcessRecord findAppProcess(IBinder app, String reason) {
13223        if (app == null) {
13224            return null;
13225        }
13226
13227        synchronized (this) {
13228            final int NP = mProcessNames.getMap().size();
13229            for (int ip=0; ip<NP; ip++) {
13230                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13231                final int NA = apps.size();
13232                for (int ia=0; ia<NA; ia++) {
13233                    ProcessRecord p = apps.valueAt(ia);
13234                    if (p.thread != null && p.thread.asBinder() == app) {
13235                        return p;
13236                    }
13237                }
13238            }
13239
13240            Slog.w(TAG, "Can't find mystery application for " + reason
13241                    + " from pid=" + Binder.getCallingPid()
13242                    + " uid=" + Binder.getCallingUid() + ": " + app);
13243            return null;
13244        }
13245    }
13246
13247    /**
13248     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13249     * to append various headers to the dropbox log text.
13250     */
13251    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13252            StringBuilder sb) {
13253        // Watchdog thread ends up invoking this function (with
13254        // a null ProcessRecord) to add the stack file to dropbox.
13255        // Do not acquire a lock on this (am) in such cases, as it
13256        // could cause a potential deadlock, if and when watchdog
13257        // is invoked due to unavailability of lock on am and it
13258        // would prevent watchdog from killing system_server.
13259        if (process == null) {
13260            sb.append("Process: ").append(processName).append("\n");
13261            return;
13262        }
13263        // Note: ProcessRecord 'process' is guarded by the service
13264        // instance.  (notably process.pkgList, which could otherwise change
13265        // concurrently during execution of this method)
13266        synchronized (this) {
13267            sb.append("Process: ").append(processName).append("\n");
13268            int flags = process.info.flags;
13269            IPackageManager pm = AppGlobals.getPackageManager();
13270            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13271            for (int ip=0; ip<process.pkgList.size(); ip++) {
13272                String pkg = process.pkgList.keyAt(ip);
13273                sb.append("Package: ").append(pkg);
13274                try {
13275                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13276                    if (pi != null) {
13277                        sb.append(" v").append(pi.versionCode);
13278                        if (pi.versionName != null) {
13279                            sb.append(" (").append(pi.versionName).append(")");
13280                        }
13281                    }
13282                } catch (RemoteException e) {
13283                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13284                }
13285                sb.append("\n");
13286            }
13287        }
13288    }
13289
13290    private static String processClass(ProcessRecord process) {
13291        if (process == null || process.pid == MY_PID) {
13292            return "system_server";
13293        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13294            return "system_app";
13295        } else {
13296            return "data_app";
13297        }
13298    }
13299
13300    private volatile long mWtfClusterStart;
13301    private volatile int mWtfClusterCount;
13302
13303    /**
13304     * Write a description of an error (crash, WTF, ANR) to the drop box.
13305     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13306     * @param process which caused the error, null means the system server
13307     * @param activity which triggered the error, null if unknown
13308     * @param parent activity related to the error, null if unknown
13309     * @param subject line related to the error, null if absent
13310     * @param report in long form describing the error, null if absent
13311     * @param logFile to include in the report, null if none
13312     * @param crashInfo giving an application stack trace, null if absent
13313     */
13314    public void addErrorToDropBox(String eventType,
13315            ProcessRecord process, String processName, ActivityRecord activity,
13316            ActivityRecord parent, String subject,
13317            final String report, final File logFile,
13318            final ApplicationErrorReport.CrashInfo crashInfo) {
13319        // NOTE -- this must never acquire the ActivityManagerService lock,
13320        // otherwise the watchdog may be prevented from resetting the system.
13321
13322        final String dropboxTag = processClass(process) + "_" + eventType;
13323        final DropBoxManager dbox = (DropBoxManager)
13324                mContext.getSystemService(Context.DROPBOX_SERVICE);
13325
13326        // Exit early if the dropbox isn't configured to accept this report type.
13327        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13328
13329        // Rate-limit how often we're willing to do the heavy lifting below to
13330        // collect and record logs; currently 5 logs per 10 second period.
13331        final long now = SystemClock.elapsedRealtime();
13332        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13333            mWtfClusterStart = now;
13334            mWtfClusterCount = 1;
13335        } else {
13336            if (mWtfClusterCount++ >= 5) return;
13337        }
13338
13339        final StringBuilder sb = new StringBuilder(1024);
13340        appendDropBoxProcessHeaders(process, processName, sb);
13341        if (process != null) {
13342            sb.append("Foreground: ")
13343                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13344                    .append("\n");
13345        }
13346        if (activity != null) {
13347            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13348        }
13349        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13350            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13351        }
13352        if (parent != null && parent != activity) {
13353            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13354        }
13355        if (subject != null) {
13356            sb.append("Subject: ").append(subject).append("\n");
13357        }
13358        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13359        if (Debug.isDebuggerConnected()) {
13360            sb.append("Debugger: Connected\n");
13361        }
13362        sb.append("\n");
13363
13364        // Do the rest in a worker thread to avoid blocking the caller on I/O
13365        // (After this point, we shouldn't access AMS internal data structures.)
13366        Thread worker = new Thread("Error dump: " + dropboxTag) {
13367            @Override
13368            public void run() {
13369                if (report != null) {
13370                    sb.append(report);
13371                }
13372                if (logFile != null) {
13373                    try {
13374                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13375                                    "\n\n[[TRUNCATED]]"));
13376                    } catch (IOException e) {
13377                        Slog.e(TAG, "Error reading " + logFile, e);
13378                    }
13379                }
13380                if (crashInfo != null && crashInfo.stackTrace != null) {
13381                    sb.append(crashInfo.stackTrace);
13382                }
13383
13384                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13385                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13386                if (lines > 0) {
13387                    sb.append("\n");
13388
13389                    // Merge several logcat streams, and take the last N lines
13390                    InputStreamReader input = null;
13391                    try {
13392                        java.lang.Process logcat = new ProcessBuilder(
13393                                "/system/bin/timeout", "-k", "15s", "10s",
13394                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13395                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13396                                        .redirectErrorStream(true).start();
13397
13398                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13399                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13400                        input = new InputStreamReader(logcat.getInputStream());
13401
13402                        int num;
13403                        char[] buf = new char[8192];
13404                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13405                    } catch (IOException e) {
13406                        Slog.e(TAG, "Error running logcat", e);
13407                    } finally {
13408                        if (input != null) try { input.close(); } catch (IOException e) {}
13409                    }
13410                }
13411
13412                dbox.addText(dropboxTag, sb.toString());
13413            }
13414        };
13415
13416        if (process == null) {
13417            // If process is null, we are being called from some internal code
13418            // and may be about to die -- run this synchronously.
13419            worker.run();
13420        } else {
13421            worker.start();
13422        }
13423    }
13424
13425    @Override
13426    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13427        enforceNotIsolatedCaller("getProcessesInErrorState");
13428        // assume our apps are happy - lazy create the list
13429        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13430
13431        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13432                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13433        int userId = UserHandle.getUserId(Binder.getCallingUid());
13434
13435        synchronized (this) {
13436
13437            // iterate across all processes
13438            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13439                ProcessRecord app = mLruProcesses.get(i);
13440                if (!allUsers && app.userId != userId) {
13441                    continue;
13442                }
13443                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13444                    // This one's in trouble, so we'll generate a report for it
13445                    // crashes are higher priority (in case there's a crash *and* an anr)
13446                    ActivityManager.ProcessErrorStateInfo report = null;
13447                    if (app.crashing) {
13448                        report = app.crashingReport;
13449                    } else if (app.notResponding) {
13450                        report = app.notRespondingReport;
13451                    }
13452
13453                    if (report != null) {
13454                        if (errList == null) {
13455                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13456                        }
13457                        errList.add(report);
13458                    } else {
13459                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13460                                " crashing = " + app.crashing +
13461                                " notResponding = " + app.notResponding);
13462                    }
13463                }
13464            }
13465        }
13466
13467        return errList;
13468    }
13469
13470    static int procStateToImportance(int procState, int memAdj,
13471            ActivityManager.RunningAppProcessInfo currApp) {
13472        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13473        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13474            currApp.lru = memAdj;
13475        } else {
13476            currApp.lru = 0;
13477        }
13478        return imp;
13479    }
13480
13481    private void fillInProcMemInfo(ProcessRecord app,
13482            ActivityManager.RunningAppProcessInfo outInfo) {
13483        outInfo.pid = app.pid;
13484        outInfo.uid = app.info.uid;
13485        if (mHeavyWeightProcess == app) {
13486            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13487        }
13488        if (app.persistent) {
13489            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13490        }
13491        if (app.activities.size() > 0) {
13492            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13493        }
13494        outInfo.lastTrimLevel = app.trimMemoryLevel;
13495        int adj = app.curAdj;
13496        int procState = app.curProcState;
13497        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13498        outInfo.importanceReasonCode = app.adjTypeCode;
13499        outInfo.processState = app.curProcState;
13500    }
13501
13502    @Override
13503    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13504        enforceNotIsolatedCaller("getRunningAppProcesses");
13505
13506        final int callingUid = Binder.getCallingUid();
13507
13508        // Lazy instantiation of list
13509        List<ActivityManager.RunningAppProcessInfo> runList = null;
13510        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13511                callingUid) == PackageManager.PERMISSION_GRANTED;
13512        final int userId = UserHandle.getUserId(callingUid);
13513        final boolean allUids = isGetTasksAllowed(
13514                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13515
13516        synchronized (this) {
13517            // Iterate across all processes
13518            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13519                ProcessRecord app = mLruProcesses.get(i);
13520                if ((!allUsers && app.userId != userId)
13521                        || (!allUids && app.uid != callingUid)) {
13522                    continue;
13523                }
13524                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13525                    // Generate process state info for running application
13526                    ActivityManager.RunningAppProcessInfo currApp =
13527                        new ActivityManager.RunningAppProcessInfo(app.processName,
13528                                app.pid, app.getPackageList());
13529                    fillInProcMemInfo(app, currApp);
13530                    if (app.adjSource instanceof ProcessRecord) {
13531                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13532                        currApp.importanceReasonImportance =
13533                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13534                                        app.adjSourceProcState);
13535                    } else if (app.adjSource instanceof ActivityRecord) {
13536                        ActivityRecord r = (ActivityRecord)app.adjSource;
13537                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13538                    }
13539                    if (app.adjTarget instanceof ComponentName) {
13540                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13541                    }
13542                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13543                    //        + " lru=" + currApp.lru);
13544                    if (runList == null) {
13545                        runList = new ArrayList<>();
13546                    }
13547                    runList.add(currApp);
13548                }
13549            }
13550        }
13551        return runList;
13552    }
13553
13554    @Override
13555    public List<ApplicationInfo> getRunningExternalApplications() {
13556        enforceNotIsolatedCaller("getRunningExternalApplications");
13557        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13558        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13559        if (runningApps != null && runningApps.size() > 0) {
13560            Set<String> extList = new HashSet<String>();
13561            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13562                if (app.pkgList != null) {
13563                    for (String pkg : app.pkgList) {
13564                        extList.add(pkg);
13565                    }
13566                }
13567            }
13568            IPackageManager pm = AppGlobals.getPackageManager();
13569            for (String pkg : extList) {
13570                try {
13571                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13572                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13573                        retList.add(info);
13574                    }
13575                } catch (RemoteException e) {
13576                }
13577            }
13578        }
13579        return retList;
13580    }
13581
13582    @Override
13583    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13584        enforceNotIsolatedCaller("getMyMemoryState");
13585        synchronized (this) {
13586            ProcessRecord proc;
13587            synchronized (mPidsSelfLocked) {
13588                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13589            }
13590            fillInProcMemInfo(proc, outInfo);
13591        }
13592    }
13593
13594    @Override
13595    public int getMemoryTrimLevel() {
13596        enforceNotIsolatedCaller("getMyMemoryState");
13597        synchronized (this) {
13598            return mLastMemoryLevel;
13599        }
13600    }
13601
13602    @Override
13603    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13604            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13605        (new ActivityManagerShellCommand(this, false)).exec(
13606                this, in, out, err, args, resultReceiver);
13607    }
13608
13609    @Override
13610    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13611        if (checkCallingPermission(android.Manifest.permission.DUMP)
13612                != PackageManager.PERMISSION_GRANTED) {
13613            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13614                    + Binder.getCallingPid()
13615                    + ", uid=" + Binder.getCallingUid()
13616                    + " without permission "
13617                    + android.Manifest.permission.DUMP);
13618            return;
13619        }
13620
13621        boolean dumpAll = false;
13622        boolean dumpClient = false;
13623        String dumpPackage = null;
13624
13625        int opti = 0;
13626        while (opti < args.length) {
13627            String opt = args[opti];
13628            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13629                break;
13630            }
13631            opti++;
13632            if ("-a".equals(opt)) {
13633                dumpAll = true;
13634            } else if ("-c".equals(opt)) {
13635                dumpClient = true;
13636            } else if ("-p".equals(opt)) {
13637                if (opti < args.length) {
13638                    dumpPackage = args[opti];
13639                    opti++;
13640                } else {
13641                    pw.println("Error: -p option requires package argument");
13642                    return;
13643                }
13644                dumpClient = true;
13645            } else if ("-h".equals(opt)) {
13646                ActivityManagerShellCommand.dumpHelp(pw, true);
13647                return;
13648            } else {
13649                pw.println("Unknown argument: " + opt + "; use -h for help");
13650            }
13651        }
13652
13653        long origId = Binder.clearCallingIdentity();
13654        boolean more = false;
13655        // Is the caller requesting to dump a particular piece of data?
13656        if (opti < args.length) {
13657            String cmd = args[opti];
13658            opti++;
13659            if ("activities".equals(cmd) || "a".equals(cmd)) {
13660                synchronized (this) {
13661                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13662                }
13663            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13664                synchronized (this) {
13665                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13666                }
13667            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13668                String[] newArgs;
13669                String name;
13670                if (opti >= args.length) {
13671                    name = null;
13672                    newArgs = EMPTY_STRING_ARRAY;
13673                } else {
13674                    dumpPackage = args[opti];
13675                    opti++;
13676                    newArgs = new String[args.length - opti];
13677                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13678                            args.length - opti);
13679                }
13680                synchronized (this) {
13681                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13682                }
13683            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13684                String[] newArgs;
13685                String name;
13686                if (opti >= args.length) {
13687                    name = null;
13688                    newArgs = EMPTY_STRING_ARRAY;
13689                } else {
13690                    dumpPackage = args[opti];
13691                    opti++;
13692                    newArgs = new String[args.length - opti];
13693                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13694                            args.length - opti);
13695                }
13696                synchronized (this) {
13697                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13698                }
13699            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13700                String[] newArgs;
13701                String name;
13702                if (opti >= args.length) {
13703                    name = null;
13704                    newArgs = EMPTY_STRING_ARRAY;
13705                } else {
13706                    dumpPackage = args[opti];
13707                    opti++;
13708                    newArgs = new String[args.length - opti];
13709                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13710                            args.length - opti);
13711                }
13712                synchronized (this) {
13713                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13714                }
13715            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13716                synchronized (this) {
13717                    dumpOomLocked(fd, pw, args, opti, true);
13718                }
13719            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13720                synchronized (this) {
13721                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13722                }
13723            } else if ("provider".equals(cmd)) {
13724                String[] newArgs;
13725                String name;
13726                if (opti >= args.length) {
13727                    name = null;
13728                    newArgs = EMPTY_STRING_ARRAY;
13729                } else {
13730                    name = args[opti];
13731                    opti++;
13732                    newArgs = new String[args.length - opti];
13733                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13734                }
13735                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13736                    pw.println("No providers match: " + name);
13737                    pw.println("Use -h for help.");
13738                }
13739            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13740                synchronized (this) {
13741                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13742                }
13743            } else if ("service".equals(cmd)) {
13744                String[] newArgs;
13745                String name;
13746                if (opti >= args.length) {
13747                    name = null;
13748                    newArgs = EMPTY_STRING_ARRAY;
13749                } else {
13750                    name = args[opti];
13751                    opti++;
13752                    newArgs = new String[args.length - opti];
13753                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13754                            args.length - opti);
13755                }
13756                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13757                    pw.println("No services match: " + name);
13758                    pw.println("Use -h for help.");
13759                }
13760            } else if ("package".equals(cmd)) {
13761                String[] newArgs;
13762                if (opti >= args.length) {
13763                    pw.println("package: no package name specified");
13764                    pw.println("Use -h for help.");
13765                } else {
13766                    dumpPackage = args[opti];
13767                    opti++;
13768                    newArgs = new String[args.length - opti];
13769                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13770                            args.length - opti);
13771                    args = newArgs;
13772                    opti = 0;
13773                    more = true;
13774                }
13775            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13776                synchronized (this) {
13777                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13778                }
13779            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13780                synchronized (this) {
13781                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13782                }
13783            } else if ("locks".equals(cmd)) {
13784                LockGuard.dump(fd, pw, args);
13785            } else {
13786                // Dumping a single activity?
13787                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13788                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13789                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13790                    if (res < 0) {
13791                        pw.println("Bad activity command, or no activities match: " + cmd);
13792                        pw.println("Use -h for help.");
13793                    }
13794                }
13795            }
13796            if (!more) {
13797                Binder.restoreCallingIdentity(origId);
13798                return;
13799            }
13800        }
13801
13802        // No piece of data specified, dump everything.
13803        synchronized (this) {
13804            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13805            pw.println();
13806            if (dumpAll) {
13807                pw.println("-------------------------------------------------------------------------------");
13808            }
13809            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13810            pw.println();
13811            if (dumpAll) {
13812                pw.println("-------------------------------------------------------------------------------");
13813            }
13814            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13815            pw.println();
13816            if (dumpAll) {
13817                pw.println("-------------------------------------------------------------------------------");
13818            }
13819            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13820            pw.println();
13821            if (dumpAll) {
13822                pw.println("-------------------------------------------------------------------------------");
13823            }
13824            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13825            pw.println();
13826            if (dumpAll) {
13827                pw.println("-------------------------------------------------------------------------------");
13828            }
13829            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13830            pw.println();
13831            if (dumpAll) {
13832                pw.println("-------------------------------------------------------------------------------");
13833            }
13834            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13835            if (mAssociations.size() > 0) {
13836                pw.println();
13837                if (dumpAll) {
13838                    pw.println("-------------------------------------------------------------------------------");
13839                }
13840                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13841            }
13842            pw.println();
13843            if (dumpAll) {
13844                pw.println("-------------------------------------------------------------------------------");
13845            }
13846            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13847        }
13848        Binder.restoreCallingIdentity(origId);
13849    }
13850
13851    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13852            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13853        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13854
13855        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13856                dumpPackage);
13857        boolean needSep = printedAnything;
13858
13859        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13860                dumpPackage, needSep, "  mFocusedActivity: ");
13861        if (printed) {
13862            printedAnything = true;
13863            needSep = false;
13864        }
13865
13866        if (dumpPackage == null) {
13867            if (needSep) {
13868                pw.println();
13869            }
13870            needSep = true;
13871            printedAnything = true;
13872            mStackSupervisor.dump(pw, "  ");
13873        }
13874
13875        if (!printedAnything) {
13876            pw.println("  (nothing)");
13877        }
13878    }
13879
13880    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13881            int opti, boolean dumpAll, String dumpPackage) {
13882        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13883
13884        boolean printedAnything = false;
13885
13886        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13887            boolean printedHeader = false;
13888
13889            final int N = mRecentTasks.size();
13890            for (int i=0; i<N; i++) {
13891                TaskRecord tr = mRecentTasks.get(i);
13892                if (dumpPackage != null) {
13893                    if (tr.realActivity == null ||
13894                            !dumpPackage.equals(tr.realActivity)) {
13895                        continue;
13896                    }
13897                }
13898                if (!printedHeader) {
13899                    pw.println("  Recent tasks:");
13900                    printedHeader = true;
13901                    printedAnything = true;
13902                }
13903                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13904                        pw.println(tr);
13905                if (dumpAll) {
13906                    mRecentTasks.get(i).dump(pw, "    ");
13907                }
13908            }
13909        }
13910
13911        if (!printedAnything) {
13912            pw.println("  (nothing)");
13913        }
13914    }
13915
13916    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13917            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13918        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13919
13920        int dumpUid = 0;
13921        if (dumpPackage != null) {
13922            IPackageManager pm = AppGlobals.getPackageManager();
13923            try {
13924                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13925            } catch (RemoteException e) {
13926            }
13927        }
13928
13929        boolean printedAnything = false;
13930
13931        final long now = SystemClock.uptimeMillis();
13932
13933        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13934            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13935                    = mAssociations.valueAt(i1);
13936            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13937                SparseArray<ArrayMap<String, Association>> sourceUids
13938                        = targetComponents.valueAt(i2);
13939                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13940                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13941                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13942                        Association ass = sourceProcesses.valueAt(i4);
13943                        if (dumpPackage != null) {
13944                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13945                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13946                                continue;
13947                            }
13948                        }
13949                        printedAnything = true;
13950                        pw.print("  ");
13951                        pw.print(ass.mTargetProcess);
13952                        pw.print("/");
13953                        UserHandle.formatUid(pw, ass.mTargetUid);
13954                        pw.print(" <- ");
13955                        pw.print(ass.mSourceProcess);
13956                        pw.print("/");
13957                        UserHandle.formatUid(pw, ass.mSourceUid);
13958                        pw.println();
13959                        pw.print("    via ");
13960                        pw.print(ass.mTargetComponent.flattenToShortString());
13961                        pw.println();
13962                        pw.print("    ");
13963                        long dur = ass.mTime;
13964                        if (ass.mNesting > 0) {
13965                            dur += now - ass.mStartTime;
13966                        }
13967                        TimeUtils.formatDuration(dur, pw);
13968                        pw.print(" (");
13969                        pw.print(ass.mCount);
13970                        pw.print(" times)");
13971                        pw.print("  ");
13972                        for (int i=0; i<ass.mStateTimes.length; i++) {
13973                            long amt = ass.mStateTimes[i];
13974                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13975                                amt += now - ass.mLastStateUptime;
13976                            }
13977                            if (amt != 0) {
13978                                pw.print(" ");
13979                                pw.print(ProcessList.makeProcStateString(
13980                                            i + ActivityManager.MIN_PROCESS_STATE));
13981                                pw.print("=");
13982                                TimeUtils.formatDuration(amt, pw);
13983                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13984                                    pw.print("*");
13985                                }
13986                            }
13987                        }
13988                        pw.println();
13989                        if (ass.mNesting > 0) {
13990                            pw.print("    Currently active: ");
13991                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13992                            pw.println();
13993                        }
13994                    }
13995                }
13996            }
13997
13998        }
13999
14000        if (!printedAnything) {
14001            pw.println("  (nothing)");
14002        }
14003    }
14004
14005    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14006            String header, boolean needSep) {
14007        boolean printed = false;
14008        int whichAppId = -1;
14009        if (dumpPackage != null) {
14010            try {
14011                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14012                        dumpPackage, 0);
14013                whichAppId = UserHandle.getAppId(info.uid);
14014            } catch (NameNotFoundException e) {
14015                e.printStackTrace();
14016            }
14017        }
14018        for (int i=0; i<uids.size(); i++) {
14019            UidRecord uidRec = uids.valueAt(i);
14020            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14021                continue;
14022            }
14023            if (!printed) {
14024                printed = true;
14025                if (needSep) {
14026                    pw.println();
14027                }
14028                pw.print("  ");
14029                pw.println(header);
14030                needSep = true;
14031            }
14032            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14033            pw.print(": "); pw.println(uidRec);
14034        }
14035        return printed;
14036    }
14037
14038    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14039            int opti, boolean dumpAll, String dumpPackage) {
14040        boolean needSep = false;
14041        boolean printedAnything = false;
14042        int numPers = 0;
14043
14044        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14045
14046        if (dumpAll) {
14047            final int NP = mProcessNames.getMap().size();
14048            for (int ip=0; ip<NP; ip++) {
14049                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14050                final int NA = procs.size();
14051                for (int ia=0; ia<NA; ia++) {
14052                    ProcessRecord r = procs.valueAt(ia);
14053                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14054                        continue;
14055                    }
14056                    if (!needSep) {
14057                        pw.println("  All known processes:");
14058                        needSep = true;
14059                        printedAnything = true;
14060                    }
14061                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14062                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14063                        pw.print(" "); pw.println(r);
14064                    r.dump(pw, "    ");
14065                    if (r.persistent) {
14066                        numPers++;
14067                    }
14068                }
14069            }
14070        }
14071
14072        if (mIsolatedProcesses.size() > 0) {
14073            boolean printed = false;
14074            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14075                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14076                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14077                    continue;
14078                }
14079                if (!printed) {
14080                    if (needSep) {
14081                        pw.println();
14082                    }
14083                    pw.println("  Isolated process list (sorted by uid):");
14084                    printedAnything = true;
14085                    printed = true;
14086                    needSep = true;
14087                }
14088                pw.println(String.format("%sIsolated #%2d: %s",
14089                        "    ", i, r.toString()));
14090            }
14091        }
14092
14093        if (mActiveUids.size() > 0) {
14094            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14095                printedAnything = needSep = true;
14096            }
14097        }
14098        if (mValidateUids.size() > 0) {
14099            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14100                printedAnything = needSep = true;
14101            }
14102        }
14103
14104        if (mLruProcesses.size() > 0) {
14105            if (needSep) {
14106                pw.println();
14107            }
14108            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14109                    pw.print(" total, non-act at ");
14110                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14111                    pw.print(", non-svc at ");
14112                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14113                    pw.println("):");
14114            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14115            needSep = true;
14116            printedAnything = true;
14117        }
14118
14119        if (dumpAll || dumpPackage != null) {
14120            synchronized (mPidsSelfLocked) {
14121                boolean printed = false;
14122                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14123                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14124                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14125                        continue;
14126                    }
14127                    if (!printed) {
14128                        if (needSep) pw.println();
14129                        needSep = true;
14130                        pw.println("  PID mappings:");
14131                        printed = true;
14132                        printedAnything = true;
14133                    }
14134                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14135                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14136                }
14137            }
14138        }
14139
14140        if (mForegroundProcesses.size() > 0) {
14141            synchronized (mPidsSelfLocked) {
14142                boolean printed = false;
14143                for (int i=0; i<mForegroundProcesses.size(); i++) {
14144                    ProcessRecord r = mPidsSelfLocked.get(
14145                            mForegroundProcesses.valueAt(i).pid);
14146                    if (dumpPackage != null && (r == null
14147                            || !r.pkgList.containsKey(dumpPackage))) {
14148                        continue;
14149                    }
14150                    if (!printed) {
14151                        if (needSep) pw.println();
14152                        needSep = true;
14153                        pw.println("  Foreground Processes:");
14154                        printed = true;
14155                        printedAnything = true;
14156                    }
14157                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14158                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14159                }
14160            }
14161        }
14162
14163        if (mPersistentStartingProcesses.size() > 0) {
14164            if (needSep) pw.println();
14165            needSep = true;
14166            printedAnything = true;
14167            pw.println("  Persisent processes that are starting:");
14168            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14169                    "Starting Norm", "Restarting PERS", dumpPackage);
14170        }
14171
14172        if (mRemovedProcesses.size() > 0) {
14173            if (needSep) pw.println();
14174            needSep = true;
14175            printedAnything = true;
14176            pw.println("  Processes that are being removed:");
14177            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14178                    "Removed Norm", "Removed PERS", dumpPackage);
14179        }
14180
14181        if (mProcessesOnHold.size() > 0) {
14182            if (needSep) pw.println();
14183            needSep = true;
14184            printedAnything = true;
14185            pw.println("  Processes that are on old until the system is ready:");
14186            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14187                    "OnHold Norm", "OnHold PERS", dumpPackage);
14188        }
14189
14190        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14191
14192        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14193        if (needSep) {
14194            printedAnything = true;
14195        }
14196
14197        if (dumpPackage == null) {
14198            pw.println();
14199            needSep = false;
14200            mUserController.dump(pw, dumpAll);
14201        }
14202        if (mHomeProcess != null && (dumpPackage == null
14203                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14204            if (needSep) {
14205                pw.println();
14206                needSep = false;
14207            }
14208            pw.println("  mHomeProcess: " + mHomeProcess);
14209        }
14210        if (mPreviousProcess != null && (dumpPackage == null
14211                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14212            if (needSep) {
14213                pw.println();
14214                needSep = false;
14215            }
14216            pw.println("  mPreviousProcess: " + mPreviousProcess);
14217        }
14218        if (dumpAll) {
14219            StringBuilder sb = new StringBuilder(128);
14220            sb.append("  mPreviousProcessVisibleTime: ");
14221            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14222            pw.println(sb);
14223        }
14224        if (mHeavyWeightProcess != null && (dumpPackage == null
14225                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14226            if (needSep) {
14227                pw.println();
14228                needSep = false;
14229            }
14230            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14231        }
14232        if (dumpPackage == null) {
14233            pw.println("  mConfiguration: " + mConfiguration);
14234        }
14235        if (dumpAll) {
14236            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14237            if (mCompatModePackages.getPackages().size() > 0) {
14238                boolean printed = false;
14239                for (Map.Entry<String, Integer> entry
14240                        : mCompatModePackages.getPackages().entrySet()) {
14241                    String pkg = entry.getKey();
14242                    int mode = entry.getValue();
14243                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14244                        continue;
14245                    }
14246                    if (!printed) {
14247                        pw.println("  mScreenCompatPackages:");
14248                        printed = true;
14249                    }
14250                    pw.print("    "); pw.print(pkg); pw.print(": ");
14251                            pw.print(mode); pw.println();
14252                }
14253            }
14254        }
14255        if (dumpPackage == null) {
14256            pw.println("  mWakefulness="
14257                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14258            pw.println("  mSleepTokens=" + mSleepTokens);
14259            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14260                    + lockScreenShownToString());
14261            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14262            if (mRunningVoice != null) {
14263                pw.println("  mRunningVoice=" + mRunningVoice);
14264                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14265            }
14266        }
14267        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14268                || mOrigWaitForDebugger) {
14269            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14270                    || dumpPackage.equals(mOrigDebugApp)) {
14271                if (needSep) {
14272                    pw.println();
14273                    needSep = false;
14274                }
14275                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14276                        + " mDebugTransient=" + mDebugTransient
14277                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14278            }
14279        }
14280        if (mCurAppTimeTracker != null) {
14281            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14282        }
14283        if (mMemWatchProcesses.getMap().size() > 0) {
14284            pw.println("  Mem watch processes:");
14285            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14286                    = mMemWatchProcesses.getMap();
14287            for (int i=0; i<procs.size(); i++) {
14288                final String proc = procs.keyAt(i);
14289                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14290                for (int j=0; j<uids.size(); j++) {
14291                    if (needSep) {
14292                        pw.println();
14293                        needSep = false;
14294                    }
14295                    StringBuilder sb = new StringBuilder();
14296                    sb.append("    ").append(proc).append('/');
14297                    UserHandle.formatUid(sb, uids.keyAt(j));
14298                    Pair<Long, String> val = uids.valueAt(j);
14299                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14300                    if (val.second != null) {
14301                        sb.append(", report to ").append(val.second);
14302                    }
14303                    pw.println(sb.toString());
14304                }
14305            }
14306            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14307            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14308            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14309                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14310        }
14311        if (mTrackAllocationApp != null) {
14312            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14313                if (needSep) {
14314                    pw.println();
14315                    needSep = false;
14316                }
14317                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14318            }
14319        }
14320        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14321                || mProfileFd != null) {
14322            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14323                if (needSep) {
14324                    pw.println();
14325                    needSep = false;
14326                }
14327                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14328                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14329                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14330                        + mAutoStopProfiler);
14331                pw.println("  mProfileType=" + mProfileType);
14332            }
14333        }
14334        if (mNativeDebuggingApp != null) {
14335            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14336                if (needSep) {
14337                    pw.println();
14338                    needSep = false;
14339                }
14340                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14341            }
14342        }
14343        if (dumpPackage == null) {
14344            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14345                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14346                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14347            }
14348            if (mController != null) {
14349                pw.println("  mController=" + mController
14350                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14351            }
14352            if (dumpAll) {
14353                pw.println("  Total persistent processes: " + numPers);
14354                pw.println("  mProcessesReady=" + mProcessesReady
14355                        + " mSystemReady=" + mSystemReady
14356                        + " mBooted=" + mBooted
14357                        + " mFactoryTest=" + mFactoryTest);
14358                pw.println("  mBooting=" + mBooting
14359                        + " mCallFinishBooting=" + mCallFinishBooting
14360                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14361                pw.print("  mLastPowerCheckRealtime=");
14362                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14363                        pw.println("");
14364                pw.print("  mLastPowerCheckUptime=");
14365                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14366                        pw.println("");
14367                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14368                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14369                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14370                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14371                        + " (" + mLruProcesses.size() + " total)"
14372                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14373                        + " mNumServiceProcs=" + mNumServiceProcs
14374                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14375                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14376                        + " mLastMemoryLevel=" + mLastMemoryLevel
14377                        + " mLastNumProcesses=" + mLastNumProcesses);
14378                long now = SystemClock.uptimeMillis();
14379                pw.print("  mLastIdleTime=");
14380                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14381                        pw.print(" mLowRamSinceLastIdle=");
14382                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14383                        pw.println();
14384            }
14385        }
14386
14387        if (!printedAnything) {
14388            pw.println("  (nothing)");
14389        }
14390    }
14391
14392    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14393            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14394        if (mProcessesToGc.size() > 0) {
14395            boolean printed = false;
14396            long now = SystemClock.uptimeMillis();
14397            for (int i=0; i<mProcessesToGc.size(); i++) {
14398                ProcessRecord proc = mProcessesToGc.get(i);
14399                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14400                    continue;
14401                }
14402                if (!printed) {
14403                    if (needSep) pw.println();
14404                    needSep = true;
14405                    pw.println("  Processes that are waiting to GC:");
14406                    printed = true;
14407                }
14408                pw.print("    Process "); pw.println(proc);
14409                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14410                        pw.print(", last gced=");
14411                        pw.print(now-proc.lastRequestedGc);
14412                        pw.print(" ms ago, last lowMem=");
14413                        pw.print(now-proc.lastLowMemory);
14414                        pw.println(" ms ago");
14415
14416            }
14417        }
14418        return needSep;
14419    }
14420
14421    void printOomLevel(PrintWriter pw, String name, int adj) {
14422        pw.print("    ");
14423        if (adj >= 0) {
14424            pw.print(' ');
14425            if (adj < 10) pw.print(' ');
14426        } else {
14427            if (adj > -10) pw.print(' ');
14428        }
14429        pw.print(adj);
14430        pw.print(": ");
14431        pw.print(name);
14432        pw.print(" (");
14433        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14434        pw.println(")");
14435    }
14436
14437    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14438            int opti, boolean dumpAll) {
14439        boolean needSep = false;
14440
14441        if (mLruProcesses.size() > 0) {
14442            if (needSep) pw.println();
14443            needSep = true;
14444            pw.println("  OOM levels:");
14445            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14446            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14447            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14448            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14449            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14450            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14451            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14452            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14453            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14454            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14455            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14456            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14457            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14458            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14459
14460            if (needSep) pw.println();
14461            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14462                    pw.print(" total, non-act at ");
14463                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14464                    pw.print(", non-svc at ");
14465                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14466                    pw.println("):");
14467            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14468            needSep = true;
14469        }
14470
14471        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14472
14473        pw.println();
14474        pw.println("  mHomeProcess: " + mHomeProcess);
14475        pw.println("  mPreviousProcess: " + mPreviousProcess);
14476        if (mHeavyWeightProcess != null) {
14477            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14478        }
14479
14480        return true;
14481    }
14482
14483    /**
14484     * There are three ways to call this:
14485     *  - no provider specified: dump all the providers
14486     *  - a flattened component name that matched an existing provider was specified as the
14487     *    first arg: dump that one provider
14488     *  - the first arg isn't the flattened component name of an existing provider:
14489     *    dump all providers whose component contains the first arg as a substring
14490     */
14491    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14492            int opti, boolean dumpAll) {
14493        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14494    }
14495
14496    static class ItemMatcher {
14497        ArrayList<ComponentName> components;
14498        ArrayList<String> strings;
14499        ArrayList<Integer> objects;
14500        boolean all;
14501
14502        ItemMatcher() {
14503            all = true;
14504        }
14505
14506        void build(String name) {
14507            ComponentName componentName = ComponentName.unflattenFromString(name);
14508            if (componentName != null) {
14509                if (components == null) {
14510                    components = new ArrayList<ComponentName>();
14511                }
14512                components.add(componentName);
14513                all = false;
14514            } else {
14515                int objectId = 0;
14516                // Not a '/' separated full component name; maybe an object ID?
14517                try {
14518                    objectId = Integer.parseInt(name, 16);
14519                    if (objects == null) {
14520                        objects = new ArrayList<Integer>();
14521                    }
14522                    objects.add(objectId);
14523                    all = false;
14524                } catch (RuntimeException e) {
14525                    // Not an integer; just do string match.
14526                    if (strings == null) {
14527                        strings = new ArrayList<String>();
14528                    }
14529                    strings.add(name);
14530                    all = false;
14531                }
14532            }
14533        }
14534
14535        int build(String[] args, int opti) {
14536            for (; opti<args.length; opti++) {
14537                String name = args[opti];
14538                if ("--".equals(name)) {
14539                    return opti+1;
14540                }
14541                build(name);
14542            }
14543            return opti;
14544        }
14545
14546        boolean match(Object object, ComponentName comp) {
14547            if (all) {
14548                return true;
14549            }
14550            if (components != null) {
14551                for (int i=0; i<components.size(); i++) {
14552                    if (components.get(i).equals(comp)) {
14553                        return true;
14554                    }
14555                }
14556            }
14557            if (objects != null) {
14558                for (int i=0; i<objects.size(); i++) {
14559                    if (System.identityHashCode(object) == objects.get(i)) {
14560                        return true;
14561                    }
14562                }
14563            }
14564            if (strings != null) {
14565                String flat = comp.flattenToString();
14566                for (int i=0; i<strings.size(); i++) {
14567                    if (flat.contains(strings.get(i))) {
14568                        return true;
14569                    }
14570                }
14571            }
14572            return false;
14573        }
14574    }
14575
14576    /**
14577     * There are three things that cmd can be:
14578     *  - a flattened component name that matches an existing activity
14579     *  - the cmd arg isn't the flattened component name of an existing activity:
14580     *    dump all activity whose component contains the cmd as a substring
14581     *  - A hex number of the ActivityRecord object instance.
14582     */
14583    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14584            int opti, boolean dumpAll) {
14585        ArrayList<ActivityRecord> activities;
14586
14587        synchronized (this) {
14588            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14589        }
14590
14591        if (activities.size() <= 0) {
14592            return false;
14593        }
14594
14595        String[] newArgs = new String[args.length - opti];
14596        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14597
14598        TaskRecord lastTask = null;
14599        boolean needSep = false;
14600        for (int i=activities.size()-1; i>=0; i--) {
14601            ActivityRecord r = activities.get(i);
14602            if (needSep) {
14603                pw.println();
14604            }
14605            needSep = true;
14606            synchronized (this) {
14607                if (lastTask != r.task) {
14608                    lastTask = r.task;
14609                    pw.print("TASK "); pw.print(lastTask.affinity);
14610                            pw.print(" id="); pw.println(lastTask.taskId);
14611                    if (dumpAll) {
14612                        lastTask.dump(pw, "  ");
14613                    }
14614                }
14615            }
14616            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14617        }
14618        return true;
14619    }
14620
14621    /**
14622     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14623     * there is a thread associated with the activity.
14624     */
14625    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14626            final ActivityRecord r, String[] args, boolean dumpAll) {
14627        String innerPrefix = prefix + "  ";
14628        synchronized (this) {
14629            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14630                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14631                    pw.print(" pid=");
14632                    if (r.app != null) pw.println(r.app.pid);
14633                    else pw.println("(not running)");
14634            if (dumpAll) {
14635                r.dump(pw, innerPrefix);
14636            }
14637        }
14638        if (r.app != null && r.app.thread != null) {
14639            // flush anything that is already in the PrintWriter since the thread is going
14640            // to write to the file descriptor directly
14641            pw.flush();
14642            try {
14643                TransferPipe tp = new TransferPipe();
14644                try {
14645                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14646                            r.appToken, innerPrefix, args);
14647                    tp.go(fd);
14648                } finally {
14649                    tp.kill();
14650                }
14651            } catch (IOException e) {
14652                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14653            } catch (RemoteException e) {
14654                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14655            }
14656        }
14657    }
14658
14659    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14660            int opti, boolean dumpAll, String dumpPackage) {
14661        boolean needSep = false;
14662        boolean onlyHistory = false;
14663        boolean printedAnything = false;
14664
14665        if ("history".equals(dumpPackage)) {
14666            if (opti < args.length && "-s".equals(args[opti])) {
14667                dumpAll = false;
14668            }
14669            onlyHistory = true;
14670            dumpPackage = null;
14671        }
14672
14673        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14674        if (!onlyHistory && dumpAll) {
14675            if (mRegisteredReceivers.size() > 0) {
14676                boolean printed = false;
14677                Iterator it = mRegisteredReceivers.values().iterator();
14678                while (it.hasNext()) {
14679                    ReceiverList r = (ReceiverList)it.next();
14680                    if (dumpPackage != null && (r.app == null ||
14681                            !dumpPackage.equals(r.app.info.packageName))) {
14682                        continue;
14683                    }
14684                    if (!printed) {
14685                        pw.println("  Registered Receivers:");
14686                        needSep = true;
14687                        printed = true;
14688                        printedAnything = true;
14689                    }
14690                    pw.print("  * "); pw.println(r);
14691                    r.dump(pw, "    ");
14692                }
14693            }
14694
14695            if (mReceiverResolver.dump(pw, needSep ?
14696                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14697                    "    ", dumpPackage, false, false)) {
14698                needSep = true;
14699                printedAnything = true;
14700            }
14701        }
14702
14703        for (BroadcastQueue q : mBroadcastQueues) {
14704            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14705            printedAnything |= needSep;
14706        }
14707
14708        needSep = true;
14709
14710        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14711            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14712                if (needSep) {
14713                    pw.println();
14714                }
14715                needSep = true;
14716                printedAnything = true;
14717                pw.print("  Sticky broadcasts for user ");
14718                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14719                StringBuilder sb = new StringBuilder(128);
14720                for (Map.Entry<String, ArrayList<Intent>> ent
14721                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14722                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14723                    if (dumpAll) {
14724                        pw.println(":");
14725                        ArrayList<Intent> intents = ent.getValue();
14726                        final int N = intents.size();
14727                        for (int i=0; i<N; i++) {
14728                            sb.setLength(0);
14729                            sb.append("    Intent: ");
14730                            intents.get(i).toShortString(sb, false, true, false, false);
14731                            pw.println(sb.toString());
14732                            Bundle bundle = intents.get(i).getExtras();
14733                            if (bundle != null) {
14734                                pw.print("      ");
14735                                pw.println(bundle.toString());
14736                            }
14737                        }
14738                    } else {
14739                        pw.println("");
14740                    }
14741                }
14742            }
14743        }
14744
14745        if (!onlyHistory && dumpAll) {
14746            pw.println();
14747            for (BroadcastQueue queue : mBroadcastQueues) {
14748                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14749                        + queue.mBroadcastsScheduled);
14750            }
14751            pw.println("  mHandler:");
14752            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14753            needSep = true;
14754            printedAnything = true;
14755        }
14756
14757        if (!printedAnything) {
14758            pw.println("  (nothing)");
14759        }
14760    }
14761
14762    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14763            int opti, boolean dumpAll, String dumpPackage) {
14764        boolean needSep;
14765        boolean printedAnything = false;
14766
14767        ItemMatcher matcher = new ItemMatcher();
14768        matcher.build(args, opti);
14769
14770        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14771
14772        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14773        printedAnything |= needSep;
14774
14775        if (mLaunchingProviders.size() > 0) {
14776            boolean printed = false;
14777            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14778                ContentProviderRecord r = mLaunchingProviders.get(i);
14779                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14780                    continue;
14781                }
14782                if (!printed) {
14783                    if (needSep) pw.println();
14784                    needSep = true;
14785                    pw.println("  Launching content providers:");
14786                    printed = true;
14787                    printedAnything = true;
14788                }
14789                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14790                        pw.println(r);
14791            }
14792        }
14793
14794        if (!printedAnything) {
14795            pw.println("  (nothing)");
14796        }
14797    }
14798
14799    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14800            int opti, boolean dumpAll, String dumpPackage) {
14801        boolean needSep = false;
14802        boolean printedAnything = false;
14803
14804        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14805
14806        if (mGrantedUriPermissions.size() > 0) {
14807            boolean printed = false;
14808            int dumpUid = -2;
14809            if (dumpPackage != null) {
14810                try {
14811                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14812                            MATCH_UNINSTALLED_PACKAGES, 0);
14813                } catch (NameNotFoundException e) {
14814                    dumpUid = -1;
14815                }
14816            }
14817            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14818                int uid = mGrantedUriPermissions.keyAt(i);
14819                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14820                    continue;
14821                }
14822                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14823                if (!printed) {
14824                    if (needSep) pw.println();
14825                    needSep = true;
14826                    pw.println("  Granted Uri Permissions:");
14827                    printed = true;
14828                    printedAnything = true;
14829                }
14830                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14831                for (UriPermission perm : perms.values()) {
14832                    pw.print("    "); pw.println(perm);
14833                    if (dumpAll) {
14834                        perm.dump(pw, "      ");
14835                    }
14836                }
14837            }
14838        }
14839
14840        if (!printedAnything) {
14841            pw.println("  (nothing)");
14842        }
14843    }
14844
14845    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14846            int opti, boolean dumpAll, String dumpPackage) {
14847        boolean printed = false;
14848
14849        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14850
14851        if (mIntentSenderRecords.size() > 0) {
14852            Iterator<WeakReference<PendingIntentRecord>> it
14853                    = mIntentSenderRecords.values().iterator();
14854            while (it.hasNext()) {
14855                WeakReference<PendingIntentRecord> ref = it.next();
14856                PendingIntentRecord rec = ref != null ? ref.get(): null;
14857                if (dumpPackage != null && (rec == null
14858                        || !dumpPackage.equals(rec.key.packageName))) {
14859                    continue;
14860                }
14861                printed = true;
14862                if (rec != null) {
14863                    pw.print("  * "); pw.println(rec);
14864                    if (dumpAll) {
14865                        rec.dump(pw, "    ");
14866                    }
14867                } else {
14868                    pw.print("  * "); pw.println(ref);
14869                }
14870            }
14871        }
14872
14873        if (!printed) {
14874            pw.println("  (nothing)");
14875        }
14876    }
14877
14878    private static final int dumpProcessList(PrintWriter pw,
14879            ActivityManagerService service, List list,
14880            String prefix, String normalLabel, String persistentLabel,
14881            String dumpPackage) {
14882        int numPers = 0;
14883        final int N = list.size()-1;
14884        for (int i=N; i>=0; i--) {
14885            ProcessRecord r = (ProcessRecord)list.get(i);
14886            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14887                continue;
14888            }
14889            pw.println(String.format("%s%s #%2d: %s",
14890                    prefix, (r.persistent ? persistentLabel : normalLabel),
14891                    i, r.toString()));
14892            if (r.persistent) {
14893                numPers++;
14894            }
14895        }
14896        return numPers;
14897    }
14898
14899    private static final boolean dumpProcessOomList(PrintWriter pw,
14900            ActivityManagerService service, List<ProcessRecord> origList,
14901            String prefix, String normalLabel, String persistentLabel,
14902            boolean inclDetails, String dumpPackage) {
14903
14904        ArrayList<Pair<ProcessRecord, Integer>> list
14905                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14906        for (int i=0; i<origList.size(); i++) {
14907            ProcessRecord r = origList.get(i);
14908            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14909                continue;
14910            }
14911            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14912        }
14913
14914        if (list.size() <= 0) {
14915            return false;
14916        }
14917
14918        Comparator<Pair<ProcessRecord, Integer>> comparator
14919                = new Comparator<Pair<ProcessRecord, Integer>>() {
14920            @Override
14921            public int compare(Pair<ProcessRecord, Integer> object1,
14922                    Pair<ProcessRecord, Integer> object2) {
14923                if (object1.first.setAdj != object2.first.setAdj) {
14924                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14925                }
14926                if (object1.first.setProcState != object2.first.setProcState) {
14927                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14928                }
14929                if (object1.second.intValue() != object2.second.intValue()) {
14930                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14931                }
14932                return 0;
14933            }
14934        };
14935
14936        Collections.sort(list, comparator);
14937
14938        final long curRealtime = SystemClock.elapsedRealtime();
14939        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14940        final long curUptime = SystemClock.uptimeMillis();
14941        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14942
14943        for (int i=list.size()-1; i>=0; i--) {
14944            ProcessRecord r = list.get(i).first;
14945            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14946            char schedGroup;
14947            switch (r.setSchedGroup) {
14948                case ProcessList.SCHED_GROUP_BACKGROUND:
14949                    schedGroup = 'B';
14950                    break;
14951                case ProcessList.SCHED_GROUP_DEFAULT:
14952                    schedGroup = 'F';
14953                    break;
14954                case ProcessList.SCHED_GROUP_TOP_APP:
14955                    schedGroup = 'T';
14956                    break;
14957                default:
14958                    schedGroup = '?';
14959                    break;
14960            }
14961            char foreground;
14962            if (r.foregroundActivities) {
14963                foreground = 'A';
14964            } else if (r.foregroundServices) {
14965                foreground = 'S';
14966            } else {
14967                foreground = ' ';
14968            }
14969            String procState = ProcessList.makeProcStateString(r.curProcState);
14970            pw.print(prefix);
14971            pw.print(r.persistent ? persistentLabel : normalLabel);
14972            pw.print(" #");
14973            int num = (origList.size()-1)-list.get(i).second;
14974            if (num < 10) pw.print(' ');
14975            pw.print(num);
14976            pw.print(": ");
14977            pw.print(oomAdj);
14978            pw.print(' ');
14979            pw.print(schedGroup);
14980            pw.print('/');
14981            pw.print(foreground);
14982            pw.print('/');
14983            pw.print(procState);
14984            pw.print(" trm:");
14985            if (r.trimMemoryLevel < 10) pw.print(' ');
14986            pw.print(r.trimMemoryLevel);
14987            pw.print(' ');
14988            pw.print(r.toShortString());
14989            pw.print(" (");
14990            pw.print(r.adjType);
14991            pw.println(')');
14992            if (r.adjSource != null || r.adjTarget != null) {
14993                pw.print(prefix);
14994                pw.print("    ");
14995                if (r.adjTarget instanceof ComponentName) {
14996                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14997                } else if (r.adjTarget != null) {
14998                    pw.print(r.adjTarget.toString());
14999                } else {
15000                    pw.print("{null}");
15001                }
15002                pw.print("<=");
15003                if (r.adjSource instanceof ProcessRecord) {
15004                    pw.print("Proc{");
15005                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15006                    pw.println("}");
15007                } else if (r.adjSource != null) {
15008                    pw.println(r.adjSource.toString());
15009                } else {
15010                    pw.println("{null}");
15011                }
15012            }
15013            if (inclDetails) {
15014                pw.print(prefix);
15015                pw.print("    ");
15016                pw.print("oom: max="); pw.print(r.maxAdj);
15017                pw.print(" curRaw="); pw.print(r.curRawAdj);
15018                pw.print(" setRaw="); pw.print(r.setRawAdj);
15019                pw.print(" cur="); pw.print(r.curAdj);
15020                pw.print(" set="); pw.println(r.setAdj);
15021                pw.print(prefix);
15022                pw.print("    ");
15023                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15024                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15025                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15026                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15027                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15028                pw.println();
15029                pw.print(prefix);
15030                pw.print("    ");
15031                pw.print("cached="); pw.print(r.cached);
15032                pw.print(" empty="); pw.print(r.empty);
15033                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15034
15035                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15036                    if (r.lastWakeTime != 0) {
15037                        long wtime;
15038                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15039                        synchronized (stats) {
15040                            wtime = stats.getProcessWakeTime(r.info.uid,
15041                                    r.pid, curRealtime);
15042                        }
15043                        long timeUsed = wtime - r.lastWakeTime;
15044                        pw.print(prefix);
15045                        pw.print("    ");
15046                        pw.print("keep awake over ");
15047                        TimeUtils.formatDuration(realtimeSince, pw);
15048                        pw.print(" used ");
15049                        TimeUtils.formatDuration(timeUsed, pw);
15050                        pw.print(" (");
15051                        pw.print((timeUsed*100)/realtimeSince);
15052                        pw.println("%)");
15053                    }
15054                    if (r.lastCpuTime != 0) {
15055                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15056                        pw.print(prefix);
15057                        pw.print("    ");
15058                        pw.print("run cpu over ");
15059                        TimeUtils.formatDuration(uptimeSince, pw);
15060                        pw.print(" used ");
15061                        TimeUtils.formatDuration(timeUsed, pw);
15062                        pw.print(" (");
15063                        pw.print((timeUsed*100)/uptimeSince);
15064                        pw.println("%)");
15065                    }
15066                }
15067            }
15068        }
15069        return true;
15070    }
15071
15072    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15073            String[] args) {
15074        ArrayList<ProcessRecord> procs;
15075        synchronized (this) {
15076            if (args != null && args.length > start
15077                    && args[start].charAt(0) != '-') {
15078                procs = new ArrayList<ProcessRecord>();
15079                int pid = -1;
15080                try {
15081                    pid = Integer.parseInt(args[start]);
15082                } catch (NumberFormatException e) {
15083                }
15084                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15085                    ProcessRecord proc = mLruProcesses.get(i);
15086                    if (proc.pid == pid) {
15087                        procs.add(proc);
15088                    } else if (allPkgs && proc.pkgList != null
15089                            && proc.pkgList.containsKey(args[start])) {
15090                        procs.add(proc);
15091                    } else if (proc.processName.equals(args[start])) {
15092                        procs.add(proc);
15093                    }
15094                }
15095                if (procs.size() <= 0) {
15096                    return null;
15097                }
15098            } else {
15099                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15100            }
15101        }
15102        return procs;
15103    }
15104
15105    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15106            PrintWriter pw, String[] args) {
15107        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15108        if (procs == null) {
15109            pw.println("No process found for: " + args[0]);
15110            return;
15111        }
15112
15113        long uptime = SystemClock.uptimeMillis();
15114        long realtime = SystemClock.elapsedRealtime();
15115        pw.println("Applications Graphics Acceleration Info:");
15116        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15117
15118        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15119            ProcessRecord r = procs.get(i);
15120            if (r.thread != null) {
15121                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15122                pw.flush();
15123                try {
15124                    TransferPipe tp = new TransferPipe();
15125                    try {
15126                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15127                        tp.go(fd);
15128                    } finally {
15129                        tp.kill();
15130                    }
15131                } catch (IOException e) {
15132                    pw.println("Failure while dumping the app: " + r);
15133                    pw.flush();
15134                } catch (RemoteException e) {
15135                    pw.println("Got a RemoteException while dumping the app " + r);
15136                    pw.flush();
15137                }
15138            }
15139        }
15140    }
15141
15142    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15143        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15144        if (procs == null) {
15145            pw.println("No process found for: " + args[0]);
15146            return;
15147        }
15148
15149        pw.println("Applications Database Info:");
15150
15151        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15152            ProcessRecord r = procs.get(i);
15153            if (r.thread != null) {
15154                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15155                pw.flush();
15156                try {
15157                    TransferPipe tp = new TransferPipe();
15158                    try {
15159                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15160                        tp.go(fd);
15161                    } finally {
15162                        tp.kill();
15163                    }
15164                } catch (IOException e) {
15165                    pw.println("Failure while dumping the app: " + r);
15166                    pw.flush();
15167                } catch (RemoteException e) {
15168                    pw.println("Got a RemoteException while dumping the app " + r);
15169                    pw.flush();
15170                }
15171            }
15172        }
15173    }
15174
15175    final static class MemItem {
15176        final boolean isProc;
15177        final String label;
15178        final String shortLabel;
15179        final long pss;
15180        final long swapPss;
15181        final int id;
15182        final boolean hasActivities;
15183        ArrayList<MemItem> subitems;
15184
15185        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15186                boolean _hasActivities) {
15187            isProc = true;
15188            label = _label;
15189            shortLabel = _shortLabel;
15190            pss = _pss;
15191            swapPss = _swapPss;
15192            id = _id;
15193            hasActivities = _hasActivities;
15194        }
15195
15196        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15197            isProc = false;
15198            label = _label;
15199            shortLabel = _shortLabel;
15200            pss = _pss;
15201            swapPss = _swapPss;
15202            id = _id;
15203            hasActivities = false;
15204        }
15205    }
15206
15207    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15208            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15209        if (sort && !isCompact) {
15210            Collections.sort(items, new Comparator<MemItem>() {
15211                @Override
15212                public int compare(MemItem lhs, MemItem rhs) {
15213                    if (lhs.pss < rhs.pss) {
15214                        return 1;
15215                    } else if (lhs.pss > rhs.pss) {
15216                        return -1;
15217                    }
15218                    return 0;
15219                }
15220            });
15221        }
15222
15223        for (int i=0; i<items.size(); i++) {
15224            MemItem mi = items.get(i);
15225            if (!isCompact) {
15226                if (dumpSwapPss) {
15227                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15228                            mi.label, stringifyKBSize(mi.swapPss));
15229                } else {
15230                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15231                }
15232            } else if (mi.isProc) {
15233                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15234                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15235                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15236                pw.println(mi.hasActivities ? ",a" : ",e");
15237            } else {
15238                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15239                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15240            }
15241            if (mi.subitems != null) {
15242                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15243                        true, isCompact, dumpSwapPss);
15244            }
15245        }
15246    }
15247
15248    // These are in KB.
15249    static final long[] DUMP_MEM_BUCKETS = new long[] {
15250        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15251        120*1024, 160*1024, 200*1024,
15252        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15253        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15254    };
15255
15256    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15257            boolean stackLike) {
15258        int start = label.lastIndexOf('.');
15259        if (start >= 0) start++;
15260        else start = 0;
15261        int end = label.length();
15262        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15263            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15264                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15265                out.append(bucket);
15266                out.append(stackLike ? "MB." : "MB ");
15267                out.append(label, start, end);
15268                return;
15269            }
15270        }
15271        out.append(memKB/1024);
15272        out.append(stackLike ? "MB." : "MB ");
15273        out.append(label, start, end);
15274    }
15275
15276    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15277            ProcessList.NATIVE_ADJ,
15278            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15279            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15280            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15281            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15282            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15283            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15284    };
15285    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15286            "Native",
15287            "System", "Persistent", "Persistent Service", "Foreground",
15288            "Visible", "Perceptible",
15289            "Heavy Weight", "Backup",
15290            "A Services", "Home",
15291            "Previous", "B Services", "Cached"
15292    };
15293    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15294            "native",
15295            "sys", "pers", "persvc", "fore",
15296            "vis", "percept",
15297            "heavy", "backup",
15298            "servicea", "home",
15299            "prev", "serviceb", "cached"
15300    };
15301
15302    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15303            long realtime, boolean isCheckinRequest, boolean isCompact) {
15304        if (isCompact) {
15305            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15306        }
15307        if (isCheckinRequest || isCompact) {
15308            // short checkin version
15309            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15310        } else {
15311            pw.println("Applications Memory Usage (in Kilobytes):");
15312            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15313        }
15314    }
15315
15316    private static final int KSM_SHARED = 0;
15317    private static final int KSM_SHARING = 1;
15318    private static final int KSM_UNSHARED = 2;
15319    private static final int KSM_VOLATILE = 3;
15320
15321    private final long[] getKsmInfo() {
15322        long[] longOut = new long[4];
15323        final int[] SINGLE_LONG_FORMAT = new int[] {
15324            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15325        };
15326        long[] longTmp = new long[1];
15327        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15328                SINGLE_LONG_FORMAT, null, longTmp, null);
15329        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15330        longTmp[0] = 0;
15331        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15332                SINGLE_LONG_FORMAT, null, longTmp, null);
15333        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15334        longTmp[0] = 0;
15335        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15336                SINGLE_LONG_FORMAT, null, longTmp, null);
15337        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15338        longTmp[0] = 0;
15339        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15340                SINGLE_LONG_FORMAT, null, longTmp, null);
15341        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15342        return longOut;
15343    }
15344
15345    private static String stringifySize(long size, int order) {
15346        Locale locale = Locale.US;
15347        switch (order) {
15348            case 1:
15349                return String.format(locale, "%,13d", size);
15350            case 1024:
15351                return String.format(locale, "%,9dK", size / 1024);
15352            case 1024 * 1024:
15353                return String.format(locale, "%,5dM", size / 1024 / 1024);
15354            case 1024 * 1024 * 1024:
15355                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15356            default:
15357                throw new IllegalArgumentException("Invalid size order");
15358        }
15359    }
15360
15361    private static String stringifyKBSize(long size) {
15362        return stringifySize(size * 1024, 1024);
15363    }
15364
15365    // Update this version number in case you change the 'compact' format
15366    private static final int MEMINFO_COMPACT_VERSION = 1;
15367
15368    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15369            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15370        boolean dumpDetails = false;
15371        boolean dumpFullDetails = false;
15372        boolean dumpDalvik = false;
15373        boolean dumpSummaryOnly = false;
15374        boolean dumpUnreachable = false;
15375        boolean oomOnly = false;
15376        boolean isCompact = false;
15377        boolean localOnly = false;
15378        boolean packages = false;
15379        boolean isCheckinRequest = false;
15380        boolean dumpSwapPss = false;
15381
15382        int opti = 0;
15383        while (opti < args.length) {
15384            String opt = args[opti];
15385            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15386                break;
15387            }
15388            opti++;
15389            if ("-a".equals(opt)) {
15390                dumpDetails = true;
15391                dumpFullDetails = true;
15392                dumpDalvik = true;
15393                dumpSwapPss = true;
15394            } else if ("-d".equals(opt)) {
15395                dumpDalvik = true;
15396            } else if ("-c".equals(opt)) {
15397                isCompact = true;
15398            } else if ("-s".equals(opt)) {
15399                dumpDetails = true;
15400                dumpSummaryOnly = true;
15401            } else if ("-S".equals(opt)) {
15402                dumpSwapPss = true;
15403            } else if ("--unreachable".equals(opt)) {
15404                dumpUnreachable = true;
15405            } else if ("--oom".equals(opt)) {
15406                oomOnly = true;
15407            } else if ("--local".equals(opt)) {
15408                localOnly = true;
15409            } else if ("--package".equals(opt)) {
15410                packages = true;
15411            } else if ("--checkin".equals(opt)) {
15412                isCheckinRequest = true;
15413
15414            } else if ("-h".equals(opt)) {
15415                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15416                pw.println("  -a: include all available information for each process.");
15417                pw.println("  -d: include dalvik details.");
15418                pw.println("  -c: dump in a compact machine-parseable representation.");
15419                pw.println("  -s: dump only summary of application memory usage.");
15420                pw.println("  -S: dump also SwapPss.");
15421                pw.println("  --oom: only show processes organized by oom adj.");
15422                pw.println("  --local: only collect details locally, don't call process.");
15423                pw.println("  --package: interpret process arg as package, dumping all");
15424                pw.println("             processes that have loaded that package.");
15425                pw.println("  --checkin: dump data for a checkin");
15426                pw.println("If [process] is specified it can be the name or ");
15427                pw.println("pid of a specific process to dump.");
15428                return;
15429            } else {
15430                pw.println("Unknown argument: " + opt + "; use -h for help");
15431            }
15432        }
15433
15434        long uptime = SystemClock.uptimeMillis();
15435        long realtime = SystemClock.elapsedRealtime();
15436        final long[] tmpLong = new long[1];
15437
15438        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15439        if (procs == null) {
15440            // No Java processes.  Maybe they want to print a native process.
15441            if (args != null && args.length > opti
15442                    && args[opti].charAt(0) != '-') {
15443                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15444                        = new ArrayList<ProcessCpuTracker.Stats>();
15445                updateCpuStatsNow();
15446                int findPid = -1;
15447                try {
15448                    findPid = Integer.parseInt(args[opti]);
15449                } catch (NumberFormatException e) {
15450                }
15451                synchronized (mProcessCpuTracker) {
15452                    final int N = mProcessCpuTracker.countStats();
15453                    for (int i=0; i<N; i++) {
15454                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15455                        if (st.pid == findPid || (st.baseName != null
15456                                && st.baseName.equals(args[opti]))) {
15457                            nativeProcs.add(st);
15458                        }
15459                    }
15460                }
15461                if (nativeProcs.size() > 0) {
15462                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15463                            isCompact);
15464                    Debug.MemoryInfo mi = null;
15465                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15466                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15467                        final int pid = r.pid;
15468                        if (!isCheckinRequest && dumpDetails) {
15469                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15470                        }
15471                        if (mi == null) {
15472                            mi = new Debug.MemoryInfo();
15473                        }
15474                        if (dumpDetails || (!brief && !oomOnly)) {
15475                            Debug.getMemoryInfo(pid, mi);
15476                        } else {
15477                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15478                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15479                        }
15480                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15481                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15482                        if (isCheckinRequest) {
15483                            pw.println();
15484                        }
15485                    }
15486                    return;
15487                }
15488            }
15489            pw.println("No process found for: " + args[opti]);
15490            return;
15491        }
15492
15493        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15494            dumpDetails = true;
15495        }
15496
15497        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15498
15499        String[] innerArgs = new String[args.length-opti];
15500        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15501
15502        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15503        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15504        long nativePss = 0;
15505        long nativeSwapPss = 0;
15506        long dalvikPss = 0;
15507        long dalvikSwapPss = 0;
15508        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15509                EmptyArray.LONG;
15510        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15511                EmptyArray.LONG;
15512        long otherPss = 0;
15513        long otherSwapPss = 0;
15514        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15515        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15516
15517        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15518        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15519        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15520                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15521
15522        long totalPss = 0;
15523        long totalSwapPss = 0;
15524        long cachedPss = 0;
15525        long cachedSwapPss = 0;
15526        boolean hasSwapPss = false;
15527
15528        Debug.MemoryInfo mi = null;
15529        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15530            final ProcessRecord r = procs.get(i);
15531            final IApplicationThread thread;
15532            final int pid;
15533            final int oomAdj;
15534            final boolean hasActivities;
15535            synchronized (this) {
15536                thread = r.thread;
15537                pid = r.pid;
15538                oomAdj = r.getSetAdjWithServices();
15539                hasActivities = r.activities.size() > 0;
15540            }
15541            if (thread != null) {
15542                if (!isCheckinRequest && dumpDetails) {
15543                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15544                }
15545                if (mi == null) {
15546                    mi = new Debug.MemoryInfo();
15547                }
15548                if (dumpDetails || (!brief && !oomOnly)) {
15549                    Debug.getMemoryInfo(pid, mi);
15550                    hasSwapPss = mi.hasSwappedOutPss;
15551                } else {
15552                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15553                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15554                }
15555                if (dumpDetails) {
15556                    if (localOnly) {
15557                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15558                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15559                        if (isCheckinRequest) {
15560                            pw.println();
15561                        }
15562                    } else {
15563                        try {
15564                            pw.flush();
15565                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15566                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15567                        } catch (RemoteException e) {
15568                            if (!isCheckinRequest) {
15569                                pw.println("Got RemoteException!");
15570                                pw.flush();
15571                            }
15572                        }
15573                    }
15574                }
15575
15576                final long myTotalPss = mi.getTotalPss();
15577                final long myTotalUss = mi.getTotalUss();
15578                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15579
15580                synchronized (this) {
15581                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15582                        // Record this for posterity if the process has been stable.
15583                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15584                    }
15585                }
15586
15587                if (!isCheckinRequest && mi != null) {
15588                    totalPss += myTotalPss;
15589                    totalSwapPss += myTotalSwapPss;
15590                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15591                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15592                            myTotalSwapPss, pid, hasActivities);
15593                    procMems.add(pssItem);
15594                    procMemsMap.put(pid, pssItem);
15595
15596                    nativePss += mi.nativePss;
15597                    nativeSwapPss += mi.nativeSwappedOutPss;
15598                    dalvikPss += mi.dalvikPss;
15599                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15600                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15601                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15602                        dalvikSubitemSwapPss[j] +=
15603                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15604                    }
15605                    otherPss += mi.otherPss;
15606                    otherSwapPss += mi.otherSwappedOutPss;
15607                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15608                        long mem = mi.getOtherPss(j);
15609                        miscPss[j] += mem;
15610                        otherPss -= mem;
15611                        mem = mi.getOtherSwappedOutPss(j);
15612                        miscSwapPss[j] += mem;
15613                        otherSwapPss -= mem;
15614                    }
15615
15616                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15617                        cachedPss += myTotalPss;
15618                        cachedSwapPss += myTotalSwapPss;
15619                    }
15620
15621                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15622                        if (oomIndex == (oomPss.length - 1)
15623                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15624                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15625                            oomPss[oomIndex] += myTotalPss;
15626                            oomSwapPss[oomIndex] += myTotalSwapPss;
15627                            if (oomProcs[oomIndex] == null) {
15628                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15629                            }
15630                            oomProcs[oomIndex].add(pssItem);
15631                            break;
15632                        }
15633                    }
15634                }
15635            }
15636        }
15637
15638        long nativeProcTotalPss = 0;
15639
15640        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15641            // If we are showing aggregations, also look for native processes to
15642            // include so that our aggregations are more accurate.
15643            updateCpuStatsNow();
15644            mi = null;
15645            synchronized (mProcessCpuTracker) {
15646                final int N = mProcessCpuTracker.countStats();
15647                for (int i=0; i<N; i++) {
15648                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15649                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15650                        if (mi == null) {
15651                            mi = new Debug.MemoryInfo();
15652                        }
15653                        if (!brief && !oomOnly) {
15654                            Debug.getMemoryInfo(st.pid, mi);
15655                        } else {
15656                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15657                            mi.nativePrivateDirty = (int)tmpLong[0];
15658                        }
15659
15660                        final long myTotalPss = mi.getTotalPss();
15661                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15662                        totalPss += myTotalPss;
15663                        nativeProcTotalPss += myTotalPss;
15664
15665                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15666                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15667                        procMems.add(pssItem);
15668
15669                        nativePss += mi.nativePss;
15670                        nativeSwapPss += mi.nativeSwappedOutPss;
15671                        dalvikPss += mi.dalvikPss;
15672                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15673                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15674                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15675                            dalvikSubitemSwapPss[j] +=
15676                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15677                        }
15678                        otherPss += mi.otherPss;
15679                        otherSwapPss += mi.otherSwappedOutPss;
15680                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15681                            long mem = mi.getOtherPss(j);
15682                            miscPss[j] += mem;
15683                            otherPss -= mem;
15684                            mem = mi.getOtherSwappedOutPss(j);
15685                            miscSwapPss[j] += mem;
15686                            otherSwapPss -= mem;
15687                        }
15688                        oomPss[0] += myTotalPss;
15689                        oomSwapPss[0] += myTotalSwapPss;
15690                        if (oomProcs[0] == null) {
15691                            oomProcs[0] = new ArrayList<MemItem>();
15692                        }
15693                        oomProcs[0].add(pssItem);
15694                    }
15695                }
15696            }
15697
15698            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15699
15700            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15701            final MemItem dalvikItem =
15702                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15703            if (dalvikSubitemPss.length > 0) {
15704                dalvikItem.subitems = new ArrayList<MemItem>();
15705                for (int j=0; j<dalvikSubitemPss.length; j++) {
15706                    final String name = Debug.MemoryInfo.getOtherLabel(
15707                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15708                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15709                                    dalvikSubitemSwapPss[j], j));
15710                }
15711            }
15712            catMems.add(dalvikItem);
15713            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15714            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15715                String label = Debug.MemoryInfo.getOtherLabel(j);
15716                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15717            }
15718
15719            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15720            for (int j=0; j<oomPss.length; j++) {
15721                if (oomPss[j] != 0) {
15722                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15723                            : DUMP_MEM_OOM_LABEL[j];
15724                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15725                            DUMP_MEM_OOM_ADJ[j]);
15726                    item.subitems = oomProcs[j];
15727                    oomMems.add(item);
15728                }
15729            }
15730
15731            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15732            if (!brief && !oomOnly && !isCompact) {
15733                pw.println();
15734                pw.println("Total PSS by process:");
15735                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15736                pw.println();
15737            }
15738            if (!isCompact) {
15739                pw.println("Total PSS by OOM adjustment:");
15740            }
15741            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15742            if (!brief && !oomOnly) {
15743                PrintWriter out = categoryPw != null ? categoryPw : pw;
15744                if (!isCompact) {
15745                    out.println();
15746                    out.println("Total PSS by category:");
15747                }
15748                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15749            }
15750            if (!isCompact) {
15751                pw.println();
15752            }
15753            MemInfoReader memInfo = new MemInfoReader();
15754            memInfo.readMemInfo();
15755            if (nativeProcTotalPss > 0) {
15756                synchronized (this) {
15757                    final long cachedKb = memInfo.getCachedSizeKb();
15758                    final long freeKb = memInfo.getFreeSizeKb();
15759                    final long zramKb = memInfo.getZramTotalSizeKb();
15760                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15761                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15762                            kernelKb*1024, nativeProcTotalPss*1024);
15763                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15764                            nativeProcTotalPss);
15765                }
15766            }
15767            if (!brief) {
15768                if (!isCompact) {
15769                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15770                    pw.print(" (status ");
15771                    switch (mLastMemoryLevel) {
15772                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15773                            pw.println("normal)");
15774                            break;
15775                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15776                            pw.println("moderate)");
15777                            break;
15778                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15779                            pw.println("low)");
15780                            break;
15781                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15782                            pw.println("critical)");
15783                            break;
15784                        default:
15785                            pw.print(mLastMemoryLevel);
15786                            pw.println(")");
15787                            break;
15788                    }
15789                    pw.print(" Free RAM: ");
15790                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15791                            + memInfo.getFreeSizeKb()));
15792                    pw.print(" (");
15793                    pw.print(stringifyKBSize(cachedPss));
15794                    pw.print(" cached pss + ");
15795                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15796                    pw.print(" cached kernel + ");
15797                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15798                    pw.println(" free)");
15799                } else {
15800                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15801                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15802                            + memInfo.getFreeSizeKb()); pw.print(",");
15803                    pw.println(totalPss - cachedPss);
15804                }
15805            }
15806            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15807                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15808                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15809            if (!isCompact) {
15810                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15811                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15812                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15813                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15814                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15815            } else {
15816                pw.print("lostram,"); pw.println(lostRAM);
15817            }
15818            if (!brief) {
15819                if (memInfo.getZramTotalSizeKb() != 0) {
15820                    if (!isCompact) {
15821                        pw.print("     ZRAM: ");
15822                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15823                                pw.print(" physical used for ");
15824                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15825                                        - memInfo.getSwapFreeSizeKb()));
15826                                pw.print(" in swap (");
15827                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15828                                pw.println(" total swap)");
15829                    } else {
15830                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15831                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15832                                pw.println(memInfo.getSwapFreeSizeKb());
15833                    }
15834                }
15835                final long[] ksm = getKsmInfo();
15836                if (!isCompact) {
15837                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15838                            || ksm[KSM_VOLATILE] != 0) {
15839                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15840                                pw.print(" saved from shared ");
15841                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15842                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15843                                pw.print(" unshared; ");
15844                                pw.print(stringifyKBSize(
15845                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15846                    }
15847                    pw.print("   Tuning: ");
15848                    pw.print(ActivityManager.staticGetMemoryClass());
15849                    pw.print(" (large ");
15850                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15851                    pw.print("), oom ");
15852                    pw.print(stringifySize(
15853                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15854                    pw.print(", restore limit ");
15855                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15856                    if (ActivityManager.isLowRamDeviceStatic()) {
15857                        pw.print(" (low-ram)");
15858                    }
15859                    if (ActivityManager.isHighEndGfx()) {
15860                        pw.print(" (high-end-gfx)");
15861                    }
15862                    pw.println();
15863                } else {
15864                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15865                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15866                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15867                    pw.print("tuning,");
15868                    pw.print(ActivityManager.staticGetMemoryClass());
15869                    pw.print(',');
15870                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15871                    pw.print(',');
15872                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15873                    if (ActivityManager.isLowRamDeviceStatic()) {
15874                        pw.print(",low-ram");
15875                    }
15876                    if (ActivityManager.isHighEndGfx()) {
15877                        pw.print(",high-end-gfx");
15878                    }
15879                    pw.println();
15880                }
15881            }
15882        }
15883    }
15884
15885    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15886            long memtrack, String name) {
15887        sb.append("  ");
15888        sb.append(ProcessList.makeOomAdjString(oomAdj));
15889        sb.append(' ');
15890        sb.append(ProcessList.makeProcStateString(procState));
15891        sb.append(' ');
15892        ProcessList.appendRamKb(sb, pss);
15893        sb.append(": ");
15894        sb.append(name);
15895        if (memtrack > 0) {
15896            sb.append(" (");
15897            sb.append(stringifyKBSize(memtrack));
15898            sb.append(" memtrack)");
15899        }
15900    }
15901
15902    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15903        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15904        sb.append(" (pid ");
15905        sb.append(mi.pid);
15906        sb.append(") ");
15907        sb.append(mi.adjType);
15908        sb.append('\n');
15909        if (mi.adjReason != null) {
15910            sb.append("                      ");
15911            sb.append(mi.adjReason);
15912            sb.append('\n');
15913        }
15914    }
15915
15916    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15917        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15918        for (int i=0, N=memInfos.size(); i<N; i++) {
15919            ProcessMemInfo mi = memInfos.get(i);
15920            infoMap.put(mi.pid, mi);
15921        }
15922        updateCpuStatsNow();
15923        long[] memtrackTmp = new long[1];
15924        synchronized (mProcessCpuTracker) {
15925            final int N = mProcessCpuTracker.countStats();
15926            for (int i=0; i<N; i++) {
15927                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15928                if (st.vsize > 0) {
15929                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15930                    if (pss > 0) {
15931                        if (infoMap.indexOfKey(st.pid) < 0) {
15932                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15933                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15934                            mi.pss = pss;
15935                            mi.memtrack = memtrackTmp[0];
15936                            memInfos.add(mi);
15937                        }
15938                    }
15939                }
15940            }
15941        }
15942
15943        long totalPss = 0;
15944        long totalMemtrack = 0;
15945        for (int i=0, N=memInfos.size(); i<N; i++) {
15946            ProcessMemInfo mi = memInfos.get(i);
15947            if (mi.pss == 0) {
15948                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15949                mi.memtrack = memtrackTmp[0];
15950            }
15951            totalPss += mi.pss;
15952            totalMemtrack += mi.memtrack;
15953        }
15954        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15955            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15956                if (lhs.oomAdj != rhs.oomAdj) {
15957                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15958                }
15959                if (lhs.pss != rhs.pss) {
15960                    return lhs.pss < rhs.pss ? 1 : -1;
15961                }
15962                return 0;
15963            }
15964        });
15965
15966        StringBuilder tag = new StringBuilder(128);
15967        StringBuilder stack = new StringBuilder(128);
15968        tag.append("Low on memory -- ");
15969        appendMemBucket(tag, totalPss, "total", false);
15970        appendMemBucket(stack, totalPss, "total", true);
15971
15972        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15973        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15974        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15975
15976        boolean firstLine = true;
15977        int lastOomAdj = Integer.MIN_VALUE;
15978        long extraNativeRam = 0;
15979        long extraNativeMemtrack = 0;
15980        long cachedPss = 0;
15981        for (int i=0, N=memInfos.size(); i<N; i++) {
15982            ProcessMemInfo mi = memInfos.get(i);
15983
15984            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15985                cachedPss += mi.pss;
15986            }
15987
15988            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15989                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15990                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15991                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15992                if (lastOomAdj != mi.oomAdj) {
15993                    lastOomAdj = mi.oomAdj;
15994                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15995                        tag.append(" / ");
15996                    }
15997                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15998                        if (firstLine) {
15999                            stack.append(":");
16000                            firstLine = false;
16001                        }
16002                        stack.append("\n\t at ");
16003                    } else {
16004                        stack.append("$");
16005                    }
16006                } else {
16007                    tag.append(" ");
16008                    stack.append("$");
16009                }
16010                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16011                    appendMemBucket(tag, mi.pss, mi.name, false);
16012                }
16013                appendMemBucket(stack, mi.pss, mi.name, true);
16014                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16015                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16016                    stack.append("(");
16017                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16018                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16019                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16020                            stack.append(":");
16021                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16022                        }
16023                    }
16024                    stack.append(")");
16025                }
16026            }
16027
16028            appendMemInfo(fullNativeBuilder, mi);
16029            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16030                // The short form only has native processes that are >= 512K.
16031                if (mi.pss >= 512) {
16032                    appendMemInfo(shortNativeBuilder, mi);
16033                } else {
16034                    extraNativeRam += mi.pss;
16035                    extraNativeMemtrack += mi.memtrack;
16036                }
16037            } else {
16038                // Short form has all other details, but if we have collected RAM
16039                // from smaller native processes let's dump a summary of that.
16040                if (extraNativeRam > 0) {
16041                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16042                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16043                    shortNativeBuilder.append('\n');
16044                    extraNativeRam = 0;
16045                }
16046                appendMemInfo(fullJavaBuilder, mi);
16047            }
16048        }
16049
16050        fullJavaBuilder.append("           ");
16051        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16052        fullJavaBuilder.append(": TOTAL");
16053        if (totalMemtrack > 0) {
16054            fullJavaBuilder.append(" (");
16055            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16056            fullJavaBuilder.append(" memtrack)");
16057        } else {
16058        }
16059        fullJavaBuilder.append("\n");
16060
16061        MemInfoReader memInfo = new MemInfoReader();
16062        memInfo.readMemInfo();
16063        final long[] infos = memInfo.getRawInfo();
16064
16065        StringBuilder memInfoBuilder = new StringBuilder(1024);
16066        Debug.getMemInfo(infos);
16067        memInfoBuilder.append("  MemInfo: ");
16068        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16069        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16070        memInfoBuilder.append(stringifyKBSize(
16071                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16072        memInfoBuilder.append(stringifyKBSize(
16073                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16074        memInfoBuilder.append(stringifyKBSize(
16075                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16076        memInfoBuilder.append("           ");
16077        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16078        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16079        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16080        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16081        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16082            memInfoBuilder.append("  ZRAM: ");
16083            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16084            memInfoBuilder.append(" RAM, ");
16085            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16086            memInfoBuilder.append(" swap total, ");
16087            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16088            memInfoBuilder.append(" swap free\n");
16089        }
16090        final long[] ksm = getKsmInfo();
16091        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16092                || ksm[KSM_VOLATILE] != 0) {
16093            memInfoBuilder.append("  KSM: ");
16094            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16095            memInfoBuilder.append(" saved from shared ");
16096            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16097            memInfoBuilder.append("\n       ");
16098            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16099            memInfoBuilder.append(" unshared; ");
16100            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16101            memInfoBuilder.append(" volatile\n");
16102        }
16103        memInfoBuilder.append("  Free RAM: ");
16104        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16105                + memInfo.getFreeSizeKb()));
16106        memInfoBuilder.append("\n");
16107        memInfoBuilder.append("  Used RAM: ");
16108        memInfoBuilder.append(stringifyKBSize(
16109                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16110        memInfoBuilder.append("\n");
16111        memInfoBuilder.append("  Lost RAM: ");
16112        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16113                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16114                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16115        memInfoBuilder.append("\n");
16116        Slog.i(TAG, "Low on memory:");
16117        Slog.i(TAG, shortNativeBuilder.toString());
16118        Slog.i(TAG, fullJavaBuilder.toString());
16119        Slog.i(TAG, memInfoBuilder.toString());
16120
16121        StringBuilder dropBuilder = new StringBuilder(1024);
16122        /*
16123        StringWriter oomSw = new StringWriter();
16124        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16125        StringWriter catSw = new StringWriter();
16126        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16127        String[] emptyArgs = new String[] { };
16128        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16129        oomPw.flush();
16130        String oomString = oomSw.toString();
16131        */
16132        dropBuilder.append("Low on memory:");
16133        dropBuilder.append(stack);
16134        dropBuilder.append('\n');
16135        dropBuilder.append(fullNativeBuilder);
16136        dropBuilder.append(fullJavaBuilder);
16137        dropBuilder.append('\n');
16138        dropBuilder.append(memInfoBuilder);
16139        dropBuilder.append('\n');
16140        /*
16141        dropBuilder.append(oomString);
16142        dropBuilder.append('\n');
16143        */
16144        StringWriter catSw = new StringWriter();
16145        synchronized (ActivityManagerService.this) {
16146            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16147            String[] emptyArgs = new String[] { };
16148            catPw.println();
16149            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16150            catPw.println();
16151            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16152                    false, false, null);
16153            catPw.println();
16154            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16155            catPw.flush();
16156        }
16157        dropBuilder.append(catSw.toString());
16158        addErrorToDropBox("lowmem", null, "system_server", null,
16159                null, tag.toString(), dropBuilder.toString(), null, null);
16160        //Slog.i(TAG, "Sent to dropbox:");
16161        //Slog.i(TAG, dropBuilder.toString());
16162        synchronized (ActivityManagerService.this) {
16163            long now = SystemClock.uptimeMillis();
16164            if (mLastMemUsageReportTime < now) {
16165                mLastMemUsageReportTime = now;
16166            }
16167        }
16168    }
16169
16170    /**
16171     * Searches array of arguments for the specified string
16172     * @param args array of argument strings
16173     * @param value value to search for
16174     * @return true if the value is contained in the array
16175     */
16176    private static boolean scanArgs(String[] args, String value) {
16177        if (args != null) {
16178            for (String arg : args) {
16179                if (value.equals(arg)) {
16180                    return true;
16181                }
16182            }
16183        }
16184        return false;
16185    }
16186
16187    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16188            ContentProviderRecord cpr, boolean always) {
16189        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16190
16191        if (!inLaunching || always) {
16192            synchronized (cpr) {
16193                cpr.launchingApp = null;
16194                cpr.notifyAll();
16195            }
16196            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16197            String names[] = cpr.info.authority.split(";");
16198            for (int j = 0; j < names.length; j++) {
16199                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16200            }
16201        }
16202
16203        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16204            ContentProviderConnection conn = cpr.connections.get(i);
16205            if (conn.waiting) {
16206                // If this connection is waiting for the provider, then we don't
16207                // need to mess with its process unless we are always removing
16208                // or for some reason the provider is not currently launching.
16209                if (inLaunching && !always) {
16210                    continue;
16211                }
16212            }
16213            ProcessRecord capp = conn.client;
16214            conn.dead = true;
16215            if (conn.stableCount > 0) {
16216                if (!capp.persistent && capp.thread != null
16217                        && capp.pid != 0
16218                        && capp.pid != MY_PID) {
16219                    capp.kill("depends on provider "
16220                            + cpr.name.flattenToShortString()
16221                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16222                }
16223            } else if (capp.thread != null && conn.provider.provider != null) {
16224                try {
16225                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16226                } catch (RemoteException e) {
16227                }
16228                // In the protocol here, we don't expect the client to correctly
16229                // clean up this connection, we'll just remove it.
16230                cpr.connections.remove(i);
16231                if (conn.client.conProviders.remove(conn)) {
16232                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16233                }
16234            }
16235        }
16236
16237        if (inLaunching && always) {
16238            mLaunchingProviders.remove(cpr);
16239        }
16240        return inLaunching;
16241    }
16242
16243    /**
16244     * Main code for cleaning up a process when it has gone away.  This is
16245     * called both as a result of the process dying, or directly when stopping
16246     * a process when running in single process mode.
16247     *
16248     * @return Returns true if the given process has been restarted, so the
16249     * app that was passed in must remain on the process lists.
16250     */
16251    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16252            boolean restarting, boolean allowRestart, int index) {
16253        if (index >= 0) {
16254            removeLruProcessLocked(app);
16255            ProcessList.remove(app.pid);
16256        }
16257
16258        mProcessesToGc.remove(app);
16259        mPendingPssProcesses.remove(app);
16260
16261        // Dismiss any open dialogs.
16262        if (app.crashDialog != null && !app.forceCrashReport) {
16263            app.crashDialog.dismiss();
16264            app.crashDialog = null;
16265        }
16266        if (app.anrDialog != null) {
16267            app.anrDialog.dismiss();
16268            app.anrDialog = null;
16269        }
16270        if (app.waitDialog != null) {
16271            app.waitDialog.dismiss();
16272            app.waitDialog = null;
16273        }
16274
16275        app.crashing = false;
16276        app.notResponding = false;
16277
16278        app.resetPackageList(mProcessStats);
16279        app.unlinkDeathRecipient();
16280        app.makeInactive(mProcessStats);
16281        app.waitingToKill = null;
16282        app.forcingToForeground = null;
16283        updateProcessForegroundLocked(app, false, false);
16284        app.foregroundActivities = false;
16285        app.hasShownUi = false;
16286        app.treatLikeActivity = false;
16287        app.hasAboveClient = false;
16288        app.hasClientActivities = false;
16289
16290        mServices.killServicesLocked(app, allowRestart);
16291
16292        boolean restart = false;
16293
16294        // Remove published content providers.
16295        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16296            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16297            final boolean always = app.bad || !allowRestart;
16298            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16299            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16300                // We left the provider in the launching list, need to
16301                // restart it.
16302                restart = true;
16303            }
16304
16305            cpr.provider = null;
16306            cpr.proc = null;
16307        }
16308        app.pubProviders.clear();
16309
16310        // Take care of any launching providers waiting for this process.
16311        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16312            restart = true;
16313        }
16314
16315        // Unregister from connected content providers.
16316        if (!app.conProviders.isEmpty()) {
16317            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16318                ContentProviderConnection conn = app.conProviders.get(i);
16319                conn.provider.connections.remove(conn);
16320                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16321                        conn.provider.name);
16322            }
16323            app.conProviders.clear();
16324        }
16325
16326        // At this point there may be remaining entries in mLaunchingProviders
16327        // where we were the only one waiting, so they are no longer of use.
16328        // Look for these and clean up if found.
16329        // XXX Commented out for now.  Trying to figure out a way to reproduce
16330        // the actual situation to identify what is actually going on.
16331        if (false) {
16332            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16333                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16334                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16335                    synchronized (cpr) {
16336                        cpr.launchingApp = null;
16337                        cpr.notifyAll();
16338                    }
16339                }
16340            }
16341        }
16342
16343        skipCurrentReceiverLocked(app);
16344
16345        // Unregister any receivers.
16346        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16347            removeReceiverLocked(app.receivers.valueAt(i));
16348        }
16349        app.receivers.clear();
16350
16351        // If the app is undergoing backup, tell the backup manager about it
16352        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16353            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16354                    + mBackupTarget.appInfo + " died during backup");
16355            try {
16356                IBackupManager bm = IBackupManager.Stub.asInterface(
16357                        ServiceManager.getService(Context.BACKUP_SERVICE));
16358                bm.agentDisconnected(app.info.packageName);
16359            } catch (RemoteException e) {
16360                // can't happen; backup manager is local
16361            }
16362        }
16363
16364        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16365            ProcessChangeItem item = mPendingProcessChanges.get(i);
16366            if (item.pid == app.pid) {
16367                mPendingProcessChanges.remove(i);
16368                mAvailProcessChanges.add(item);
16369            }
16370        }
16371        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16372                null).sendToTarget();
16373
16374        // If the caller is restarting this app, then leave it in its
16375        // current lists and let the caller take care of it.
16376        if (restarting) {
16377            return false;
16378        }
16379
16380        if (!app.persistent || app.isolated) {
16381            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16382                    "Removing non-persistent process during cleanup: " + app);
16383            removeProcessNameLocked(app.processName, app.uid);
16384            if (mHeavyWeightProcess == app) {
16385                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16386                        mHeavyWeightProcess.userId, 0));
16387                mHeavyWeightProcess = null;
16388            }
16389        } else if (!app.removed) {
16390            // This app is persistent, so we need to keep its record around.
16391            // If it is not already on the pending app list, add it there
16392            // and start a new process for it.
16393            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16394                mPersistentStartingProcesses.add(app);
16395                restart = true;
16396            }
16397        }
16398        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16399                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16400        mProcessesOnHold.remove(app);
16401
16402        if (app == mHomeProcess) {
16403            mHomeProcess = null;
16404        }
16405        if (app == mPreviousProcess) {
16406            mPreviousProcess = null;
16407        }
16408
16409        if (restart && !app.isolated) {
16410            // We have components that still need to be running in the
16411            // process, so re-launch it.
16412            if (index < 0) {
16413                ProcessList.remove(app.pid);
16414            }
16415            addProcessNameLocked(app);
16416            startProcessLocked(app, "restart", app.processName);
16417            return true;
16418        } else if (app.pid > 0 && app.pid != MY_PID) {
16419            // Goodbye!
16420            boolean removed;
16421            synchronized (mPidsSelfLocked) {
16422                mPidsSelfLocked.remove(app.pid);
16423                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16424            }
16425            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16426            if (app.isolated) {
16427                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16428            }
16429            app.setPid(0);
16430        }
16431        return false;
16432    }
16433
16434    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16435        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16436            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16437            if (cpr.launchingApp == app) {
16438                return true;
16439            }
16440        }
16441        return false;
16442    }
16443
16444    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16445        // Look through the content providers we are waiting to have launched,
16446        // and if any run in this process then either schedule a restart of
16447        // the process or kill the client waiting for it if this process has
16448        // gone bad.
16449        boolean restart = false;
16450        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16451            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16452            if (cpr.launchingApp == app) {
16453                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16454                    restart = true;
16455                } else {
16456                    removeDyingProviderLocked(app, cpr, true);
16457                }
16458            }
16459        }
16460        return restart;
16461    }
16462
16463    // =========================================================
16464    // SERVICES
16465    // =========================================================
16466
16467    @Override
16468    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16469            int flags) {
16470        enforceNotIsolatedCaller("getServices");
16471        synchronized (this) {
16472            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16473        }
16474    }
16475
16476    @Override
16477    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16478        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16479        synchronized (this) {
16480            return mServices.getRunningServiceControlPanelLocked(name);
16481        }
16482    }
16483
16484    @Override
16485    public ComponentName startService(IApplicationThread caller, Intent service,
16486            String resolvedType, String callingPackage, int userId)
16487            throws TransactionTooLargeException {
16488        enforceNotIsolatedCaller("startService");
16489        // Refuse possible leaked file descriptors
16490        if (service != null && service.hasFileDescriptors() == true) {
16491            throw new IllegalArgumentException("File descriptors passed in Intent");
16492        }
16493
16494        if (callingPackage == null) {
16495            throw new IllegalArgumentException("callingPackage cannot be null");
16496        }
16497
16498        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16499                "startService: " + service + " type=" + resolvedType);
16500        synchronized(this) {
16501            final int callingPid = Binder.getCallingPid();
16502            final int callingUid = Binder.getCallingUid();
16503            final long origId = Binder.clearCallingIdentity();
16504            ComponentName res = mServices.startServiceLocked(caller, service,
16505                    resolvedType, callingPid, callingUid, callingPackage, userId);
16506            Binder.restoreCallingIdentity(origId);
16507            return res;
16508        }
16509    }
16510
16511    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16512            String callingPackage, int userId)
16513            throws TransactionTooLargeException {
16514        synchronized(this) {
16515            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16516                    "startServiceInPackage: " + service + " type=" + resolvedType);
16517            final long origId = Binder.clearCallingIdentity();
16518            ComponentName res = mServices.startServiceLocked(null, service,
16519                    resolvedType, -1, uid, callingPackage, userId);
16520            Binder.restoreCallingIdentity(origId);
16521            return res;
16522        }
16523    }
16524
16525    @Override
16526    public int stopService(IApplicationThread caller, Intent service,
16527            String resolvedType, int userId) {
16528        enforceNotIsolatedCaller("stopService");
16529        // Refuse possible leaked file descriptors
16530        if (service != null && service.hasFileDescriptors() == true) {
16531            throw new IllegalArgumentException("File descriptors passed in Intent");
16532        }
16533
16534        synchronized(this) {
16535            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16536        }
16537    }
16538
16539    @Override
16540    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16541        enforceNotIsolatedCaller("peekService");
16542        // Refuse possible leaked file descriptors
16543        if (service != null && service.hasFileDescriptors() == true) {
16544            throw new IllegalArgumentException("File descriptors passed in Intent");
16545        }
16546
16547        if (callingPackage == null) {
16548            throw new IllegalArgumentException("callingPackage cannot be null");
16549        }
16550
16551        synchronized(this) {
16552            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16553        }
16554    }
16555
16556    @Override
16557    public boolean stopServiceToken(ComponentName className, IBinder token,
16558            int startId) {
16559        synchronized(this) {
16560            return mServices.stopServiceTokenLocked(className, token, startId);
16561        }
16562    }
16563
16564    @Override
16565    public void setServiceForeground(ComponentName className, IBinder token,
16566            int id, Notification notification, int flags) {
16567        synchronized(this) {
16568            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16569        }
16570    }
16571
16572    @Override
16573    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16574            boolean requireFull, String name, String callerPackage) {
16575        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16576                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16577    }
16578
16579    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16580            String className, int flags) {
16581        boolean result = false;
16582        // For apps that don't have pre-defined UIDs, check for permission
16583        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16584            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16585                if (ActivityManager.checkUidPermission(
16586                        INTERACT_ACROSS_USERS,
16587                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16588                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16589                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16590                            + " requests FLAG_SINGLE_USER, but app does not hold "
16591                            + INTERACT_ACROSS_USERS;
16592                    Slog.w(TAG, msg);
16593                    throw new SecurityException(msg);
16594                }
16595                // Permission passed
16596                result = true;
16597            }
16598        } else if ("system".equals(componentProcessName)) {
16599            result = true;
16600        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16601            // Phone app and persistent apps are allowed to export singleuser providers.
16602            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16603                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16604        }
16605        if (DEBUG_MU) Slog.v(TAG_MU,
16606                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16607                + Integer.toHexString(flags) + ") = " + result);
16608        return result;
16609    }
16610
16611    /**
16612     * Checks to see if the caller is in the same app as the singleton
16613     * component, or the component is in a special app. It allows special apps
16614     * to export singleton components but prevents exporting singleton
16615     * components for regular apps.
16616     */
16617    boolean isValidSingletonCall(int callingUid, int componentUid) {
16618        int componentAppId = UserHandle.getAppId(componentUid);
16619        return UserHandle.isSameApp(callingUid, componentUid)
16620                || componentAppId == Process.SYSTEM_UID
16621                || componentAppId == Process.PHONE_UID
16622                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16623                        == PackageManager.PERMISSION_GRANTED;
16624    }
16625
16626    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16627            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16628            int userId) throws TransactionTooLargeException {
16629        enforceNotIsolatedCaller("bindService");
16630
16631        // Refuse possible leaked file descriptors
16632        if (service != null && service.hasFileDescriptors() == true) {
16633            throw new IllegalArgumentException("File descriptors passed in Intent");
16634        }
16635
16636        if (callingPackage == null) {
16637            throw new IllegalArgumentException("callingPackage cannot be null");
16638        }
16639
16640        synchronized(this) {
16641            return mServices.bindServiceLocked(caller, token, service,
16642                    resolvedType, connection, flags, callingPackage, userId);
16643        }
16644    }
16645
16646    public boolean unbindService(IServiceConnection connection) {
16647        synchronized (this) {
16648            return mServices.unbindServiceLocked(connection);
16649        }
16650    }
16651
16652    public void publishService(IBinder token, Intent intent, IBinder service) {
16653        // Refuse possible leaked file descriptors
16654        if (intent != null && intent.hasFileDescriptors() == true) {
16655            throw new IllegalArgumentException("File descriptors passed in Intent");
16656        }
16657
16658        synchronized(this) {
16659            if (!(token instanceof ServiceRecord)) {
16660                throw new IllegalArgumentException("Invalid service token");
16661            }
16662            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16663        }
16664    }
16665
16666    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16667        // Refuse possible leaked file descriptors
16668        if (intent != null && intent.hasFileDescriptors() == true) {
16669            throw new IllegalArgumentException("File descriptors passed in Intent");
16670        }
16671
16672        synchronized(this) {
16673            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16674        }
16675    }
16676
16677    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16678        synchronized(this) {
16679            if (!(token instanceof ServiceRecord)) {
16680                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16681                throw new IllegalArgumentException("Invalid service token");
16682            }
16683            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16684        }
16685    }
16686
16687    // =========================================================
16688    // BACKUP AND RESTORE
16689    // =========================================================
16690
16691    // Cause the target app to be launched if necessary and its backup agent
16692    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16693    // activity manager to announce its creation.
16694    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16695        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16696                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16697        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16698
16699        synchronized(this) {
16700            // !!! TODO: currently no check here that we're already bound
16701            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16702            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16703            synchronized (stats) {
16704                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16705            }
16706
16707            // Backup agent is now in use, its package can't be stopped.
16708            try {
16709                AppGlobals.getPackageManager().setPackageStoppedState(
16710                        app.packageName, false, UserHandle.getUserId(app.uid));
16711            } catch (RemoteException e) {
16712            } catch (IllegalArgumentException e) {
16713                Slog.w(TAG, "Failed trying to unstop package "
16714                        + app.packageName + ": " + e);
16715            }
16716
16717            BackupRecord r = new BackupRecord(ss, app, backupMode);
16718            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16719                    ? new ComponentName(app.packageName, app.backupAgentName)
16720                    : new ComponentName("android", "FullBackupAgent");
16721            // startProcessLocked() returns existing proc's record if it's already running
16722            ProcessRecord proc = startProcessLocked(app.processName, app,
16723                    false, 0, "backup", hostingName, false, false, false);
16724            if (proc == null) {
16725                Slog.e(TAG, "Unable to start backup agent process " + r);
16726                return false;
16727            }
16728
16729            r.app = proc;
16730            mBackupTarget = r;
16731            mBackupAppName = app.packageName;
16732
16733            // Try not to kill the process during backup
16734            updateOomAdjLocked(proc);
16735
16736            // If the process is already attached, schedule the creation of the backup agent now.
16737            // If it is not yet live, this will be done when it attaches to the framework.
16738            if (proc.thread != null) {
16739                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16740                try {
16741                    proc.thread.scheduleCreateBackupAgent(app,
16742                            compatibilityInfoForPackageLocked(app), backupMode);
16743                } catch (RemoteException e) {
16744                    // Will time out on the backup manager side
16745                }
16746            } else {
16747                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16748            }
16749            // Invariants: at this point, the target app process exists and the application
16750            // is either already running or in the process of coming up.  mBackupTarget and
16751            // mBackupAppName describe the app, so that when it binds back to the AM we
16752            // know that it's scheduled for a backup-agent operation.
16753        }
16754
16755        return true;
16756    }
16757
16758    @Override
16759    public void clearPendingBackup() {
16760        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16761        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16762
16763        synchronized (this) {
16764            mBackupTarget = null;
16765            mBackupAppName = null;
16766        }
16767    }
16768
16769    // A backup agent has just come up
16770    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16771        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16772                + " = " + agent);
16773
16774        synchronized(this) {
16775            if (!agentPackageName.equals(mBackupAppName)) {
16776                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16777                return;
16778            }
16779        }
16780
16781        long oldIdent = Binder.clearCallingIdentity();
16782        try {
16783            IBackupManager bm = IBackupManager.Stub.asInterface(
16784                    ServiceManager.getService(Context.BACKUP_SERVICE));
16785            bm.agentConnected(agentPackageName, agent);
16786        } catch (RemoteException e) {
16787            // can't happen; the backup manager service is local
16788        } catch (Exception e) {
16789            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16790            e.printStackTrace();
16791        } finally {
16792            Binder.restoreCallingIdentity(oldIdent);
16793        }
16794    }
16795
16796    // done with this agent
16797    public void unbindBackupAgent(ApplicationInfo appInfo) {
16798        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16799        if (appInfo == null) {
16800            Slog.w(TAG, "unbind backup agent for null app");
16801            return;
16802        }
16803
16804        synchronized(this) {
16805            try {
16806                if (mBackupAppName == null) {
16807                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16808                    return;
16809                }
16810
16811                if (!mBackupAppName.equals(appInfo.packageName)) {
16812                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16813                    return;
16814                }
16815
16816                // Not backing this app up any more; reset its OOM adjustment
16817                final ProcessRecord proc = mBackupTarget.app;
16818                updateOomAdjLocked(proc);
16819
16820                // If the app crashed during backup, 'thread' will be null here
16821                if (proc.thread != null) {
16822                    try {
16823                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16824                                compatibilityInfoForPackageLocked(appInfo));
16825                    } catch (Exception e) {
16826                        Slog.e(TAG, "Exception when unbinding backup agent:");
16827                        e.printStackTrace();
16828                    }
16829                }
16830            } finally {
16831                mBackupTarget = null;
16832                mBackupAppName = null;
16833            }
16834        }
16835    }
16836    // =========================================================
16837    // BROADCASTS
16838    // =========================================================
16839
16840    boolean isPendingBroadcastProcessLocked(int pid) {
16841        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16842                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16843    }
16844
16845    void skipPendingBroadcastLocked(int pid) {
16846            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16847            for (BroadcastQueue queue : mBroadcastQueues) {
16848                queue.skipPendingBroadcastLocked(pid);
16849            }
16850    }
16851
16852    // The app just attached; send any pending broadcasts that it should receive
16853    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16854        boolean didSomething = false;
16855        for (BroadcastQueue queue : mBroadcastQueues) {
16856            didSomething |= queue.sendPendingBroadcastsLocked(app);
16857        }
16858        return didSomething;
16859    }
16860
16861    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16862            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16863        enforceNotIsolatedCaller("registerReceiver");
16864        ArrayList<Intent> stickyIntents = null;
16865        ProcessRecord callerApp = null;
16866        int callingUid;
16867        int callingPid;
16868        synchronized(this) {
16869            if (caller != null) {
16870                callerApp = getRecordForAppLocked(caller);
16871                if (callerApp == null) {
16872                    throw new SecurityException(
16873                            "Unable to find app for caller " + caller
16874                            + " (pid=" + Binder.getCallingPid()
16875                            + ") when registering receiver " + receiver);
16876                }
16877                if (callerApp.info.uid != Process.SYSTEM_UID &&
16878                        !callerApp.pkgList.containsKey(callerPackage) &&
16879                        !"android".equals(callerPackage)) {
16880                    throw new SecurityException("Given caller package " + callerPackage
16881                            + " is not running in process " + callerApp);
16882                }
16883                callingUid = callerApp.info.uid;
16884                callingPid = callerApp.pid;
16885            } else {
16886                callerPackage = null;
16887                callingUid = Binder.getCallingUid();
16888                callingPid = Binder.getCallingPid();
16889            }
16890
16891            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16892                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16893
16894            Iterator<String> actions = filter.actionsIterator();
16895            if (actions == null) {
16896                ArrayList<String> noAction = new ArrayList<String>(1);
16897                noAction.add(null);
16898                actions = noAction.iterator();
16899            }
16900
16901            // Collect stickies of users
16902            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16903            while (actions.hasNext()) {
16904                String action = actions.next();
16905                for (int id : userIds) {
16906                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16907                    if (stickies != null) {
16908                        ArrayList<Intent> intents = stickies.get(action);
16909                        if (intents != null) {
16910                            if (stickyIntents == null) {
16911                                stickyIntents = new ArrayList<Intent>();
16912                            }
16913                            stickyIntents.addAll(intents);
16914                        }
16915                    }
16916                }
16917            }
16918        }
16919
16920        ArrayList<Intent> allSticky = null;
16921        if (stickyIntents != null) {
16922            final ContentResolver resolver = mContext.getContentResolver();
16923            // Look for any matching sticky broadcasts...
16924            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16925                Intent intent = stickyIntents.get(i);
16926                // If intent has scheme "content", it will need to acccess
16927                // provider that needs to lock mProviderMap in ActivityThread
16928                // and also it may need to wait application response, so we
16929                // cannot lock ActivityManagerService here.
16930                if (filter.match(resolver, intent, true, TAG) >= 0) {
16931                    if (allSticky == null) {
16932                        allSticky = new ArrayList<Intent>();
16933                    }
16934                    allSticky.add(intent);
16935                }
16936            }
16937        }
16938
16939        // The first sticky in the list is returned directly back to the client.
16940        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16941        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16942        if (receiver == null) {
16943            return sticky;
16944        }
16945
16946        synchronized (this) {
16947            if (callerApp != null && (callerApp.thread == null
16948                    || callerApp.thread.asBinder() != caller.asBinder())) {
16949                // Original caller already died
16950                return null;
16951            }
16952            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16953            if (rl == null) {
16954                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16955                        userId, receiver);
16956                if (rl.app != null) {
16957                    rl.app.receivers.add(rl);
16958                } else {
16959                    try {
16960                        receiver.asBinder().linkToDeath(rl, 0);
16961                    } catch (RemoteException e) {
16962                        return sticky;
16963                    }
16964                    rl.linkedToDeath = true;
16965                }
16966                mRegisteredReceivers.put(receiver.asBinder(), rl);
16967            } else if (rl.uid != callingUid) {
16968                throw new IllegalArgumentException(
16969                        "Receiver requested to register for uid " + callingUid
16970                        + " was previously registered for uid " + rl.uid);
16971            } else if (rl.pid != callingPid) {
16972                throw new IllegalArgumentException(
16973                        "Receiver requested to register for pid " + callingPid
16974                        + " was previously registered for pid " + rl.pid);
16975            } else if (rl.userId != userId) {
16976                throw new IllegalArgumentException(
16977                        "Receiver requested to register for user " + userId
16978                        + " was previously registered for user " + rl.userId);
16979            }
16980            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16981                    permission, callingUid, userId);
16982            rl.add(bf);
16983            if (!bf.debugCheck()) {
16984                Slog.w(TAG, "==> For Dynamic broadcast");
16985            }
16986            mReceiverResolver.addFilter(bf);
16987
16988            // Enqueue broadcasts for all existing stickies that match
16989            // this filter.
16990            if (allSticky != null) {
16991                ArrayList receivers = new ArrayList();
16992                receivers.add(bf);
16993
16994                final int stickyCount = allSticky.size();
16995                for (int i = 0; i < stickyCount; i++) {
16996                    Intent intent = allSticky.get(i);
16997                    BroadcastQueue queue = broadcastQueueForIntent(intent);
16998                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16999                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17000                            null, 0, null, null, false, true, true, -1);
17001                    queue.enqueueParallelBroadcastLocked(r);
17002                    queue.scheduleBroadcastsLocked();
17003                }
17004            }
17005
17006            return sticky;
17007        }
17008    }
17009
17010    public void unregisterReceiver(IIntentReceiver receiver) {
17011        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17012
17013        final long origId = Binder.clearCallingIdentity();
17014        try {
17015            boolean doTrim = false;
17016
17017            synchronized(this) {
17018                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17019                if (rl != null) {
17020                    final BroadcastRecord r = rl.curBroadcast;
17021                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17022                        final boolean doNext = r.queue.finishReceiverLocked(
17023                                r, r.resultCode, r.resultData, r.resultExtras,
17024                                r.resultAbort, false);
17025                        if (doNext) {
17026                            doTrim = true;
17027                            r.queue.processNextBroadcast(false);
17028                        }
17029                    }
17030
17031                    if (rl.app != null) {
17032                        rl.app.receivers.remove(rl);
17033                    }
17034                    removeReceiverLocked(rl);
17035                    if (rl.linkedToDeath) {
17036                        rl.linkedToDeath = false;
17037                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17038                    }
17039                }
17040            }
17041
17042            // If we actually concluded any broadcasts, we might now be able
17043            // to trim the recipients' apps from our working set
17044            if (doTrim) {
17045                trimApplications();
17046                return;
17047            }
17048
17049        } finally {
17050            Binder.restoreCallingIdentity(origId);
17051        }
17052    }
17053
17054    void removeReceiverLocked(ReceiverList rl) {
17055        mRegisteredReceivers.remove(rl.receiver.asBinder());
17056        for (int i = rl.size() - 1; i >= 0; i--) {
17057            mReceiverResolver.removeFilter(rl.get(i));
17058        }
17059    }
17060
17061    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17062        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17063            ProcessRecord r = mLruProcesses.get(i);
17064            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17065                try {
17066                    r.thread.dispatchPackageBroadcast(cmd, packages);
17067                } catch (RemoteException ex) {
17068                }
17069            }
17070        }
17071    }
17072
17073    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17074            int callingUid, int[] users) {
17075        // TODO: come back and remove this assumption to triage all broadcasts
17076        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17077
17078        List<ResolveInfo> receivers = null;
17079        try {
17080            HashSet<ComponentName> singleUserReceivers = null;
17081            boolean scannedFirstReceivers = false;
17082            for (int user : users) {
17083                // Skip users that have Shell restrictions, with exception of always permitted
17084                // Shell broadcasts
17085                if (callingUid == Process.SHELL_UID
17086                        && mUserController.hasUserRestriction(
17087                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17088                        && !isPermittedShellBroadcast(intent)) {
17089                    continue;
17090                }
17091                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17092                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17093                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17094                    // If this is not the system user, we need to check for
17095                    // any receivers that should be filtered out.
17096                    for (int i=0; i<newReceivers.size(); i++) {
17097                        ResolveInfo ri = newReceivers.get(i);
17098                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17099                            newReceivers.remove(i);
17100                            i--;
17101                        }
17102                    }
17103                }
17104                if (newReceivers != null && newReceivers.size() == 0) {
17105                    newReceivers = null;
17106                }
17107                if (receivers == null) {
17108                    receivers = newReceivers;
17109                } else if (newReceivers != null) {
17110                    // We need to concatenate the additional receivers
17111                    // found with what we have do far.  This would be easy,
17112                    // but we also need to de-dup any receivers that are
17113                    // singleUser.
17114                    if (!scannedFirstReceivers) {
17115                        // Collect any single user receivers we had already retrieved.
17116                        scannedFirstReceivers = true;
17117                        for (int i=0; i<receivers.size(); i++) {
17118                            ResolveInfo ri = receivers.get(i);
17119                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17120                                ComponentName cn = new ComponentName(
17121                                        ri.activityInfo.packageName, ri.activityInfo.name);
17122                                if (singleUserReceivers == null) {
17123                                    singleUserReceivers = new HashSet<ComponentName>();
17124                                }
17125                                singleUserReceivers.add(cn);
17126                            }
17127                        }
17128                    }
17129                    // Add the new results to the existing results, tracking
17130                    // and de-dupping single user receivers.
17131                    for (int i=0; i<newReceivers.size(); i++) {
17132                        ResolveInfo ri = newReceivers.get(i);
17133                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17134                            ComponentName cn = new ComponentName(
17135                                    ri.activityInfo.packageName, ri.activityInfo.name);
17136                            if (singleUserReceivers == null) {
17137                                singleUserReceivers = new HashSet<ComponentName>();
17138                            }
17139                            if (!singleUserReceivers.contains(cn)) {
17140                                singleUserReceivers.add(cn);
17141                                receivers.add(ri);
17142                            }
17143                        } else {
17144                            receivers.add(ri);
17145                        }
17146                    }
17147                }
17148            }
17149        } catch (RemoteException ex) {
17150            // pm is in same process, this will never happen.
17151        }
17152        return receivers;
17153    }
17154
17155    private boolean isPermittedShellBroadcast(Intent intent) {
17156        // remote bugreport should always be allowed to be taken
17157        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17158    }
17159
17160    final int broadcastIntentLocked(ProcessRecord callerApp,
17161            String callerPackage, Intent intent, String resolvedType,
17162            IIntentReceiver resultTo, int resultCode, String resultData,
17163            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17164            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17165        intent = new Intent(intent);
17166
17167        // By default broadcasts do not go to stopped apps.
17168        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17169
17170        // If we have not finished booting, don't allow this to launch new processes.
17171        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17172            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17173        }
17174
17175        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17176                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17177                + " ordered=" + ordered + " userid=" + userId);
17178        if ((resultTo != null) && !ordered) {
17179            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17180        }
17181
17182        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17183                ALLOW_NON_FULL, "broadcast", callerPackage);
17184
17185        // Make sure that the user who is receiving this broadcast is running.
17186        // If not, we will just skip it. Make an exception for shutdown broadcasts
17187        // and upgrade steps.
17188
17189        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17190            if ((callingUid != Process.SYSTEM_UID
17191                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17192                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17193                Slog.w(TAG, "Skipping broadcast of " + intent
17194                        + ": user " + userId + " is stopped");
17195                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17196            }
17197        }
17198
17199        BroadcastOptions brOptions = null;
17200        if (bOptions != null) {
17201            brOptions = new BroadcastOptions(bOptions);
17202            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17203                // See if the caller is allowed to do this.  Note we are checking against
17204                // the actual real caller (not whoever provided the operation as say a
17205                // PendingIntent), because that who is actually supplied the arguments.
17206                if (checkComponentPermission(
17207                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17208                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17209                        != PackageManager.PERMISSION_GRANTED) {
17210                    String msg = "Permission Denial: " + intent.getAction()
17211                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17212                            + ", uid=" + callingUid + ")"
17213                            + " requires "
17214                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17215                    Slog.w(TAG, msg);
17216                    throw new SecurityException(msg);
17217                }
17218            }
17219        }
17220
17221        // Verify that protected broadcasts are only being sent by system code,
17222        // and that system code is only sending protected broadcasts.
17223        final String action = intent.getAction();
17224        final boolean isProtectedBroadcast;
17225        try {
17226            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17227        } catch (RemoteException e) {
17228            Slog.w(TAG, "Remote exception", e);
17229            return ActivityManager.BROADCAST_SUCCESS;
17230        }
17231
17232        final boolean isCallerSystem;
17233        switch (UserHandle.getAppId(callingUid)) {
17234            case Process.ROOT_UID:
17235            case Process.SYSTEM_UID:
17236            case Process.PHONE_UID:
17237            case Process.BLUETOOTH_UID:
17238            case Process.NFC_UID:
17239                isCallerSystem = true;
17240                break;
17241            default:
17242                isCallerSystem = (callerApp != null) && callerApp.persistent;
17243                break;
17244        }
17245
17246        if (isCallerSystem) {
17247            if (isProtectedBroadcast
17248                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17249                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17250                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17251                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17252                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17253                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17254                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17255                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17256                // Broadcast is either protected, or it's a public action that
17257                // we've relaxed, so it's fine for system internals to send.
17258            } else {
17259                // The vast majority of broadcasts sent from system internals
17260                // should be protected to avoid security holes, so yell loudly
17261                // to ensure we examine these cases.
17262                Log.wtf(TAG, "Sending non-protected broadcast " + action
17263                        + " from system", new Throwable());
17264            }
17265
17266        } else {
17267            if (isProtectedBroadcast) {
17268                String msg = "Permission Denial: not allowed to send broadcast "
17269                        + action + " from pid="
17270                        + callingPid + ", uid=" + callingUid;
17271                Slog.w(TAG, msg);
17272                throw new SecurityException(msg);
17273
17274            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17275                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17276                // Special case for compatibility: we don't want apps to send this,
17277                // but historically it has not been protected and apps may be using it
17278                // to poke their own app widget.  So, instead of making it protected,
17279                // just limit it to the caller.
17280                if (callerPackage == null) {
17281                    String msg = "Permission Denial: not allowed to send broadcast "
17282                            + action + " from unknown caller.";
17283                    Slog.w(TAG, msg);
17284                    throw new SecurityException(msg);
17285                } else if (intent.getComponent() != null) {
17286                    // They are good enough to send to an explicit component...  verify
17287                    // it is being sent to the calling app.
17288                    if (!intent.getComponent().getPackageName().equals(
17289                            callerPackage)) {
17290                        String msg = "Permission Denial: not allowed to send broadcast "
17291                                + action + " to "
17292                                + intent.getComponent().getPackageName() + " from "
17293                                + callerPackage;
17294                        Slog.w(TAG, msg);
17295                        throw new SecurityException(msg);
17296                    }
17297                } else {
17298                    // Limit broadcast to their own package.
17299                    intent.setPackage(callerPackage);
17300                }
17301            }
17302        }
17303
17304        if (action != null) {
17305            switch (action) {
17306                case Intent.ACTION_UID_REMOVED:
17307                case Intent.ACTION_PACKAGE_REMOVED:
17308                case Intent.ACTION_PACKAGE_CHANGED:
17309                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17310                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17311                case Intent.ACTION_PACKAGES_SUSPENDED:
17312                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17313                    // Handle special intents: if this broadcast is from the package
17314                    // manager about a package being removed, we need to remove all of
17315                    // its activities from the history stack.
17316                    if (checkComponentPermission(
17317                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17318                            callingPid, callingUid, -1, true)
17319                            != PackageManager.PERMISSION_GRANTED) {
17320                        String msg = "Permission Denial: " + intent.getAction()
17321                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17322                                + ", uid=" + callingUid + ")"
17323                                + " requires "
17324                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17325                        Slog.w(TAG, msg);
17326                        throw new SecurityException(msg);
17327                    }
17328                    switch (action) {
17329                        case Intent.ACTION_UID_REMOVED:
17330                            final Bundle intentExtras = intent.getExtras();
17331                            final int uid = intentExtras != null
17332                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17333                            if (uid >= 0) {
17334                                mBatteryStatsService.removeUid(uid);
17335                                mAppOpsService.uidRemoved(uid);
17336                            }
17337                            break;
17338                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17339                            // If resources are unavailable just force stop all those packages
17340                            // and flush the attribute cache as well.
17341                            String list[] =
17342                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17343                            if (list != null && list.length > 0) {
17344                                for (int i = 0; i < list.length; i++) {
17345                                    forceStopPackageLocked(list[i], -1, false, true, true,
17346                                            false, false, userId, "storage unmount");
17347                                }
17348                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17349                                sendPackageBroadcastLocked(
17350                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17351                                        userId);
17352                            }
17353                            break;
17354                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17355                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17356                            break;
17357                        case Intent.ACTION_PACKAGE_REMOVED:
17358                        case Intent.ACTION_PACKAGE_CHANGED:
17359                            Uri data = intent.getData();
17360                            String ssp;
17361                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17362                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17363                                final boolean replacing =
17364                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17365                                final boolean killProcess =
17366                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17367                                final boolean fullUninstall = removed && !replacing;
17368                                if (killProcess) {
17369                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17370                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17371                                            false, true, true, false, fullUninstall, userId,
17372                                            removed ? "pkg removed" : "pkg changed");
17373                                }
17374                                if (removed) {
17375                                    final int cmd = killProcess
17376                                            ? IApplicationThread.PACKAGE_REMOVED
17377                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17378                                    sendPackageBroadcastLocked(cmd,
17379                                            new String[] {ssp}, userId);
17380                                    if (fullUninstall) {
17381                                        mAppOpsService.packageRemoved(
17382                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17383
17384                                        // Remove all permissions granted from/to this package
17385                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17386
17387                                        removeTasksByPackageNameLocked(ssp, userId);
17388                                        mBatteryStatsService.notePackageUninstalled(ssp);
17389                                    }
17390                                } else {
17391                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17392                                            intent.getStringArrayExtra(
17393                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17394                                }
17395                            }
17396                            break;
17397                        case Intent.ACTION_PACKAGES_SUSPENDED:
17398                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17399                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17400                                    intent.getAction());
17401                            final String[] packageNames = intent.getStringArrayExtra(
17402                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17403                            final int userHandle = intent.getIntExtra(
17404                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17405
17406                            synchronized(ActivityManagerService.this) {
17407                                mRecentTasks.onPackagesSuspendedChanged(
17408                                        packageNames, suspended, userHandle);
17409                            }
17410                            break;
17411                    }
17412                    break;
17413                case Intent.ACTION_PACKAGE_REPLACED:
17414                {
17415                    final Uri data = intent.getData();
17416                    final String ssp;
17417                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17418                        final ApplicationInfo aInfo =
17419                                getPackageManagerInternalLocked().getApplicationInfo(
17420                                        ssp,
17421                                        userId);
17422                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17423                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17424                                new String[] {ssp}, userId);
17425                    }
17426                    break;
17427                }
17428                case Intent.ACTION_PACKAGE_ADDED:
17429                {
17430                    // Special case for adding a package: by default turn on compatibility mode.
17431                    Uri data = intent.getData();
17432                    String ssp;
17433                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17434                        final boolean replacing =
17435                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17436                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17437
17438                        try {
17439                            ApplicationInfo ai = AppGlobals.getPackageManager().
17440                                    getApplicationInfo(ssp, 0, 0);
17441                            mBatteryStatsService.notePackageInstalled(ssp,
17442                                    ai != null ? ai.versionCode : 0);
17443                        } catch (RemoteException e) {
17444                        }
17445                    }
17446                    break;
17447                }
17448                case Intent.ACTION_TIMEZONE_CHANGED:
17449                    // If this is the time zone changed action, queue up a message that will reset
17450                    // the timezone of all currently running processes. This message will get
17451                    // queued up before the broadcast happens.
17452                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17453                    break;
17454                case Intent.ACTION_TIME_CHANGED:
17455                    // If the user set the time, let all running processes know.
17456                    final int is24Hour =
17457                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17458                                    : 0;
17459                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17460                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17461                    synchronized (stats) {
17462                        stats.noteCurrentTimeChangedLocked();
17463                    }
17464                    break;
17465                case Intent.ACTION_CLEAR_DNS_CACHE:
17466                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17467                    break;
17468                case Proxy.PROXY_CHANGE_ACTION:
17469                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17470                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17471                    break;
17472                case android.hardware.Camera.ACTION_NEW_PICTURE:
17473                case android.hardware.Camera.ACTION_NEW_VIDEO:
17474                    // These broadcasts are no longer allowed by the system, since they can
17475                    // cause significant thrashing at a crictical point (using the camera).
17476                    // Apps should use JobScehduler to monitor for media provider changes.
17477                    Slog.w(TAG, action + " no longer allowed; dropping from "
17478                            + UserHandle.formatUid(callingUid));
17479                    // Lie; we don't want to crash the app.
17480                    return ActivityManager.BROADCAST_SUCCESS;
17481            }
17482        }
17483
17484        // Add to the sticky list if requested.
17485        if (sticky) {
17486            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17487                    callingPid, callingUid)
17488                    != PackageManager.PERMISSION_GRANTED) {
17489                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17490                        + callingPid + ", uid=" + callingUid
17491                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17492                Slog.w(TAG, msg);
17493                throw new SecurityException(msg);
17494            }
17495            if (requiredPermissions != null && requiredPermissions.length > 0) {
17496                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17497                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17498                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17499            }
17500            if (intent.getComponent() != null) {
17501                throw new SecurityException(
17502                        "Sticky broadcasts can't target a specific component");
17503            }
17504            // We use userId directly here, since the "all" target is maintained
17505            // as a separate set of sticky broadcasts.
17506            if (userId != UserHandle.USER_ALL) {
17507                // But first, if this is not a broadcast to all users, then
17508                // make sure it doesn't conflict with an existing broadcast to
17509                // all users.
17510                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17511                        UserHandle.USER_ALL);
17512                if (stickies != null) {
17513                    ArrayList<Intent> list = stickies.get(intent.getAction());
17514                    if (list != null) {
17515                        int N = list.size();
17516                        int i;
17517                        for (i=0; i<N; i++) {
17518                            if (intent.filterEquals(list.get(i))) {
17519                                throw new IllegalArgumentException(
17520                                        "Sticky broadcast " + intent + " for user "
17521                                        + userId + " conflicts with existing global broadcast");
17522                            }
17523                        }
17524                    }
17525                }
17526            }
17527            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17528            if (stickies == null) {
17529                stickies = new ArrayMap<>();
17530                mStickyBroadcasts.put(userId, stickies);
17531            }
17532            ArrayList<Intent> list = stickies.get(intent.getAction());
17533            if (list == null) {
17534                list = new ArrayList<>();
17535                stickies.put(intent.getAction(), list);
17536            }
17537            final int stickiesCount = list.size();
17538            int i;
17539            for (i = 0; i < stickiesCount; i++) {
17540                if (intent.filterEquals(list.get(i))) {
17541                    // This sticky already exists, replace it.
17542                    list.set(i, new Intent(intent));
17543                    break;
17544                }
17545            }
17546            if (i >= stickiesCount) {
17547                list.add(new Intent(intent));
17548            }
17549        }
17550
17551        int[] users;
17552        if (userId == UserHandle.USER_ALL) {
17553            // Caller wants broadcast to go to all started users.
17554            users = mUserController.getStartedUserArrayLocked();
17555        } else {
17556            // Caller wants broadcast to go to one specific user.
17557            users = new int[] {userId};
17558        }
17559
17560        // Figure out who all will receive this broadcast.
17561        List receivers = null;
17562        List<BroadcastFilter> registeredReceivers = null;
17563        // Need to resolve the intent to interested receivers...
17564        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17565                 == 0) {
17566            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17567        }
17568        if (intent.getComponent() == null) {
17569            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17570                // Query one target user at a time, excluding shell-restricted users
17571                for (int i = 0; i < users.length; i++) {
17572                    if (mUserController.hasUserRestriction(
17573                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17574                        continue;
17575                    }
17576                    List<BroadcastFilter> registeredReceiversForUser =
17577                            mReceiverResolver.queryIntent(intent,
17578                                    resolvedType, false, users[i]);
17579                    if (registeredReceivers == null) {
17580                        registeredReceivers = registeredReceiversForUser;
17581                    } else if (registeredReceiversForUser != null) {
17582                        registeredReceivers.addAll(registeredReceiversForUser);
17583                    }
17584                }
17585            } else {
17586                registeredReceivers = mReceiverResolver.queryIntent(intent,
17587                        resolvedType, false, userId);
17588            }
17589        }
17590
17591        final boolean replacePending =
17592                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17593
17594        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17595                + " replacePending=" + replacePending);
17596
17597        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17598        if (!ordered && NR > 0) {
17599            // If we are not serializing this broadcast, then send the
17600            // registered receivers separately so they don't wait for the
17601            // components to be launched.
17602            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17603            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17604                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17605                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17606                    resultExtras, ordered, sticky, false, userId);
17607            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17608            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17609            if (!replaced) {
17610                queue.enqueueParallelBroadcastLocked(r);
17611                queue.scheduleBroadcastsLocked();
17612            }
17613            registeredReceivers = null;
17614            NR = 0;
17615        }
17616
17617        // Merge into one list.
17618        int ir = 0;
17619        if (receivers != null) {
17620            // A special case for PACKAGE_ADDED: do not allow the package
17621            // being added to see this broadcast.  This prevents them from
17622            // using this as a back door to get run as soon as they are
17623            // installed.  Maybe in the future we want to have a special install
17624            // broadcast or such for apps, but we'd like to deliberately make
17625            // this decision.
17626            String skipPackages[] = null;
17627            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17628                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17629                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17630                Uri data = intent.getData();
17631                if (data != null) {
17632                    String pkgName = data.getSchemeSpecificPart();
17633                    if (pkgName != null) {
17634                        skipPackages = new String[] { pkgName };
17635                    }
17636                }
17637            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17638                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17639            }
17640            if (skipPackages != null && (skipPackages.length > 0)) {
17641                for (String skipPackage : skipPackages) {
17642                    if (skipPackage != null) {
17643                        int NT = receivers.size();
17644                        for (int it=0; it<NT; it++) {
17645                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17646                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17647                                receivers.remove(it);
17648                                it--;
17649                                NT--;
17650                            }
17651                        }
17652                    }
17653                }
17654            }
17655
17656            int NT = receivers != null ? receivers.size() : 0;
17657            int it = 0;
17658            ResolveInfo curt = null;
17659            BroadcastFilter curr = null;
17660            while (it < NT && ir < NR) {
17661                if (curt == null) {
17662                    curt = (ResolveInfo)receivers.get(it);
17663                }
17664                if (curr == null) {
17665                    curr = registeredReceivers.get(ir);
17666                }
17667                if (curr.getPriority() >= curt.priority) {
17668                    // Insert this broadcast record into the final list.
17669                    receivers.add(it, curr);
17670                    ir++;
17671                    curr = null;
17672                    it++;
17673                    NT++;
17674                } else {
17675                    // Skip to the next ResolveInfo in the final list.
17676                    it++;
17677                    curt = null;
17678                }
17679            }
17680        }
17681        while (ir < NR) {
17682            if (receivers == null) {
17683                receivers = new ArrayList();
17684            }
17685            receivers.add(registeredReceivers.get(ir));
17686            ir++;
17687        }
17688
17689        if ((receivers != null && receivers.size() > 0)
17690                || resultTo != null) {
17691            BroadcastQueue queue = broadcastQueueForIntent(intent);
17692            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17693                    callerPackage, callingPid, callingUid, resolvedType,
17694                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17695                    resultData, resultExtras, ordered, sticky, false, userId);
17696
17697            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17698                    + ": prev had " + queue.mOrderedBroadcasts.size());
17699            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17700                    "Enqueueing broadcast " + r.intent.getAction());
17701
17702            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17703            if (!replaced) {
17704                queue.enqueueOrderedBroadcastLocked(r);
17705                queue.scheduleBroadcastsLocked();
17706            }
17707        }
17708
17709        return ActivityManager.BROADCAST_SUCCESS;
17710    }
17711
17712    final Intent verifyBroadcastLocked(Intent intent) {
17713        // Refuse possible leaked file descriptors
17714        if (intent != null && intent.hasFileDescriptors() == true) {
17715            throw new IllegalArgumentException("File descriptors passed in Intent");
17716        }
17717
17718        int flags = intent.getFlags();
17719
17720        if (!mProcessesReady) {
17721            // if the caller really truly claims to know what they're doing, go
17722            // ahead and allow the broadcast without launching any receivers
17723            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17724                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17725            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17726                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17727                        + " before boot completion");
17728                throw new IllegalStateException("Cannot broadcast before boot completed");
17729            }
17730        }
17731
17732        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17733            throw new IllegalArgumentException(
17734                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17735        }
17736
17737        return intent;
17738    }
17739
17740    public final int broadcastIntent(IApplicationThread caller,
17741            Intent intent, String resolvedType, IIntentReceiver resultTo,
17742            int resultCode, String resultData, Bundle resultExtras,
17743            String[] requiredPermissions, int appOp, Bundle bOptions,
17744            boolean serialized, boolean sticky, int userId) {
17745        enforceNotIsolatedCaller("broadcastIntent");
17746        synchronized(this) {
17747            intent = verifyBroadcastLocked(intent);
17748
17749            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17750            final int callingPid = Binder.getCallingPid();
17751            final int callingUid = Binder.getCallingUid();
17752            final long origId = Binder.clearCallingIdentity();
17753            int res = broadcastIntentLocked(callerApp,
17754                    callerApp != null ? callerApp.info.packageName : null,
17755                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17756                    requiredPermissions, appOp, bOptions, serialized, sticky,
17757                    callingPid, callingUid, userId);
17758            Binder.restoreCallingIdentity(origId);
17759            return res;
17760        }
17761    }
17762
17763
17764    int broadcastIntentInPackage(String packageName, int uid,
17765            Intent intent, String resolvedType, IIntentReceiver resultTo,
17766            int resultCode, String resultData, Bundle resultExtras,
17767            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17768            int userId) {
17769        synchronized(this) {
17770            intent = verifyBroadcastLocked(intent);
17771
17772            final long origId = Binder.clearCallingIdentity();
17773            String[] requiredPermissions = requiredPermission == null ? null
17774                    : new String[] {requiredPermission};
17775            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17776                    resultTo, resultCode, resultData, resultExtras,
17777                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17778                    sticky, -1, uid, userId);
17779            Binder.restoreCallingIdentity(origId);
17780            return res;
17781        }
17782    }
17783
17784    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17785        // Refuse possible leaked file descriptors
17786        if (intent != null && intent.hasFileDescriptors() == true) {
17787            throw new IllegalArgumentException("File descriptors passed in Intent");
17788        }
17789
17790        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17791                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17792
17793        synchronized(this) {
17794            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17795                    != PackageManager.PERMISSION_GRANTED) {
17796                String msg = "Permission Denial: unbroadcastIntent() from pid="
17797                        + Binder.getCallingPid()
17798                        + ", uid=" + Binder.getCallingUid()
17799                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17800                Slog.w(TAG, msg);
17801                throw new SecurityException(msg);
17802            }
17803            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17804            if (stickies != null) {
17805                ArrayList<Intent> list = stickies.get(intent.getAction());
17806                if (list != null) {
17807                    int N = list.size();
17808                    int i;
17809                    for (i=0; i<N; i++) {
17810                        if (intent.filterEquals(list.get(i))) {
17811                            list.remove(i);
17812                            break;
17813                        }
17814                    }
17815                    if (list.size() <= 0) {
17816                        stickies.remove(intent.getAction());
17817                    }
17818                }
17819                if (stickies.size() <= 0) {
17820                    mStickyBroadcasts.remove(userId);
17821                }
17822            }
17823        }
17824    }
17825
17826    void backgroundServicesFinishedLocked(int userId) {
17827        for (BroadcastQueue queue : mBroadcastQueues) {
17828            queue.backgroundServicesFinishedLocked(userId);
17829        }
17830    }
17831
17832    public void finishReceiver(IBinder who, int resultCode, String resultData,
17833            Bundle resultExtras, boolean resultAbort, int flags) {
17834        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17835
17836        // Refuse possible leaked file descriptors
17837        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17838            throw new IllegalArgumentException("File descriptors passed in Bundle");
17839        }
17840
17841        final long origId = Binder.clearCallingIdentity();
17842        try {
17843            boolean doNext = false;
17844            BroadcastRecord r;
17845
17846            synchronized(this) {
17847                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17848                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17849                r = queue.getMatchingOrderedReceiver(who);
17850                if (r != null) {
17851                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17852                        resultData, resultExtras, resultAbort, true);
17853                }
17854            }
17855
17856            if (doNext) {
17857                r.queue.processNextBroadcast(false);
17858            }
17859            trimApplications();
17860        } finally {
17861            Binder.restoreCallingIdentity(origId);
17862        }
17863    }
17864
17865    // =========================================================
17866    // INSTRUMENTATION
17867    // =========================================================
17868
17869    public boolean startInstrumentation(ComponentName className,
17870            String profileFile, int flags, Bundle arguments,
17871            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17872            int userId, String abiOverride) {
17873        enforceNotIsolatedCaller("startInstrumentation");
17874        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17875                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17876        // Refuse possible leaked file descriptors
17877        if (arguments != null && arguments.hasFileDescriptors()) {
17878            throw new IllegalArgumentException("File descriptors passed in Bundle");
17879        }
17880
17881        synchronized(this) {
17882            InstrumentationInfo ii = null;
17883            ApplicationInfo ai = null;
17884            try {
17885                ii = mContext.getPackageManager().getInstrumentationInfo(
17886                    className, STOCK_PM_FLAGS);
17887                ai = AppGlobals.getPackageManager().getApplicationInfo(
17888                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17889            } catch (PackageManager.NameNotFoundException e) {
17890            } catch (RemoteException e) {
17891            }
17892            if (ii == null) {
17893                reportStartInstrumentationFailureLocked(watcher, className,
17894                        "Unable to find instrumentation info for: " + className);
17895                return false;
17896            }
17897            if (ai == null) {
17898                reportStartInstrumentationFailureLocked(watcher, className,
17899                        "Unable to find instrumentation target package: " + ii.targetPackage);
17900                return false;
17901            }
17902            if (!ai.hasCode()) {
17903                reportStartInstrumentationFailureLocked(watcher, className,
17904                        "Instrumentation target has no code: " + ii.targetPackage);
17905                return false;
17906            }
17907
17908            int match = mContext.getPackageManager().checkSignatures(
17909                    ii.targetPackage, ii.packageName);
17910            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17911                String msg = "Permission Denial: starting instrumentation "
17912                        + className + " from pid="
17913                        + Binder.getCallingPid()
17914                        + ", uid=" + Binder.getCallingPid()
17915                        + " not allowed because package " + ii.packageName
17916                        + " does not have a signature matching the target "
17917                        + ii.targetPackage;
17918                reportStartInstrumentationFailureLocked(watcher, className, msg);
17919                throw new SecurityException(msg);
17920            }
17921
17922            final long origId = Binder.clearCallingIdentity();
17923            // Instrumentation can kill and relaunch even persistent processes
17924            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17925                    "start instr");
17926            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17927            app.instrumentationClass = className;
17928            app.instrumentationInfo = ai;
17929            app.instrumentationProfileFile = profileFile;
17930            app.instrumentationArguments = arguments;
17931            app.instrumentationWatcher = watcher;
17932            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17933            app.instrumentationResultClass = className;
17934            Binder.restoreCallingIdentity(origId);
17935        }
17936
17937        return true;
17938    }
17939
17940    /**
17941     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17942     * error to the logs, but if somebody is watching, send the report there too.  This enables
17943     * the "am" command to report errors with more information.
17944     *
17945     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17946     * @param cn The component name of the instrumentation.
17947     * @param report The error report.
17948     */
17949    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17950            ComponentName cn, String report) {
17951        Slog.w(TAG, report);
17952        if (watcher != null) {
17953            Bundle results = new Bundle();
17954            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17955            results.putString("Error", report);
17956            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17957        }
17958    }
17959
17960    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17961        if (app.instrumentationWatcher != null) {
17962            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17963                    app.instrumentationClass, resultCode, results);
17964        }
17965
17966        // Can't call out of the system process with a lock held, so post a message.
17967        if (app.instrumentationUiAutomationConnection != null) {
17968            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17969                    app.instrumentationUiAutomationConnection).sendToTarget();
17970        }
17971
17972        app.instrumentationWatcher = null;
17973        app.instrumentationUiAutomationConnection = null;
17974        app.instrumentationClass = null;
17975        app.instrumentationInfo = null;
17976        app.instrumentationProfileFile = null;
17977        app.instrumentationArguments = null;
17978
17979        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17980                "finished inst");
17981    }
17982
17983    public void finishInstrumentation(IApplicationThread target,
17984            int resultCode, Bundle results) {
17985        int userId = UserHandle.getCallingUserId();
17986        // Refuse possible leaked file descriptors
17987        if (results != null && results.hasFileDescriptors()) {
17988            throw new IllegalArgumentException("File descriptors passed in Intent");
17989        }
17990
17991        synchronized(this) {
17992            ProcessRecord app = getRecordForAppLocked(target);
17993            if (app == null) {
17994                Slog.w(TAG, "finishInstrumentation: no app for " + target);
17995                return;
17996            }
17997            final long origId = Binder.clearCallingIdentity();
17998            finishInstrumentationLocked(app, resultCode, results);
17999            Binder.restoreCallingIdentity(origId);
18000        }
18001    }
18002
18003    // =========================================================
18004    // CONFIGURATION
18005    // =========================================================
18006
18007    public ConfigurationInfo getDeviceConfigurationInfo() {
18008        ConfigurationInfo config = new ConfigurationInfo();
18009        synchronized (this) {
18010            config.reqTouchScreen = mConfiguration.touchscreen;
18011            config.reqKeyboardType = mConfiguration.keyboard;
18012            config.reqNavigation = mConfiguration.navigation;
18013            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18014                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18015                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18016            }
18017            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18018                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18019                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18020            }
18021            config.reqGlEsVersion = GL_ES_VERSION;
18022        }
18023        return config;
18024    }
18025
18026    ActivityStack getFocusedStack() {
18027        return mStackSupervisor.getFocusedStack();
18028    }
18029
18030    @Override
18031    public int getFocusedStackId() throws RemoteException {
18032        ActivityStack focusedStack = getFocusedStack();
18033        if (focusedStack != null) {
18034            return focusedStack.getStackId();
18035        }
18036        return -1;
18037    }
18038
18039    public Configuration getConfiguration() {
18040        Configuration ci;
18041        synchronized(this) {
18042            ci = new Configuration(mConfiguration);
18043            ci.userSetLocale = false;
18044        }
18045        return ci;
18046    }
18047
18048    @Override
18049    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18050        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18051        synchronized (this) {
18052            mSuppressResizeConfigChanges = suppress;
18053        }
18054    }
18055
18056    @Override
18057    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18058        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18059        if (fromStackId == HOME_STACK_ID) {
18060            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18061        }
18062        synchronized (this) {
18063            final long origId = Binder.clearCallingIdentity();
18064            try {
18065                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18066            } finally {
18067                Binder.restoreCallingIdentity(origId);
18068            }
18069        }
18070    }
18071
18072    @Override
18073    public void updatePersistentConfiguration(Configuration values) {
18074        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18075                "updateConfiguration()");
18076        enforceWriteSettingsPermission("updateConfiguration()");
18077        if (values == null) {
18078            throw new NullPointerException("Configuration must not be null");
18079        }
18080
18081        int userId = UserHandle.getCallingUserId();
18082
18083        synchronized(this) {
18084            final long origId = Binder.clearCallingIdentity();
18085            updateConfigurationLocked(values, null, false, true, userId);
18086            Binder.restoreCallingIdentity(origId);
18087        }
18088    }
18089
18090    private void updateFontScaleIfNeeded() {
18091        final int currentUserId;
18092        synchronized(this) {
18093            currentUserId = mUserController.getCurrentUserIdLocked();
18094        }
18095        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18096                FONT_SCALE, 1.0f, currentUserId);
18097        if (mConfiguration.fontScale != scaleFactor) {
18098            final Configuration configuration = mWindowManager.computeNewConfiguration();
18099            configuration.fontScale = scaleFactor;
18100            updatePersistentConfiguration(configuration);
18101        }
18102    }
18103
18104    private void enforceWriteSettingsPermission(String func) {
18105        int uid = Binder.getCallingUid();
18106        if (uid == Process.ROOT_UID) {
18107            return;
18108        }
18109
18110        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18111                Settings.getPackageNameForUid(mContext, uid), false)) {
18112            return;
18113        }
18114
18115        String msg = "Permission Denial: " + func + " from pid="
18116                + Binder.getCallingPid()
18117                + ", uid=" + uid
18118                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18119        Slog.w(TAG, msg);
18120        throw new SecurityException(msg);
18121    }
18122
18123    public void updateConfiguration(Configuration values) {
18124        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18125                "updateConfiguration()");
18126
18127        synchronized(this) {
18128            if (values == null && mWindowManager != null) {
18129                // sentinel: fetch the current configuration from the window manager
18130                values = mWindowManager.computeNewConfiguration();
18131            }
18132
18133            if (mWindowManager != null) {
18134                mProcessList.applyDisplaySize(mWindowManager);
18135            }
18136
18137            final long origId = Binder.clearCallingIdentity();
18138            if (values != null) {
18139                Settings.System.clearConfiguration(values);
18140            }
18141            updateConfigurationLocked(values, null, false);
18142            Binder.restoreCallingIdentity(origId);
18143        }
18144    }
18145
18146    void updateUserConfigurationLocked() {
18147        Configuration configuration = new Configuration(mConfiguration);
18148        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18149                mUserController.getCurrentUserIdLocked());
18150        updateConfigurationLocked(configuration, null, false);
18151    }
18152
18153    boolean updateConfigurationLocked(Configuration values,
18154            ActivityRecord starting, boolean initLocale) {
18155        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18156        return updateConfigurationLocked(values, starting, initLocale, false,
18157                UserHandle.USER_NULL);
18158    }
18159
18160    // To cache the list of supported system locales
18161    private String[] mSupportedSystemLocales = null;
18162
18163    /**
18164     * Do either or both things: (1) change the current configuration, and (2)
18165     * make sure the given activity is running with the (now) current
18166     * configuration.  Returns true if the activity has been left running, or
18167     * false if <var>starting</var> is being destroyed to match the new
18168     * configuration.
18169     *
18170     * @param userId is only used when persistent parameter is set to true to persist configuration
18171     *               for that particular user
18172     */
18173    private boolean updateConfigurationLocked(Configuration values,
18174            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18175        int changes = 0;
18176
18177        if (mWindowManager != null) {
18178            mWindowManager.deferSurfaceLayout();
18179        }
18180        if (values != null) {
18181            Configuration newConfig = new Configuration(mConfiguration);
18182            changes = newConfig.updateFrom(values);
18183            if (changes != 0) {
18184                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18185                        "Updating configuration to: " + values);
18186
18187                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18188
18189                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18190                    final Locale locale;
18191                    if (values.getLocales().size() == 1) {
18192                        // This is an optimization to avoid the JNI call when the result of
18193                        // getFirstMatch() does not depend on the supported locales.
18194                        locale = values.getLocales().get(0);
18195                    } else {
18196                        if (mSupportedSystemLocales == null) {
18197                            mSupportedSystemLocales =
18198                                    Resources.getSystem().getAssets().getLocales();
18199                        }
18200                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18201                    }
18202                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18203                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18204                            locale));
18205                }
18206
18207                mConfigurationSeq++;
18208                if (mConfigurationSeq <= 0) {
18209                    mConfigurationSeq = 1;
18210                }
18211                newConfig.seq = mConfigurationSeq;
18212                mConfiguration = newConfig;
18213                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18214                mUsageStatsService.reportConfigurationChange(newConfig,
18215                        mUserController.getCurrentUserIdLocked());
18216                //mUsageStatsService.noteStartConfig(newConfig);
18217
18218                final Configuration configCopy = new Configuration(mConfiguration);
18219
18220                // TODO: If our config changes, should we auto dismiss any currently
18221                // showing dialogs?
18222                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18223
18224                AttributeCache ac = AttributeCache.instance();
18225                if (ac != null) {
18226                    ac.updateConfiguration(configCopy);
18227                }
18228
18229                // Make sure all resources in our process are updated
18230                // right now, so that anyone who is going to retrieve
18231                // resource values after we return will be sure to get
18232                // the new ones.  This is especially important during
18233                // boot, where the first config change needs to guarantee
18234                // all resources have that config before following boot
18235                // code is executed.
18236                mSystemThread.applyConfigurationToResources(configCopy);
18237
18238                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18239                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18240                    msg.obj = new Configuration(configCopy);
18241                    msg.arg1 = userId;
18242                    mHandler.sendMessage(msg);
18243                }
18244
18245                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18246                if (isDensityChange) {
18247                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18248                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18249                }
18250
18251                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18252                    ProcessRecord app = mLruProcesses.get(i);
18253                    try {
18254                        if (app.thread != null) {
18255                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18256                                    + app.processName + " new config " + mConfiguration);
18257                            app.thread.scheduleConfigurationChanged(configCopy);
18258                        }
18259                    } catch (Exception e) {
18260                    }
18261                }
18262                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18263                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18264                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18265                        | Intent.FLAG_RECEIVER_FOREGROUND);
18266                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18267                        null, AppOpsManager.OP_NONE, null, false, false,
18268                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18269                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18270                    // Tell the shortcut manager that the system locale changed.  It needs to know
18271                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18272                    // we "push" from here, rather than having the service listen to the broadcast.
18273                    final ShortcutServiceInternal shortcutService =
18274                            LocalServices.getService(ShortcutServiceInternal.class);
18275                    if (shortcutService != null) {
18276                        shortcutService.onSystemLocaleChangedNoLock();
18277                    }
18278
18279                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18280                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18281                    if (!mProcessesReady) {
18282                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18283                    }
18284                    broadcastIntentLocked(null, null, intent,
18285                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18286                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18287                }
18288            }
18289            // Update the configuration with WM first and check if any of the stacks need to be
18290            // resized due to the configuration change. If so, resize the stacks now and do any
18291            // relaunches if necessary. This way we don't need to relaunch again below in
18292            // ensureActivityConfigurationLocked().
18293            if (mWindowManager != null) {
18294                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18295                if (resizedStacks != null) {
18296                    for (int stackId : resizedStacks) {
18297                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18298                        mStackSupervisor.resizeStackLocked(
18299                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18300                    }
18301                }
18302            }
18303        }
18304
18305        boolean kept = true;
18306        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18307        // mainStack is null during startup.
18308        if (mainStack != null) {
18309            if (changes != 0 && starting == null) {
18310                // If the configuration changed, and the caller is not already
18311                // in the process of starting an activity, then find the top
18312                // activity to check if its configuration needs to change.
18313                starting = mainStack.topRunningActivityLocked();
18314            }
18315
18316            if (starting != null) {
18317                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18318                // And we need to make sure at this point that all other activities
18319                // are made visible with the correct configuration.
18320                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18321                        !PRESERVE_WINDOWS);
18322            }
18323        }
18324        if (mWindowManager != null) {
18325            mWindowManager.continueSurfaceLayout();
18326        }
18327        return kept;
18328    }
18329
18330    /**
18331     * Decide based on the configuration whether we should shouw the ANR,
18332     * crash, etc dialogs.  The idea is that if there is no affordnace to
18333     * press the on-screen buttons, we shouldn't show the dialog.
18334     *
18335     * A thought: SystemUI might also want to get told about this, the Power
18336     * dialog / global actions also might want different behaviors.
18337     */
18338    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18339        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18340                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18341                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18342        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18343                                    == Configuration.UI_MODE_TYPE_CAR);
18344        return inputMethodExists && uiIsNotCarType && !inVrMode;
18345    }
18346
18347    @Override
18348    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18349        synchronized (this) {
18350            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18351            if (srec != null) {
18352                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18353            }
18354        }
18355        return false;
18356    }
18357
18358    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18359            Intent resultData) {
18360
18361        synchronized (this) {
18362            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18363            if (r != null) {
18364                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18365            }
18366            return false;
18367        }
18368    }
18369
18370    public int getLaunchedFromUid(IBinder activityToken) {
18371        ActivityRecord srec;
18372        synchronized (this) {
18373            srec = ActivityRecord.forTokenLocked(activityToken);
18374        }
18375        if (srec == null) {
18376            return -1;
18377        }
18378        return srec.launchedFromUid;
18379    }
18380
18381    public String getLaunchedFromPackage(IBinder activityToken) {
18382        ActivityRecord srec;
18383        synchronized (this) {
18384            srec = ActivityRecord.forTokenLocked(activityToken);
18385        }
18386        if (srec == null) {
18387            return null;
18388        }
18389        return srec.launchedFromPackage;
18390    }
18391
18392    // =========================================================
18393    // LIFETIME MANAGEMENT
18394    // =========================================================
18395
18396    // Returns which broadcast queue the app is the current [or imminent] receiver
18397    // on, or 'null' if the app is not an active broadcast recipient.
18398    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18399        BroadcastRecord r = app.curReceiver;
18400        if (r != null) {
18401            return r.queue;
18402        }
18403
18404        // It's not the current receiver, but it might be starting up to become one
18405        synchronized (this) {
18406            for (BroadcastQueue queue : mBroadcastQueues) {
18407                r = queue.mPendingBroadcast;
18408                if (r != null && r.curApp == app) {
18409                    // found it; report which queue it's in
18410                    return queue;
18411                }
18412            }
18413        }
18414
18415        return null;
18416    }
18417
18418    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18419            int targetUid, ComponentName targetComponent, String targetProcess) {
18420        if (!mTrackingAssociations) {
18421            return null;
18422        }
18423        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18424                = mAssociations.get(targetUid);
18425        if (components == null) {
18426            components = new ArrayMap<>();
18427            mAssociations.put(targetUid, components);
18428        }
18429        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18430        if (sourceUids == null) {
18431            sourceUids = new SparseArray<>();
18432            components.put(targetComponent, sourceUids);
18433        }
18434        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18435        if (sourceProcesses == null) {
18436            sourceProcesses = new ArrayMap<>();
18437            sourceUids.put(sourceUid, sourceProcesses);
18438        }
18439        Association ass = sourceProcesses.get(sourceProcess);
18440        if (ass == null) {
18441            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18442                    targetProcess);
18443            sourceProcesses.put(sourceProcess, ass);
18444        }
18445        ass.mCount++;
18446        ass.mNesting++;
18447        if (ass.mNesting == 1) {
18448            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18449            ass.mLastState = sourceState;
18450        }
18451        return ass;
18452    }
18453
18454    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18455            ComponentName targetComponent) {
18456        if (!mTrackingAssociations) {
18457            return;
18458        }
18459        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18460                = mAssociations.get(targetUid);
18461        if (components == null) {
18462            return;
18463        }
18464        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18465        if (sourceUids == null) {
18466            return;
18467        }
18468        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18469        if (sourceProcesses == null) {
18470            return;
18471        }
18472        Association ass = sourceProcesses.get(sourceProcess);
18473        if (ass == null || ass.mNesting <= 0) {
18474            return;
18475        }
18476        ass.mNesting--;
18477        if (ass.mNesting == 0) {
18478            long uptime = SystemClock.uptimeMillis();
18479            ass.mTime += uptime - ass.mStartTime;
18480            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18481                    += uptime - ass.mLastStateUptime;
18482            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18483        }
18484    }
18485
18486    private void noteUidProcessState(final int uid, final int state) {
18487        mBatteryStatsService.noteUidProcessState(uid, state);
18488        if (mTrackingAssociations) {
18489            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18490                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18491                        = mAssociations.valueAt(i1);
18492                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18493                    SparseArray<ArrayMap<String, Association>> sourceUids
18494                            = targetComponents.valueAt(i2);
18495                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18496                    if (sourceProcesses != null) {
18497                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18498                            Association ass = sourceProcesses.valueAt(i4);
18499                            if (ass.mNesting >= 1) {
18500                                // currently associated
18501                                long uptime = SystemClock.uptimeMillis();
18502                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18503                                        += uptime - ass.mLastStateUptime;
18504                                ass.mLastState = state;
18505                                ass.mLastStateUptime = uptime;
18506                            }
18507                        }
18508                    }
18509                }
18510            }
18511        }
18512    }
18513
18514    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18515            boolean doingAll, long now) {
18516        if (mAdjSeq == app.adjSeq) {
18517            // This adjustment has already been computed.
18518            return app.curRawAdj;
18519        }
18520
18521        if (app.thread == null) {
18522            app.adjSeq = mAdjSeq;
18523            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18524            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18525            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18526        }
18527
18528        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18529        app.adjSource = null;
18530        app.adjTarget = null;
18531        app.empty = false;
18532        app.cached = false;
18533
18534        final int activitiesSize = app.activities.size();
18535
18536        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18537            // The max adjustment doesn't allow this app to be anything
18538            // below foreground, so it is not worth doing work for it.
18539            app.adjType = "fixed";
18540            app.adjSeq = mAdjSeq;
18541            app.curRawAdj = app.maxAdj;
18542            app.foregroundActivities = false;
18543            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18544            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18545            // System processes can do UI, and when they do we want to have
18546            // them trim their memory after the user leaves the UI.  To
18547            // facilitate this, here we need to determine whether or not it
18548            // is currently showing UI.
18549            app.systemNoUi = true;
18550            if (app == TOP_APP) {
18551                app.systemNoUi = false;
18552            } else if (activitiesSize > 0) {
18553                for (int j = 0; j < activitiesSize; j++) {
18554                    final ActivityRecord r = app.activities.get(j);
18555                    if (r.visible) {
18556                        app.systemNoUi = false;
18557                    }
18558                }
18559            }
18560            if (!app.systemNoUi) {
18561                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18562            }
18563            return (app.curAdj=app.maxAdj);
18564        }
18565
18566        app.systemNoUi = false;
18567
18568        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18569
18570        // Determine the importance of the process, starting with most
18571        // important to least, and assign an appropriate OOM adjustment.
18572        int adj;
18573        int schedGroup;
18574        int procState;
18575        boolean foregroundActivities = false;
18576        BroadcastQueue queue;
18577        if (app == TOP_APP) {
18578            // The last app on the list is the foreground app.
18579            adj = ProcessList.FOREGROUND_APP_ADJ;
18580            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18581            app.adjType = "top-activity";
18582            foregroundActivities = true;
18583            procState = PROCESS_STATE_CUR_TOP;
18584        } else if (app.instrumentationClass != null) {
18585            // Don't want to kill running instrumentation.
18586            adj = ProcessList.FOREGROUND_APP_ADJ;
18587            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18588            app.adjType = "instrumentation";
18589            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18590        } else if ((queue = isReceivingBroadcast(app)) != null) {
18591            // An app that is currently receiving a broadcast also
18592            // counts as being in the foreground for OOM killer purposes.
18593            // It's placed in a sched group based on the nature of the
18594            // broadcast as reflected by which queue it's active in.
18595            adj = ProcessList.FOREGROUND_APP_ADJ;
18596            schedGroup = (queue == mFgBroadcastQueue)
18597                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18598            app.adjType = "broadcast";
18599            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18600        } else if (app.executingServices.size() > 0) {
18601            // An app that is currently executing a service callback also
18602            // counts as being in the foreground.
18603            adj = ProcessList.FOREGROUND_APP_ADJ;
18604            schedGroup = app.execServicesFg ?
18605                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18606            app.adjType = "exec-service";
18607            procState = ActivityManager.PROCESS_STATE_SERVICE;
18608            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18609        } else {
18610            // As far as we know the process is empty.  We may change our mind later.
18611            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18612            // At this point we don't actually know the adjustment.  Use the cached adj
18613            // value that the caller wants us to.
18614            adj = cachedAdj;
18615            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18616            app.cached = true;
18617            app.empty = true;
18618            app.adjType = "cch-empty";
18619        }
18620
18621        // Examine all activities if not already foreground.
18622        if (!foregroundActivities && activitiesSize > 0) {
18623            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18624            for (int j = 0; j < activitiesSize; j++) {
18625                final ActivityRecord r = app.activities.get(j);
18626                if (r.app != app) {
18627                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18628                            + " instead of expected " + app);
18629                    if (r.app == null || (r.app.uid == app.uid)) {
18630                        // Only fix things up when they look sane
18631                        r.app = app;
18632                    } else {
18633                        continue;
18634                    }
18635                }
18636                if (r.visible) {
18637                    // App has a visible activity; only upgrade adjustment.
18638                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18639                        adj = ProcessList.VISIBLE_APP_ADJ;
18640                        app.adjType = "visible";
18641                    }
18642                    if (procState > PROCESS_STATE_CUR_TOP) {
18643                        procState = PROCESS_STATE_CUR_TOP;
18644                    }
18645                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18646                    app.cached = false;
18647                    app.empty = false;
18648                    foregroundActivities = true;
18649                    if (r.task != null && minLayer > 0) {
18650                        final int layer = r.task.mLayerRank;
18651                        if (layer >= 0 && minLayer > layer) {
18652                            minLayer = layer;
18653                        }
18654                    }
18655                    break;
18656                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18657                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18658                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18659                        app.adjType = "pausing";
18660                    }
18661                    if (procState > PROCESS_STATE_CUR_TOP) {
18662                        procState = PROCESS_STATE_CUR_TOP;
18663                    }
18664                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18665                    app.cached = false;
18666                    app.empty = false;
18667                    foregroundActivities = true;
18668                } else if (r.state == ActivityState.STOPPING) {
18669                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18670                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18671                        app.adjType = "stopping";
18672                    }
18673                    // For the process state, we will at this point consider the
18674                    // process to be cached.  It will be cached either as an activity
18675                    // or empty depending on whether the activity is finishing.  We do
18676                    // this so that we can treat the process as cached for purposes of
18677                    // memory trimming (determing current memory level, trim command to
18678                    // send to process) since there can be an arbitrary number of stopping
18679                    // processes and they should soon all go into the cached state.
18680                    if (!r.finishing) {
18681                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18682                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18683                        }
18684                    }
18685                    app.cached = false;
18686                    app.empty = false;
18687                    foregroundActivities = true;
18688                } else {
18689                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18690                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18691                        app.adjType = "cch-act";
18692                    }
18693                }
18694            }
18695            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18696                adj += minLayer;
18697            }
18698        }
18699
18700        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18701                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18702            if (app.foregroundServices) {
18703                // The user is aware of this app, so make it visible.
18704                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18705                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18706                app.cached = false;
18707                app.adjType = "fg-service";
18708                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18709            } else if (app.forcingToForeground != null) {
18710                // The user is aware of this app, so make it visible.
18711                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18712                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18713                app.cached = false;
18714                app.adjType = "force-fg";
18715                app.adjSource = app.forcingToForeground;
18716                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18717            }
18718        }
18719
18720        if (app == mHeavyWeightProcess) {
18721            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18722                // We don't want to kill the current heavy-weight process.
18723                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18724                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18725                app.cached = false;
18726                app.adjType = "heavy";
18727            }
18728            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18729                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18730            }
18731        }
18732
18733        if (app == mHomeProcess) {
18734            if (adj > ProcessList.HOME_APP_ADJ) {
18735                // This process is hosting what we currently consider to be the
18736                // home app, so we don't want to let it go into the background.
18737                adj = ProcessList.HOME_APP_ADJ;
18738                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18739                app.cached = false;
18740                app.adjType = "home";
18741            }
18742            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18743                procState = ActivityManager.PROCESS_STATE_HOME;
18744            }
18745        }
18746
18747        if (app == mPreviousProcess && app.activities.size() > 0) {
18748            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18749                // This was the previous process that showed UI to the user.
18750                // We want to try to keep it around more aggressively, to give
18751                // a good experience around switching between two apps.
18752                adj = ProcessList.PREVIOUS_APP_ADJ;
18753                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18754                app.cached = false;
18755                app.adjType = "previous";
18756            }
18757            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18758                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18759            }
18760        }
18761
18762        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18763                + " reason=" + app.adjType);
18764
18765        // By default, we use the computed adjustment.  It may be changed if
18766        // there are applications dependent on our services or providers, but
18767        // this gives us a baseline and makes sure we don't get into an
18768        // infinite recursion.
18769        app.adjSeq = mAdjSeq;
18770        app.curRawAdj = adj;
18771        app.hasStartedServices = false;
18772
18773        if (mBackupTarget != null && app == mBackupTarget.app) {
18774            // If possible we want to avoid killing apps while they're being backed up
18775            if (adj > ProcessList.BACKUP_APP_ADJ) {
18776                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18777                adj = ProcessList.BACKUP_APP_ADJ;
18778                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18779                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18780                }
18781                app.adjType = "backup";
18782                app.cached = false;
18783            }
18784            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18785                procState = ActivityManager.PROCESS_STATE_BACKUP;
18786            }
18787        }
18788
18789        boolean mayBeTop = false;
18790
18791        for (int is = app.services.size()-1;
18792                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18793                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18794                        || procState > ActivityManager.PROCESS_STATE_TOP);
18795                is--) {
18796            ServiceRecord s = app.services.valueAt(is);
18797            if (s.startRequested) {
18798                app.hasStartedServices = true;
18799                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18800                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18801                }
18802                if (app.hasShownUi && app != mHomeProcess) {
18803                    // If this process has shown some UI, let it immediately
18804                    // go to the LRU list because it may be pretty heavy with
18805                    // UI stuff.  We'll tag it with a label just to help
18806                    // debug and understand what is going on.
18807                    if (adj > ProcessList.SERVICE_ADJ) {
18808                        app.adjType = "cch-started-ui-services";
18809                    }
18810                } else {
18811                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18812                        // This service has seen some activity within
18813                        // recent memory, so we will keep its process ahead
18814                        // of the background processes.
18815                        if (adj > ProcessList.SERVICE_ADJ) {
18816                            adj = ProcessList.SERVICE_ADJ;
18817                            app.adjType = "started-services";
18818                            app.cached = false;
18819                        }
18820                    }
18821                    // If we have let the service slide into the background
18822                    // state, still have some text describing what it is doing
18823                    // even though the service no longer has an impact.
18824                    if (adj > ProcessList.SERVICE_ADJ) {
18825                        app.adjType = "cch-started-services";
18826                    }
18827                }
18828            }
18829            for (int conni = s.connections.size()-1;
18830                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18831                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18832                            || procState > ActivityManager.PROCESS_STATE_TOP);
18833                    conni--) {
18834                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18835                for (int i = 0;
18836                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18837                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18838                                || procState > ActivityManager.PROCESS_STATE_TOP);
18839                        i++) {
18840                    // XXX should compute this based on the max of
18841                    // all connected clients.
18842                    ConnectionRecord cr = clist.get(i);
18843                    if (cr.binding.client == app) {
18844                        // Binding to ourself is not interesting.
18845                        continue;
18846                    }
18847                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18848                        ProcessRecord client = cr.binding.client;
18849                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18850                                TOP_APP, doingAll, now);
18851                        int clientProcState = client.curProcState;
18852                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18853                            // If the other app is cached for any reason, for purposes here
18854                            // we are going to consider it empty.  The specific cached state
18855                            // doesn't propagate except under certain conditions.
18856                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18857                        }
18858                        String adjType = null;
18859                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18860                            // Not doing bind OOM management, so treat
18861                            // this guy more like a started service.
18862                            if (app.hasShownUi && app != mHomeProcess) {
18863                                // If this process has shown some UI, let it immediately
18864                                // go to the LRU list because it may be pretty heavy with
18865                                // UI stuff.  We'll tag it with a label just to help
18866                                // debug and understand what is going on.
18867                                if (adj > clientAdj) {
18868                                    adjType = "cch-bound-ui-services";
18869                                }
18870                                app.cached = false;
18871                                clientAdj = adj;
18872                                clientProcState = procState;
18873                            } else {
18874                                if (now >= (s.lastActivity
18875                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18876                                    // This service has not seen activity within
18877                                    // recent memory, so allow it to drop to the
18878                                    // LRU list if there is no other reason to keep
18879                                    // it around.  We'll also tag it with a label just
18880                                    // to help debug and undertand what is going on.
18881                                    if (adj > clientAdj) {
18882                                        adjType = "cch-bound-services";
18883                                    }
18884                                    clientAdj = adj;
18885                                }
18886                            }
18887                        }
18888                        if (adj > clientAdj) {
18889                            // If this process has recently shown UI, and
18890                            // the process that is binding to it is less
18891                            // important than being visible, then we don't
18892                            // care about the binding as much as we care
18893                            // about letting this process get into the LRU
18894                            // list to be killed and restarted if needed for
18895                            // memory.
18896                            if (app.hasShownUi && app != mHomeProcess
18897                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18898                                adjType = "cch-bound-ui-services";
18899                            } else {
18900                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18901                                        |Context.BIND_IMPORTANT)) != 0) {
18902                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18903                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18904                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18905                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18906                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18907                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18908                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18909                                    adj = clientAdj;
18910                                } else {
18911                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18912                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18913                                    }
18914                                }
18915                                if (!client.cached) {
18916                                    app.cached = false;
18917                                }
18918                                adjType = "service";
18919                            }
18920                        }
18921                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18922                            // This will treat important bound services identically to
18923                            // the top app, which may behave differently than generic
18924                            // foreground work.
18925                            if (client.curSchedGroup > schedGroup) {
18926                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18927                                    schedGroup = client.curSchedGroup;
18928                                } else {
18929                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18930                                }
18931                            }
18932                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18933                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18934                                    // Special handling of clients who are in the top state.
18935                                    // We *may* want to consider this process to be in the
18936                                    // top state as well, but only if there is not another
18937                                    // reason for it to be running.  Being on the top is a
18938                                    // special state, meaning you are specifically running
18939                                    // for the current top app.  If the process is already
18940                                    // running in the background for some other reason, it
18941                                    // is more important to continue considering it to be
18942                                    // in the background state.
18943                                    mayBeTop = true;
18944                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18945                                } else {
18946                                    // Special handling for above-top states (persistent
18947                                    // processes).  These should not bring the current process
18948                                    // into the top state, since they are not on top.  Instead
18949                                    // give them the best state after that.
18950                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18951                                        clientProcState =
18952                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18953                                    } else if (mWakefulness
18954                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18955                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18956                                                    != 0) {
18957                                        clientProcState =
18958                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18959                                    } else {
18960                                        clientProcState =
18961                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18962                                    }
18963                                }
18964                            }
18965                        } else {
18966                            if (clientProcState <
18967                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18968                                clientProcState =
18969                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18970                            }
18971                        }
18972                        if (procState > clientProcState) {
18973                            procState = clientProcState;
18974                        }
18975                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18976                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18977                            app.pendingUiClean = true;
18978                        }
18979                        if (adjType != null) {
18980                            app.adjType = adjType;
18981                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18982                                    .REASON_SERVICE_IN_USE;
18983                            app.adjSource = cr.binding.client;
18984                            app.adjSourceProcState = clientProcState;
18985                            app.adjTarget = s.name;
18986                        }
18987                    }
18988                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18989                        app.treatLikeActivity = true;
18990                    }
18991                    final ActivityRecord a = cr.activity;
18992                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18993                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18994                            (a.visible || a.state == ActivityState.RESUMED ||
18995                             a.state == ActivityState.PAUSING)) {
18996                            adj = ProcessList.FOREGROUND_APP_ADJ;
18997                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18998                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18999                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19000                                } else {
19001                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19002                                }
19003                            }
19004                            app.cached = false;
19005                            app.adjType = "service";
19006                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19007                                    .REASON_SERVICE_IN_USE;
19008                            app.adjSource = a;
19009                            app.adjSourceProcState = procState;
19010                            app.adjTarget = s.name;
19011                        }
19012                    }
19013                }
19014            }
19015        }
19016
19017        for (int provi = app.pubProviders.size()-1;
19018                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19019                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19020                        || procState > ActivityManager.PROCESS_STATE_TOP);
19021                provi--) {
19022            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19023            for (int i = cpr.connections.size()-1;
19024                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19025                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19026                            || procState > ActivityManager.PROCESS_STATE_TOP);
19027                    i--) {
19028                ContentProviderConnection conn = cpr.connections.get(i);
19029                ProcessRecord client = conn.client;
19030                if (client == app) {
19031                    // Being our own client is not interesting.
19032                    continue;
19033                }
19034                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19035                int clientProcState = client.curProcState;
19036                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19037                    // If the other app is cached for any reason, for purposes here
19038                    // we are going to consider it empty.
19039                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19040                }
19041                if (adj > clientAdj) {
19042                    if (app.hasShownUi && app != mHomeProcess
19043                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19044                        app.adjType = "cch-ui-provider";
19045                    } else {
19046                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19047                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19048                        app.adjType = "provider";
19049                    }
19050                    app.cached &= client.cached;
19051                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19052                            .REASON_PROVIDER_IN_USE;
19053                    app.adjSource = client;
19054                    app.adjSourceProcState = clientProcState;
19055                    app.adjTarget = cpr.name;
19056                }
19057                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19058                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19059                        // Special handling of clients who are in the top state.
19060                        // We *may* want to consider this process to be in the
19061                        // top state as well, but only if there is not another
19062                        // reason for it to be running.  Being on the top is a
19063                        // special state, meaning you are specifically running
19064                        // for the current top app.  If the process is already
19065                        // running in the background for some other reason, it
19066                        // is more important to continue considering it to be
19067                        // in the background state.
19068                        mayBeTop = true;
19069                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19070                    } else {
19071                        // Special handling for above-top states (persistent
19072                        // processes).  These should not bring the current process
19073                        // into the top state, since they are not on top.  Instead
19074                        // give them the best state after that.
19075                        clientProcState =
19076                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19077                    }
19078                }
19079                if (procState > clientProcState) {
19080                    procState = clientProcState;
19081                }
19082                if (client.curSchedGroup > schedGroup) {
19083                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19084                }
19085            }
19086            // If the provider has external (non-framework) process
19087            // dependencies, ensure that its adjustment is at least
19088            // FOREGROUND_APP_ADJ.
19089            if (cpr.hasExternalProcessHandles()) {
19090                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19091                    adj = ProcessList.FOREGROUND_APP_ADJ;
19092                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19093                    app.cached = false;
19094                    app.adjType = "provider";
19095                    app.adjTarget = cpr.name;
19096                }
19097                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19098                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19099                }
19100            }
19101        }
19102
19103        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19104            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19105                adj = ProcessList.PREVIOUS_APP_ADJ;
19106                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19107                app.cached = false;
19108                app.adjType = "provider";
19109            }
19110            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19111                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19112            }
19113        }
19114
19115        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19116            // A client of one of our services or providers is in the top state.  We
19117            // *may* want to be in the top state, but not if we are already running in
19118            // the background for some other reason.  For the decision here, we are going
19119            // to pick out a few specific states that we want to remain in when a client
19120            // is top (states that tend to be longer-term) and otherwise allow it to go
19121            // to the top state.
19122            switch (procState) {
19123                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19124                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19125                case ActivityManager.PROCESS_STATE_SERVICE:
19126                    // These all are longer-term states, so pull them up to the top
19127                    // of the background states, but not all the way to the top state.
19128                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19129                    break;
19130                default:
19131                    // Otherwise, top is a better choice, so take it.
19132                    procState = ActivityManager.PROCESS_STATE_TOP;
19133                    break;
19134            }
19135        }
19136
19137        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19138            if (app.hasClientActivities) {
19139                // This is a cached process, but with client activities.  Mark it so.
19140                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19141                app.adjType = "cch-client-act";
19142            } else if (app.treatLikeActivity) {
19143                // This is a cached process, but somebody wants us to treat it like it has
19144                // an activity, okay!
19145                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19146                app.adjType = "cch-as-act";
19147            }
19148        }
19149
19150        if (adj == ProcessList.SERVICE_ADJ) {
19151            if (doingAll) {
19152                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19153                mNewNumServiceProcs++;
19154                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19155                if (!app.serviceb) {
19156                    // This service isn't far enough down on the LRU list to
19157                    // normally be a B service, but if we are low on RAM and it
19158                    // is large we want to force it down since we would prefer to
19159                    // keep launcher over it.
19160                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19161                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19162                        app.serviceHighRam = true;
19163                        app.serviceb = true;
19164                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19165                    } else {
19166                        mNewNumAServiceProcs++;
19167                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19168                    }
19169                } else {
19170                    app.serviceHighRam = false;
19171                }
19172            }
19173            if (app.serviceb) {
19174                adj = ProcessList.SERVICE_B_ADJ;
19175            }
19176        }
19177
19178        app.curRawAdj = adj;
19179
19180        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19181        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19182        if (adj > app.maxAdj) {
19183            adj = app.maxAdj;
19184            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19185                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19186            }
19187        }
19188
19189        // Do final modification to adj.  Everything we do between here and applying
19190        // the final setAdj must be done in this function, because we will also use
19191        // it when computing the final cached adj later.  Note that we don't need to
19192        // worry about this for max adj above, since max adj will always be used to
19193        // keep it out of the cached vaues.
19194        app.curAdj = app.modifyRawOomAdj(adj);
19195        app.curSchedGroup = schedGroup;
19196        app.curProcState = procState;
19197        app.foregroundActivities = foregroundActivities;
19198
19199        return app.curRawAdj;
19200    }
19201
19202    /**
19203     * Record new PSS sample for a process.
19204     */
19205    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19206            long now) {
19207        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19208                swapPss * 1024);
19209        proc.lastPssTime = now;
19210        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19211        if (DEBUG_PSS) Slog.d(TAG_PSS,
19212                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19213                + " state=" + ProcessList.makeProcStateString(procState));
19214        if (proc.initialIdlePss == 0) {
19215            proc.initialIdlePss = pss;
19216        }
19217        proc.lastPss = pss;
19218        proc.lastSwapPss = swapPss;
19219        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19220            proc.lastCachedPss = pss;
19221            proc.lastCachedSwapPss = swapPss;
19222        }
19223
19224        final SparseArray<Pair<Long, String>> watchUids
19225                = mMemWatchProcesses.getMap().get(proc.processName);
19226        Long check = null;
19227        if (watchUids != null) {
19228            Pair<Long, String> val = watchUids.get(proc.uid);
19229            if (val == null) {
19230                val = watchUids.get(0);
19231            }
19232            if (val != null) {
19233                check = val.first;
19234            }
19235        }
19236        if (check != null) {
19237            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19238                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19239                if (!isDebuggable) {
19240                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19241                        isDebuggable = true;
19242                    }
19243                }
19244                if (isDebuggable) {
19245                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19246                    final ProcessRecord myProc = proc;
19247                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19248                    mMemWatchDumpProcName = proc.processName;
19249                    mMemWatchDumpFile = heapdumpFile.toString();
19250                    mMemWatchDumpPid = proc.pid;
19251                    mMemWatchDumpUid = proc.uid;
19252                    BackgroundThread.getHandler().post(new Runnable() {
19253                        @Override
19254                        public void run() {
19255                            revokeUriPermission(ActivityThread.currentActivityThread()
19256                                            .getApplicationThread(),
19257                                    DumpHeapActivity.JAVA_URI,
19258                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19259                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19260                                    UserHandle.myUserId());
19261                            ParcelFileDescriptor fd = null;
19262                            try {
19263                                heapdumpFile.delete();
19264                                fd = ParcelFileDescriptor.open(heapdumpFile,
19265                                        ParcelFileDescriptor.MODE_CREATE |
19266                                                ParcelFileDescriptor.MODE_TRUNCATE |
19267                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19268                                                ParcelFileDescriptor.MODE_APPEND);
19269                                IApplicationThread thread = myProc.thread;
19270                                if (thread != null) {
19271                                    try {
19272                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19273                                                "Requesting dump heap from "
19274                                                + myProc + " to " + heapdumpFile);
19275                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19276                                    } catch (RemoteException e) {
19277                                    }
19278                                }
19279                            } catch (FileNotFoundException e) {
19280                                e.printStackTrace();
19281                            } finally {
19282                                if (fd != null) {
19283                                    try {
19284                                        fd.close();
19285                                    } catch (IOException e) {
19286                                    }
19287                                }
19288                            }
19289                        }
19290                    });
19291                } else {
19292                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19293                            + ", but debugging not enabled");
19294                }
19295            }
19296        }
19297    }
19298
19299    /**
19300     * Schedule PSS collection of a process.
19301     */
19302    void requestPssLocked(ProcessRecord proc, int procState) {
19303        if (mPendingPssProcesses.contains(proc)) {
19304            return;
19305        }
19306        if (mPendingPssProcesses.size() == 0) {
19307            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19308        }
19309        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19310        proc.pssProcState = procState;
19311        mPendingPssProcesses.add(proc);
19312    }
19313
19314    /**
19315     * Schedule PSS collection of all processes.
19316     */
19317    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19318        if (!always) {
19319            if (now < (mLastFullPssTime +
19320                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19321                return;
19322            }
19323        }
19324        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19325        mLastFullPssTime = now;
19326        mFullPssPending = true;
19327        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19328        mPendingPssProcesses.clear();
19329        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19330            ProcessRecord app = mLruProcesses.get(i);
19331            if (app.thread == null
19332                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19333                continue;
19334            }
19335            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19336                app.pssProcState = app.setProcState;
19337                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19338                        mTestPssMode, isSleeping(), now);
19339                mPendingPssProcesses.add(app);
19340            }
19341        }
19342        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19343    }
19344
19345    public void setTestPssMode(boolean enabled) {
19346        synchronized (this) {
19347            mTestPssMode = enabled;
19348            if (enabled) {
19349                // Whenever we enable the mode, we want to take a snapshot all of current
19350                // process mem use.
19351                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19352            }
19353        }
19354    }
19355
19356    /**
19357     * Ask a given process to GC right now.
19358     */
19359    final void performAppGcLocked(ProcessRecord app) {
19360        try {
19361            app.lastRequestedGc = SystemClock.uptimeMillis();
19362            if (app.thread != null) {
19363                if (app.reportLowMemory) {
19364                    app.reportLowMemory = false;
19365                    app.thread.scheduleLowMemory();
19366                } else {
19367                    app.thread.processInBackground();
19368                }
19369            }
19370        } catch (Exception e) {
19371            // whatever.
19372        }
19373    }
19374
19375    /**
19376     * Returns true if things are idle enough to perform GCs.
19377     */
19378    private final boolean canGcNowLocked() {
19379        boolean processingBroadcasts = false;
19380        for (BroadcastQueue q : mBroadcastQueues) {
19381            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19382                processingBroadcasts = true;
19383            }
19384        }
19385        return !processingBroadcasts
19386                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19387    }
19388
19389    /**
19390     * Perform GCs on all processes that are waiting for it, but only
19391     * if things are idle.
19392     */
19393    final void performAppGcsLocked() {
19394        final int N = mProcessesToGc.size();
19395        if (N <= 0) {
19396            return;
19397        }
19398        if (canGcNowLocked()) {
19399            while (mProcessesToGc.size() > 0) {
19400                ProcessRecord proc = mProcessesToGc.remove(0);
19401                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19402                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19403                            <= SystemClock.uptimeMillis()) {
19404                        // To avoid spamming the system, we will GC processes one
19405                        // at a time, waiting a few seconds between each.
19406                        performAppGcLocked(proc);
19407                        scheduleAppGcsLocked();
19408                        return;
19409                    } else {
19410                        // It hasn't been long enough since we last GCed this
19411                        // process...  put it in the list to wait for its time.
19412                        addProcessToGcListLocked(proc);
19413                        break;
19414                    }
19415                }
19416            }
19417
19418            scheduleAppGcsLocked();
19419        }
19420    }
19421
19422    /**
19423     * If all looks good, perform GCs on all processes waiting for them.
19424     */
19425    final void performAppGcsIfAppropriateLocked() {
19426        if (canGcNowLocked()) {
19427            performAppGcsLocked();
19428            return;
19429        }
19430        // Still not idle, wait some more.
19431        scheduleAppGcsLocked();
19432    }
19433
19434    /**
19435     * Schedule the execution of all pending app GCs.
19436     */
19437    final void scheduleAppGcsLocked() {
19438        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19439
19440        if (mProcessesToGc.size() > 0) {
19441            // Schedule a GC for the time to the next process.
19442            ProcessRecord proc = mProcessesToGc.get(0);
19443            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19444
19445            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19446            long now = SystemClock.uptimeMillis();
19447            if (when < (now+GC_TIMEOUT)) {
19448                when = now + GC_TIMEOUT;
19449            }
19450            mHandler.sendMessageAtTime(msg, when);
19451        }
19452    }
19453
19454    /**
19455     * Add a process to the array of processes waiting to be GCed.  Keeps the
19456     * list in sorted order by the last GC time.  The process can't already be
19457     * on the list.
19458     */
19459    final void addProcessToGcListLocked(ProcessRecord proc) {
19460        boolean added = false;
19461        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19462            if (mProcessesToGc.get(i).lastRequestedGc <
19463                    proc.lastRequestedGc) {
19464                added = true;
19465                mProcessesToGc.add(i+1, proc);
19466                break;
19467            }
19468        }
19469        if (!added) {
19470            mProcessesToGc.add(0, proc);
19471        }
19472    }
19473
19474    /**
19475     * Set up to ask a process to GC itself.  This will either do it
19476     * immediately, or put it on the list of processes to gc the next
19477     * time things are idle.
19478     */
19479    final void scheduleAppGcLocked(ProcessRecord app) {
19480        long now = SystemClock.uptimeMillis();
19481        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19482            return;
19483        }
19484        if (!mProcessesToGc.contains(app)) {
19485            addProcessToGcListLocked(app);
19486            scheduleAppGcsLocked();
19487        }
19488    }
19489
19490    final void checkExcessivePowerUsageLocked(boolean doKills) {
19491        updateCpuStatsNow();
19492
19493        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19494        boolean doWakeKills = doKills;
19495        boolean doCpuKills = doKills;
19496        if (mLastPowerCheckRealtime == 0) {
19497            doWakeKills = false;
19498        }
19499        if (mLastPowerCheckUptime == 0) {
19500            doCpuKills = false;
19501        }
19502        if (stats.isScreenOn()) {
19503            doWakeKills = false;
19504        }
19505        final long curRealtime = SystemClock.elapsedRealtime();
19506        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19507        final long curUptime = SystemClock.uptimeMillis();
19508        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19509        mLastPowerCheckRealtime = curRealtime;
19510        mLastPowerCheckUptime = curUptime;
19511        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19512            doWakeKills = false;
19513        }
19514        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19515            doCpuKills = false;
19516        }
19517        int i = mLruProcesses.size();
19518        while (i > 0) {
19519            i--;
19520            ProcessRecord app = mLruProcesses.get(i);
19521            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19522                long wtime;
19523                synchronized (stats) {
19524                    wtime = stats.getProcessWakeTime(app.info.uid,
19525                            app.pid, curRealtime);
19526                }
19527                long wtimeUsed = wtime - app.lastWakeTime;
19528                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19529                if (DEBUG_POWER) {
19530                    StringBuilder sb = new StringBuilder(128);
19531                    sb.append("Wake for ");
19532                    app.toShortString(sb);
19533                    sb.append(": over ");
19534                    TimeUtils.formatDuration(realtimeSince, sb);
19535                    sb.append(" used ");
19536                    TimeUtils.formatDuration(wtimeUsed, sb);
19537                    sb.append(" (");
19538                    sb.append((wtimeUsed*100)/realtimeSince);
19539                    sb.append("%)");
19540                    Slog.i(TAG_POWER, sb.toString());
19541                    sb.setLength(0);
19542                    sb.append("CPU for ");
19543                    app.toShortString(sb);
19544                    sb.append(": over ");
19545                    TimeUtils.formatDuration(uptimeSince, sb);
19546                    sb.append(" used ");
19547                    TimeUtils.formatDuration(cputimeUsed, sb);
19548                    sb.append(" (");
19549                    sb.append((cputimeUsed*100)/uptimeSince);
19550                    sb.append("%)");
19551                    Slog.i(TAG_POWER, sb.toString());
19552                }
19553                // If a process has held a wake lock for more
19554                // than 50% of the time during this period,
19555                // that sounds bad.  Kill!
19556                if (doWakeKills && realtimeSince > 0
19557                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19558                    synchronized (stats) {
19559                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19560                                realtimeSince, wtimeUsed);
19561                    }
19562                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19563                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19564                } else if (doCpuKills && uptimeSince > 0
19565                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19566                    synchronized (stats) {
19567                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19568                                uptimeSince, cputimeUsed);
19569                    }
19570                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19571                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19572                } else {
19573                    app.lastWakeTime = wtime;
19574                    app.lastCpuTime = app.curCpuTime;
19575                }
19576            }
19577        }
19578    }
19579
19580    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19581            long nowElapsed) {
19582        boolean success = true;
19583
19584        if (app.curRawAdj != app.setRawAdj) {
19585            app.setRawAdj = app.curRawAdj;
19586        }
19587
19588        int changes = 0;
19589
19590        if (app.curAdj != app.setAdj) {
19591            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19592            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19593                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19594                    + app.adjType);
19595            app.setAdj = app.curAdj;
19596        }
19597
19598        if (app.setSchedGroup != app.curSchedGroup) {
19599            app.setSchedGroup = app.curSchedGroup;
19600            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19601                    "Setting sched group of " + app.processName
19602                    + " to " + app.curSchedGroup);
19603            if (app.waitingToKill != null && app.curReceiver == null
19604                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19605                app.kill(app.waitingToKill, true);
19606                success = false;
19607            } else {
19608                int processGroup;
19609                switch (app.curSchedGroup) {
19610                    case ProcessList.SCHED_GROUP_BACKGROUND:
19611                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19612                        break;
19613                    case ProcessList.SCHED_GROUP_TOP_APP:
19614                        processGroup = Process.THREAD_GROUP_TOP_APP;
19615                        break;
19616                    default:
19617                        processGroup = Process.THREAD_GROUP_DEFAULT;
19618                        break;
19619                }
19620                if (true) {
19621                    long oldId = Binder.clearCallingIdentity();
19622                    try {
19623                        Process.setProcessGroup(app.pid, processGroup);
19624                    } catch (Exception e) {
19625                        Slog.w(TAG, "Failed setting process group of " + app.pid
19626                                + " to " + app.curSchedGroup);
19627                        e.printStackTrace();
19628                    } finally {
19629                        Binder.restoreCallingIdentity(oldId);
19630                    }
19631                } else {
19632                    if (app.thread != null) {
19633                        try {
19634                            app.thread.setSchedulingGroup(processGroup);
19635                        } catch (RemoteException e) {
19636                        }
19637                    }
19638                }
19639            }
19640        }
19641        if (app.repForegroundActivities != app.foregroundActivities) {
19642            app.repForegroundActivities = app.foregroundActivities;
19643            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19644        }
19645        if (app.repProcState != app.curProcState) {
19646            app.repProcState = app.curProcState;
19647            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19648            if (app.thread != null) {
19649                try {
19650                    if (false) {
19651                        //RuntimeException h = new RuntimeException("here");
19652                        Slog.i(TAG, "Sending new process state " + app.repProcState
19653                                + " to " + app /*, h*/);
19654                    }
19655                    app.thread.setProcessState(app.repProcState);
19656                } catch (RemoteException e) {
19657                }
19658            }
19659        }
19660        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19661                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19662            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19663                // Experimental code to more aggressively collect pss while
19664                // running test...  the problem is that this tends to collect
19665                // the data right when a process is transitioning between process
19666                // states, which well tend to give noisy data.
19667                long start = SystemClock.uptimeMillis();
19668                long pss = Debug.getPss(app.pid, mTmpLong, null);
19669                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19670                mPendingPssProcesses.remove(app);
19671                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19672                        + " to " + app.curProcState + ": "
19673                        + (SystemClock.uptimeMillis()-start) + "ms");
19674            }
19675            app.lastStateTime = now;
19676            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19677                    mTestPssMode, isSleeping(), now);
19678            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19679                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19680                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19681                    + (app.nextPssTime-now) + ": " + app);
19682        } else {
19683            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19684                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19685                    mTestPssMode)))) {
19686                requestPssLocked(app, app.setProcState);
19687                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19688                        mTestPssMode, isSleeping(), now);
19689            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19690                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19691        }
19692        if (app.setProcState != app.curProcState) {
19693            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19694                    "Proc state change of " + app.processName
19695                            + " to " + app.curProcState);
19696            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19697            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19698            if (setImportant && !curImportant) {
19699                // This app is no longer something we consider important enough to allow to
19700                // use arbitrary amounts of battery power.  Note
19701                // its current wake lock time to later know to kill it if
19702                // it is not behaving well.
19703                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19704                synchronized (stats) {
19705                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19706                            app.pid, nowElapsed);
19707                }
19708                app.lastCpuTime = app.curCpuTime;
19709
19710            }
19711            // Inform UsageStats of important process state change
19712            // Must be called before updating setProcState
19713            maybeUpdateUsageStatsLocked(app, nowElapsed);
19714
19715            app.setProcState = app.curProcState;
19716            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19717                app.notCachedSinceIdle = false;
19718            }
19719            if (!doingAll) {
19720                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19721            } else {
19722                app.procStateChanged = true;
19723            }
19724        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19725                > USAGE_STATS_INTERACTION_INTERVAL) {
19726            // For apps that sit around for a long time in the interactive state, we need
19727            // to report this at least once a day so they don't go idle.
19728            maybeUpdateUsageStatsLocked(app, nowElapsed);
19729        }
19730
19731        if (changes != 0) {
19732            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19733                    "Changes in " + app + ": " + changes);
19734            int i = mPendingProcessChanges.size()-1;
19735            ProcessChangeItem item = null;
19736            while (i >= 0) {
19737                item = mPendingProcessChanges.get(i);
19738                if (item.pid == app.pid) {
19739                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19740                            "Re-using existing item: " + item);
19741                    break;
19742                }
19743                i--;
19744            }
19745            if (i < 0) {
19746                // No existing item in pending changes; need a new one.
19747                final int NA = mAvailProcessChanges.size();
19748                if (NA > 0) {
19749                    item = mAvailProcessChanges.remove(NA-1);
19750                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19751                            "Retrieving available item: " + item);
19752                } else {
19753                    item = new ProcessChangeItem();
19754                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19755                            "Allocating new item: " + item);
19756                }
19757                item.changes = 0;
19758                item.pid = app.pid;
19759                item.uid = app.info.uid;
19760                if (mPendingProcessChanges.size() == 0) {
19761                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19762                            "*** Enqueueing dispatch processes changed!");
19763                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19764                }
19765                mPendingProcessChanges.add(item);
19766            }
19767            item.changes |= changes;
19768            item.processState = app.repProcState;
19769            item.foregroundActivities = app.repForegroundActivities;
19770            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19771                    "Item " + Integer.toHexString(System.identityHashCode(item))
19772                    + " " + app.toShortString() + ": changes=" + item.changes
19773                    + " procState=" + item.processState
19774                    + " foreground=" + item.foregroundActivities
19775                    + " type=" + app.adjType + " source=" + app.adjSource
19776                    + " target=" + app.adjTarget);
19777        }
19778
19779        return success;
19780    }
19781
19782    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19783        final UidRecord.ChangeItem pendingChange;
19784        if (uidRec == null || uidRec.pendingChange == null) {
19785            if (mPendingUidChanges.size() == 0) {
19786                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19787                        "*** Enqueueing dispatch uid changed!");
19788                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19789            }
19790            final int NA = mAvailUidChanges.size();
19791            if (NA > 0) {
19792                pendingChange = mAvailUidChanges.remove(NA-1);
19793                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19794                        "Retrieving available item: " + pendingChange);
19795            } else {
19796                pendingChange = new UidRecord.ChangeItem();
19797                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19798                        "Allocating new item: " + pendingChange);
19799            }
19800            if (uidRec != null) {
19801                uidRec.pendingChange = pendingChange;
19802                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19803                    // If this uid is going away, and we haven't yet reported it is gone,
19804                    // then do so now.
19805                    change = UidRecord.CHANGE_GONE_IDLE;
19806                }
19807            } else if (uid < 0) {
19808                throw new IllegalArgumentException("No UidRecord or uid");
19809            }
19810            pendingChange.uidRecord = uidRec;
19811            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19812            mPendingUidChanges.add(pendingChange);
19813        } else {
19814            pendingChange = uidRec.pendingChange;
19815            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19816                change = UidRecord.CHANGE_GONE_IDLE;
19817            }
19818        }
19819        pendingChange.change = change;
19820        pendingChange.processState = uidRec != null
19821                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19822    }
19823
19824    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19825            String authority) {
19826        if (app == null) return;
19827        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19828            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19829            if (userState == null) return;
19830            final long now = SystemClock.elapsedRealtime();
19831            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19832            if (lastReported == null || lastReported < now - 60 * 1000L) {
19833                mUsageStatsService.reportContentProviderUsage(
19834                        authority, providerPkgName, app.userId);
19835                userState.mProviderLastReportedFg.put(authority, now);
19836            }
19837        }
19838    }
19839
19840    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19841        if (DEBUG_USAGE_STATS) {
19842            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19843                    + "] state changes: old = " + app.setProcState + ", new = "
19844                    + app.curProcState);
19845        }
19846        if (mUsageStatsService == null) {
19847            return;
19848        }
19849        boolean isInteraction;
19850        // To avoid some abuse patterns, we are going to be careful about what we consider
19851        // to be an app interaction.  Being the top activity doesn't count while the display
19852        // is sleeping, nor do short foreground services.
19853        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19854            isInteraction = true;
19855            app.fgInteractionTime = 0;
19856        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19857            if (app.fgInteractionTime == 0) {
19858                app.fgInteractionTime = nowElapsed;
19859                isInteraction = false;
19860            } else {
19861                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19862            }
19863        } else {
19864            isInteraction = app.curProcState
19865                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19866            app.fgInteractionTime = 0;
19867        }
19868        if (isInteraction && (!app.reportedInteraction
19869                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19870            app.interactionEventTime = nowElapsed;
19871            String[] packages = app.getPackageList();
19872            if (packages != null) {
19873                for (int i = 0; i < packages.length; i++) {
19874                    mUsageStatsService.reportEvent(packages[i], app.userId,
19875                            UsageEvents.Event.SYSTEM_INTERACTION);
19876                }
19877            }
19878        }
19879        app.reportedInteraction = isInteraction;
19880        if (!isInteraction) {
19881            app.interactionEventTime = 0;
19882        }
19883    }
19884
19885    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19886        if (proc.thread != null) {
19887            if (proc.baseProcessTracker != null) {
19888                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19889            }
19890        }
19891    }
19892
19893    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19894            ProcessRecord TOP_APP, boolean doingAll, long now) {
19895        if (app.thread == null) {
19896            return false;
19897        }
19898
19899        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19900
19901        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19902    }
19903
19904    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19905            boolean oomAdj) {
19906        if (isForeground != proc.foregroundServices) {
19907            proc.foregroundServices = isForeground;
19908            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19909                    proc.info.uid);
19910            if (isForeground) {
19911                if (curProcs == null) {
19912                    curProcs = new ArrayList<ProcessRecord>();
19913                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19914                }
19915                if (!curProcs.contains(proc)) {
19916                    curProcs.add(proc);
19917                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19918                            proc.info.packageName, proc.info.uid);
19919                }
19920            } else {
19921                if (curProcs != null) {
19922                    if (curProcs.remove(proc)) {
19923                        mBatteryStatsService.noteEvent(
19924                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19925                                proc.info.packageName, proc.info.uid);
19926                        if (curProcs.size() <= 0) {
19927                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19928                        }
19929                    }
19930                }
19931            }
19932            if (oomAdj) {
19933                updateOomAdjLocked();
19934            }
19935        }
19936    }
19937
19938    private final ActivityRecord resumedAppLocked() {
19939        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19940        String pkg;
19941        int uid;
19942        if (act != null) {
19943            pkg = act.packageName;
19944            uid = act.info.applicationInfo.uid;
19945        } else {
19946            pkg = null;
19947            uid = -1;
19948        }
19949        // Has the UID or resumed package name changed?
19950        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19951                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19952            if (mCurResumedPackage != null) {
19953                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19954                        mCurResumedPackage, mCurResumedUid);
19955            }
19956            mCurResumedPackage = pkg;
19957            mCurResumedUid = uid;
19958            if (mCurResumedPackage != null) {
19959                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19960                        mCurResumedPackage, mCurResumedUid);
19961            }
19962        }
19963        return act;
19964    }
19965
19966    final boolean updateOomAdjLocked(ProcessRecord app) {
19967        final ActivityRecord TOP_ACT = resumedAppLocked();
19968        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19969        final boolean wasCached = app.cached;
19970
19971        mAdjSeq++;
19972
19973        // This is the desired cached adjusment we want to tell it to use.
19974        // If our app is currently cached, we know it, and that is it.  Otherwise,
19975        // we don't know it yet, and it needs to now be cached we will then
19976        // need to do a complete oom adj.
19977        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19978                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19979        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19980                SystemClock.uptimeMillis());
19981        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19982            // Changed to/from cached state, so apps after it in the LRU
19983            // list may also be changed.
19984            updateOomAdjLocked();
19985        }
19986        return success;
19987    }
19988
19989    final void updateOomAdjLocked() {
19990        final ActivityRecord TOP_ACT = resumedAppLocked();
19991        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19992        final long now = SystemClock.uptimeMillis();
19993        final long nowElapsed = SystemClock.elapsedRealtime();
19994        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19995        final int N = mLruProcesses.size();
19996
19997        if (false) {
19998            RuntimeException e = new RuntimeException();
19999            e.fillInStackTrace();
20000            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20001        }
20002
20003        // Reset state in all uid records.
20004        for (int i=mActiveUids.size()-1; i>=0; i--) {
20005            final UidRecord uidRec = mActiveUids.valueAt(i);
20006            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20007                    "Starting update of " + uidRec);
20008            uidRec.reset();
20009        }
20010
20011        mStackSupervisor.rankTaskLayersIfNeeded();
20012
20013        mAdjSeq++;
20014        mNewNumServiceProcs = 0;
20015        mNewNumAServiceProcs = 0;
20016
20017        final int emptyProcessLimit;
20018        final int cachedProcessLimit;
20019        if (mProcessLimit <= 0) {
20020            emptyProcessLimit = cachedProcessLimit = 0;
20021        } else if (mProcessLimit == 1) {
20022            emptyProcessLimit = 1;
20023            cachedProcessLimit = 0;
20024        } else {
20025            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20026            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20027        }
20028
20029        // Let's determine how many processes we have running vs.
20030        // how many slots we have for background processes; we may want
20031        // to put multiple processes in a slot of there are enough of
20032        // them.
20033        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20034                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20035        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20036        if (numEmptyProcs > cachedProcessLimit) {
20037            // If there are more empty processes than our limit on cached
20038            // processes, then use the cached process limit for the factor.
20039            // This ensures that the really old empty processes get pushed
20040            // down to the bottom, so if we are running low on memory we will
20041            // have a better chance at keeping around more cached processes
20042            // instead of a gazillion empty processes.
20043            numEmptyProcs = cachedProcessLimit;
20044        }
20045        int emptyFactor = numEmptyProcs/numSlots;
20046        if (emptyFactor < 1) emptyFactor = 1;
20047        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20048        if (cachedFactor < 1) cachedFactor = 1;
20049        int stepCached = 0;
20050        int stepEmpty = 0;
20051        int numCached = 0;
20052        int numEmpty = 0;
20053        int numTrimming = 0;
20054
20055        mNumNonCachedProcs = 0;
20056        mNumCachedHiddenProcs = 0;
20057
20058        // First update the OOM adjustment for each of the
20059        // application processes based on their current state.
20060        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20061        int nextCachedAdj = curCachedAdj+1;
20062        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20063        int nextEmptyAdj = curEmptyAdj+2;
20064        for (int i=N-1; i>=0; i--) {
20065            ProcessRecord app = mLruProcesses.get(i);
20066            if (!app.killedByAm && app.thread != null) {
20067                app.procStateChanged = false;
20068                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20069
20070                // If we haven't yet assigned the final cached adj
20071                // to the process, do that now.
20072                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20073                    switch (app.curProcState) {
20074                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20075                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20076                            // This process is a cached process holding activities...
20077                            // assign it the next cached value for that type, and then
20078                            // step that cached level.
20079                            app.curRawAdj = curCachedAdj;
20080                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20081                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20082                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20083                                    + ")");
20084                            if (curCachedAdj != nextCachedAdj) {
20085                                stepCached++;
20086                                if (stepCached >= cachedFactor) {
20087                                    stepCached = 0;
20088                                    curCachedAdj = nextCachedAdj;
20089                                    nextCachedAdj += 2;
20090                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20091                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20092                                    }
20093                                }
20094                            }
20095                            break;
20096                        default:
20097                            // For everything else, assign next empty cached process
20098                            // level and bump that up.  Note that this means that
20099                            // long-running services that have dropped down to the
20100                            // cached level will be treated as empty (since their process
20101                            // state is still as a service), which is what we want.
20102                            app.curRawAdj = curEmptyAdj;
20103                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20104                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20105                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20106                                    + ")");
20107                            if (curEmptyAdj != nextEmptyAdj) {
20108                                stepEmpty++;
20109                                if (stepEmpty >= emptyFactor) {
20110                                    stepEmpty = 0;
20111                                    curEmptyAdj = nextEmptyAdj;
20112                                    nextEmptyAdj += 2;
20113                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20114                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20115                                    }
20116                                }
20117                            }
20118                            break;
20119                    }
20120                }
20121
20122                applyOomAdjLocked(app, true, now, nowElapsed);
20123
20124                // Count the number of process types.
20125                switch (app.curProcState) {
20126                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20127                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20128                        mNumCachedHiddenProcs++;
20129                        numCached++;
20130                        if (numCached > cachedProcessLimit) {
20131                            app.kill("cached #" + numCached, true);
20132                        }
20133                        break;
20134                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20135                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20136                                && app.lastActivityTime < oldTime) {
20137                            app.kill("empty for "
20138                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20139                                    / 1000) + "s", true);
20140                        } else {
20141                            numEmpty++;
20142                            if (numEmpty > emptyProcessLimit) {
20143                                app.kill("empty #" + numEmpty, true);
20144                            }
20145                        }
20146                        break;
20147                    default:
20148                        mNumNonCachedProcs++;
20149                        break;
20150                }
20151
20152                if (app.isolated && app.services.size() <= 0) {
20153                    // If this is an isolated process, and there are no
20154                    // services running in it, then the process is no longer
20155                    // needed.  We agressively kill these because we can by
20156                    // definition not re-use the same process again, and it is
20157                    // good to avoid having whatever code was running in them
20158                    // left sitting around after no longer needed.
20159                    app.kill("isolated not needed", true);
20160                } else {
20161                    // Keeping this process, update its uid.
20162                    final UidRecord uidRec = app.uidRecord;
20163                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20164                        uidRec.curProcState = app.curProcState;
20165                    }
20166                }
20167
20168                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20169                        && !app.killedByAm) {
20170                    numTrimming++;
20171                }
20172            }
20173        }
20174
20175        mNumServiceProcs = mNewNumServiceProcs;
20176
20177        // Now determine the memory trimming level of background processes.
20178        // Unfortunately we need to start at the back of the list to do this
20179        // properly.  We only do this if the number of background apps we
20180        // are managing to keep around is less than half the maximum we desire;
20181        // if we are keeping a good number around, we'll let them use whatever
20182        // memory they want.
20183        final int numCachedAndEmpty = numCached + numEmpty;
20184        int memFactor;
20185        if (numCached <= ProcessList.TRIM_CACHED_APPS
20186                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20187            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20188                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20189            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20190                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20191            } else {
20192                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20193            }
20194        } else {
20195            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20196        }
20197        // We always allow the memory level to go up (better).  We only allow it to go
20198        // down if we are in a state where that is allowed, *and* the total number of processes
20199        // has gone down since last time.
20200        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20201                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20202                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20203        if (memFactor > mLastMemoryLevel) {
20204            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20205                memFactor = mLastMemoryLevel;
20206                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20207            }
20208        }
20209        if (memFactor != mLastMemoryLevel) {
20210            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20211        }
20212        mLastMemoryLevel = memFactor;
20213        mLastNumProcesses = mLruProcesses.size();
20214        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20215        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20216        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20217            if (mLowRamStartTime == 0) {
20218                mLowRamStartTime = now;
20219            }
20220            int step = 0;
20221            int fgTrimLevel;
20222            switch (memFactor) {
20223                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20224                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20225                    break;
20226                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20227                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20228                    break;
20229                default:
20230                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20231                    break;
20232            }
20233            int factor = numTrimming/3;
20234            int minFactor = 2;
20235            if (mHomeProcess != null) minFactor++;
20236            if (mPreviousProcess != null) minFactor++;
20237            if (factor < minFactor) factor = minFactor;
20238            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20239            for (int i=N-1; i>=0; i--) {
20240                ProcessRecord app = mLruProcesses.get(i);
20241                if (allChanged || app.procStateChanged) {
20242                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20243                    app.procStateChanged = false;
20244                }
20245                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20246                        && !app.killedByAm) {
20247                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20248                        try {
20249                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20250                                    "Trimming memory of " + app.processName + " to " + curLevel);
20251                            app.thread.scheduleTrimMemory(curLevel);
20252                        } catch (RemoteException e) {
20253                        }
20254                        if (false) {
20255                            // For now we won't do this; our memory trimming seems
20256                            // to be good enough at this point that destroying
20257                            // activities causes more harm than good.
20258                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20259                                    && app != mHomeProcess && app != mPreviousProcess) {
20260                                // Need to do this on its own message because the stack may not
20261                                // be in a consistent state at this point.
20262                                // For these apps we will also finish their activities
20263                                // to help them free memory.
20264                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20265                            }
20266                        }
20267                    }
20268                    app.trimMemoryLevel = curLevel;
20269                    step++;
20270                    if (step >= factor) {
20271                        step = 0;
20272                        switch (curLevel) {
20273                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20274                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20275                                break;
20276                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20277                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20278                                break;
20279                        }
20280                    }
20281                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20282                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20283                            && app.thread != null) {
20284                        try {
20285                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20286                                    "Trimming memory of heavy-weight " + app.processName
20287                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20288                            app.thread.scheduleTrimMemory(
20289                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20290                        } catch (RemoteException e) {
20291                        }
20292                    }
20293                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20294                } else {
20295                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20296                            || app.systemNoUi) && app.pendingUiClean) {
20297                        // If this application is now in the background and it
20298                        // had done UI, then give it the special trim level to
20299                        // have it free UI resources.
20300                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20301                        if (app.trimMemoryLevel < level && app.thread != null) {
20302                            try {
20303                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20304                                        "Trimming memory of bg-ui " + app.processName
20305                                        + " to " + level);
20306                                app.thread.scheduleTrimMemory(level);
20307                            } catch (RemoteException e) {
20308                            }
20309                        }
20310                        app.pendingUiClean = false;
20311                    }
20312                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20313                        try {
20314                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20315                                    "Trimming memory of fg " + app.processName
20316                                    + " to " + fgTrimLevel);
20317                            app.thread.scheduleTrimMemory(fgTrimLevel);
20318                        } catch (RemoteException e) {
20319                        }
20320                    }
20321                    app.trimMemoryLevel = fgTrimLevel;
20322                }
20323            }
20324        } else {
20325            if (mLowRamStartTime != 0) {
20326                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20327                mLowRamStartTime = 0;
20328            }
20329            for (int i=N-1; i>=0; i--) {
20330                ProcessRecord app = mLruProcesses.get(i);
20331                if (allChanged || app.procStateChanged) {
20332                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20333                    app.procStateChanged = false;
20334                }
20335                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20336                        || app.systemNoUi) && app.pendingUiClean) {
20337                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20338                            && app.thread != null) {
20339                        try {
20340                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20341                                    "Trimming memory of ui hidden " + app.processName
20342                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20343                            app.thread.scheduleTrimMemory(
20344                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20345                        } catch (RemoteException e) {
20346                        }
20347                    }
20348                    app.pendingUiClean = false;
20349                }
20350                app.trimMemoryLevel = 0;
20351            }
20352        }
20353
20354        if (mAlwaysFinishActivities) {
20355            // Need to do this on its own message because the stack may not
20356            // be in a consistent state at this point.
20357            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20358        }
20359
20360        if (allChanged) {
20361            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20362        }
20363
20364        // Update from any uid changes.
20365        for (int i=mActiveUids.size()-1; i>=0; i--) {
20366            final UidRecord uidRec = mActiveUids.valueAt(i);
20367            int uidChange = UidRecord.CHANGE_PROCSTATE;
20368            if (uidRec.setProcState != uidRec.curProcState) {
20369                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20370                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20371                        + " to " + uidRec.curProcState);
20372                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20373                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20374                        uidRec.lastBackgroundTime = nowElapsed;
20375                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20376                            // Note: the background settle time is in elapsed realtime, while
20377                            // the handler time base is uptime.  All this means is that we may
20378                            // stop background uids later than we had intended, but that only
20379                            // happens because the device was sleeping so we are okay anyway.
20380                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20381                        }
20382                    }
20383                } else {
20384                    if (uidRec.idle) {
20385                        uidChange = UidRecord.CHANGE_ACTIVE;
20386                        uidRec.idle = false;
20387                    }
20388                    uidRec.lastBackgroundTime = 0;
20389                }
20390                uidRec.setProcState = uidRec.curProcState;
20391                enqueueUidChangeLocked(uidRec, -1, uidChange);
20392                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20393            }
20394        }
20395
20396        if (mProcessStats.shouldWriteNowLocked(now)) {
20397            mHandler.post(new Runnable() {
20398                @Override public void run() {
20399                    synchronized (ActivityManagerService.this) {
20400                        mProcessStats.writeStateAsyncLocked();
20401                    }
20402                }
20403            });
20404        }
20405
20406        if (DEBUG_OOM_ADJ) {
20407            final long duration = SystemClock.uptimeMillis() - now;
20408            if (false) {
20409                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20410                        new RuntimeException("here").fillInStackTrace());
20411            } else {
20412                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20413            }
20414        }
20415    }
20416
20417    final void idleUids() {
20418        synchronized (this) {
20419            final long nowElapsed = SystemClock.elapsedRealtime();
20420            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20421            long nextTime = 0;
20422            for (int i=mActiveUids.size()-1; i>=0; i--) {
20423                final UidRecord uidRec = mActiveUids.valueAt(i);
20424                final long bgTime = uidRec.lastBackgroundTime;
20425                if (bgTime > 0 && !uidRec.idle) {
20426                    if (bgTime <= maxBgTime) {
20427                        uidRec.idle = true;
20428                        doStopUidLocked(uidRec.uid, uidRec);
20429                    } else {
20430                        if (nextTime == 0 || nextTime > bgTime) {
20431                            nextTime = bgTime;
20432                        }
20433                    }
20434                }
20435            }
20436            if (nextTime > 0) {
20437                mHandler.removeMessages(IDLE_UIDS_MSG);
20438                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20439                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20440            }
20441        }
20442    }
20443
20444    final void runInBackgroundDisabled(int uid) {
20445        synchronized (this) {
20446            UidRecord uidRec = mActiveUids.get(uid);
20447            if (uidRec != null) {
20448                // This uid is actually running...  should it be considered background now?
20449                if (uidRec.idle) {
20450                    doStopUidLocked(uidRec.uid, uidRec);
20451                }
20452            } else {
20453                // This uid isn't actually running...  still send a report about it being "stopped".
20454                doStopUidLocked(uid, null);
20455            }
20456        }
20457    }
20458
20459    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20460        mServices.stopInBackgroundLocked(uid);
20461        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20462    }
20463
20464    final void trimApplications() {
20465        synchronized (this) {
20466            int i;
20467
20468            // First remove any unused application processes whose package
20469            // has been removed.
20470            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20471                final ProcessRecord app = mRemovedProcesses.get(i);
20472                if (app.activities.size() == 0
20473                        && app.curReceiver == null && app.services.size() == 0) {
20474                    Slog.i(
20475                        TAG, "Exiting empty application process "
20476                        + app.toShortString() + " ("
20477                        + (app.thread != null ? app.thread.asBinder() : null)
20478                        + ")\n");
20479                    if (app.pid > 0 && app.pid != MY_PID) {
20480                        app.kill("empty", false);
20481                    } else {
20482                        try {
20483                            app.thread.scheduleExit();
20484                        } catch (Exception e) {
20485                            // Ignore exceptions.
20486                        }
20487                    }
20488                    cleanUpApplicationRecordLocked(app, false, true, -1);
20489                    mRemovedProcesses.remove(i);
20490
20491                    if (app.persistent) {
20492                        addAppLocked(app.info, false, null /* ABI override */);
20493                    }
20494                }
20495            }
20496
20497            // Now update the oom adj for all processes.
20498            updateOomAdjLocked();
20499        }
20500    }
20501
20502    /** This method sends the specified signal to each of the persistent apps */
20503    public void signalPersistentProcesses(int sig) throws RemoteException {
20504        if (sig != Process.SIGNAL_USR1) {
20505            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20506        }
20507
20508        synchronized (this) {
20509            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20510                    != PackageManager.PERMISSION_GRANTED) {
20511                throw new SecurityException("Requires permission "
20512                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20513            }
20514
20515            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20516                ProcessRecord r = mLruProcesses.get(i);
20517                if (r.thread != null && r.persistent) {
20518                    Process.sendSignal(r.pid, sig);
20519                }
20520            }
20521        }
20522    }
20523
20524    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20525        if (proc == null || proc == mProfileProc) {
20526            proc = mProfileProc;
20527            profileType = mProfileType;
20528            clearProfilerLocked();
20529        }
20530        if (proc == null) {
20531            return;
20532        }
20533        try {
20534            proc.thread.profilerControl(false, null, profileType);
20535        } catch (RemoteException e) {
20536            throw new IllegalStateException("Process disappeared");
20537        }
20538    }
20539
20540    private void clearProfilerLocked() {
20541        if (mProfileFd != null) {
20542            try {
20543                mProfileFd.close();
20544            } catch (IOException e) {
20545            }
20546        }
20547        mProfileApp = null;
20548        mProfileProc = null;
20549        mProfileFile = null;
20550        mProfileType = 0;
20551        mAutoStopProfiler = false;
20552        mSamplingInterval = 0;
20553    }
20554
20555    public boolean profileControl(String process, int userId, boolean start,
20556            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20557
20558        try {
20559            synchronized (this) {
20560                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20561                // its own permission.
20562                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20563                        != PackageManager.PERMISSION_GRANTED) {
20564                    throw new SecurityException("Requires permission "
20565                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20566                }
20567
20568                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20569                    throw new IllegalArgumentException("null profile info or fd");
20570                }
20571
20572                ProcessRecord proc = null;
20573                if (process != null) {
20574                    proc = findProcessLocked(process, userId, "profileControl");
20575                }
20576
20577                if (start && (proc == null || proc.thread == null)) {
20578                    throw new IllegalArgumentException("Unknown process: " + process);
20579                }
20580
20581                if (start) {
20582                    stopProfilerLocked(null, 0);
20583                    setProfileApp(proc.info, proc.processName, profilerInfo);
20584                    mProfileProc = proc;
20585                    mProfileType = profileType;
20586                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20587                    try {
20588                        fd = fd.dup();
20589                    } catch (IOException e) {
20590                        fd = null;
20591                    }
20592                    profilerInfo.profileFd = fd;
20593                    proc.thread.profilerControl(start, profilerInfo, profileType);
20594                    fd = null;
20595                    mProfileFd = null;
20596                } else {
20597                    stopProfilerLocked(proc, profileType);
20598                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20599                        try {
20600                            profilerInfo.profileFd.close();
20601                        } catch (IOException e) {
20602                        }
20603                    }
20604                }
20605
20606                return true;
20607            }
20608        } catch (RemoteException e) {
20609            throw new IllegalStateException("Process disappeared");
20610        } finally {
20611            if (profilerInfo != null && profilerInfo.profileFd != null) {
20612                try {
20613                    profilerInfo.profileFd.close();
20614                } catch (IOException e) {
20615                }
20616            }
20617        }
20618    }
20619
20620    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20621        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20622                userId, true, ALLOW_FULL_ONLY, callName, null);
20623        ProcessRecord proc = null;
20624        try {
20625            int pid = Integer.parseInt(process);
20626            synchronized (mPidsSelfLocked) {
20627                proc = mPidsSelfLocked.get(pid);
20628            }
20629        } catch (NumberFormatException e) {
20630        }
20631
20632        if (proc == null) {
20633            ArrayMap<String, SparseArray<ProcessRecord>> all
20634                    = mProcessNames.getMap();
20635            SparseArray<ProcessRecord> procs = all.get(process);
20636            if (procs != null && procs.size() > 0) {
20637                proc = procs.valueAt(0);
20638                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20639                    for (int i=1; i<procs.size(); i++) {
20640                        ProcessRecord thisProc = procs.valueAt(i);
20641                        if (thisProc.userId == userId) {
20642                            proc = thisProc;
20643                            break;
20644                        }
20645                    }
20646                }
20647            }
20648        }
20649
20650        return proc;
20651    }
20652
20653    public boolean dumpHeap(String process, int userId, boolean managed,
20654            String path, ParcelFileDescriptor fd) throws RemoteException {
20655
20656        try {
20657            synchronized (this) {
20658                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20659                // its own permission (same as profileControl).
20660                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20661                        != PackageManager.PERMISSION_GRANTED) {
20662                    throw new SecurityException("Requires permission "
20663                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20664                }
20665
20666                if (fd == null) {
20667                    throw new IllegalArgumentException("null fd");
20668                }
20669
20670                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20671                if (proc == null || proc.thread == null) {
20672                    throw new IllegalArgumentException("Unknown process: " + process);
20673                }
20674
20675                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20676                if (!isDebuggable) {
20677                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20678                        throw new SecurityException("Process not debuggable: " + proc);
20679                    }
20680                }
20681
20682                proc.thread.dumpHeap(managed, path, fd);
20683                fd = null;
20684                return true;
20685            }
20686        } catch (RemoteException e) {
20687            throw new IllegalStateException("Process disappeared");
20688        } finally {
20689            if (fd != null) {
20690                try {
20691                    fd.close();
20692                } catch (IOException e) {
20693                }
20694            }
20695        }
20696    }
20697
20698    @Override
20699    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20700            String reportPackage) {
20701        if (processName != null) {
20702            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20703                    "setDumpHeapDebugLimit()");
20704        } else {
20705            synchronized (mPidsSelfLocked) {
20706                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20707                if (proc == null) {
20708                    throw new SecurityException("No process found for calling pid "
20709                            + Binder.getCallingPid());
20710                }
20711                if (!Build.IS_DEBUGGABLE
20712                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20713                    throw new SecurityException("Not running a debuggable build");
20714                }
20715                processName = proc.processName;
20716                uid = proc.uid;
20717                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20718                    throw new SecurityException("Package " + reportPackage + " is not running in "
20719                            + proc);
20720                }
20721            }
20722        }
20723        synchronized (this) {
20724            if (maxMemSize > 0) {
20725                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20726            } else {
20727                if (uid != 0) {
20728                    mMemWatchProcesses.remove(processName, uid);
20729                } else {
20730                    mMemWatchProcesses.getMap().remove(processName);
20731                }
20732            }
20733        }
20734    }
20735
20736    @Override
20737    public void dumpHeapFinished(String path) {
20738        synchronized (this) {
20739            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20740                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20741                        + " does not match last pid " + mMemWatchDumpPid);
20742                return;
20743            }
20744            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20745                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20746                        + " does not match last path " + mMemWatchDumpFile);
20747                return;
20748            }
20749            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20750            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20751        }
20752    }
20753
20754    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20755    public void monitor() {
20756        synchronized (this) { }
20757    }
20758
20759    void onCoreSettingsChange(Bundle settings) {
20760        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20761            ProcessRecord processRecord = mLruProcesses.get(i);
20762            try {
20763                if (processRecord.thread != null) {
20764                    processRecord.thread.setCoreSettings(settings);
20765                }
20766            } catch (RemoteException re) {
20767                /* ignore */
20768            }
20769        }
20770    }
20771
20772    // Multi-user methods
20773
20774    /**
20775     * Start user, if its not already running, but don't bring it to foreground.
20776     */
20777    @Override
20778    public boolean startUserInBackground(final int userId) {
20779        return mUserController.startUser(userId, /* foreground */ false);
20780    }
20781
20782    @Override
20783    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20784        return mUserController.unlockUser(userId, token, secret, listener);
20785    }
20786
20787    @Override
20788    public boolean switchUser(final int targetUserId) {
20789        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20790        UserInfo currentUserInfo;
20791        UserInfo targetUserInfo;
20792        synchronized (this) {
20793            int currentUserId = mUserController.getCurrentUserIdLocked();
20794            currentUserInfo = mUserController.getUserInfo(currentUserId);
20795            targetUserInfo = mUserController.getUserInfo(targetUserId);
20796            if (targetUserInfo == null) {
20797                Slog.w(TAG, "No user info for user #" + targetUserId);
20798                return false;
20799            }
20800            if (!targetUserInfo.supportsSwitchTo()) {
20801                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20802                return false;
20803            }
20804            if (targetUserInfo.isManagedProfile()) {
20805                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20806                return false;
20807            }
20808            mUserController.setTargetUserIdLocked(targetUserId);
20809        }
20810        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20811        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20812        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20813        return true;
20814    }
20815
20816    void scheduleStartProfilesLocked() {
20817        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20818            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20819                    DateUtils.SECOND_IN_MILLIS);
20820        }
20821    }
20822
20823    @Override
20824    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20825        return mUserController.stopUser(userId, force, callback);
20826    }
20827
20828    @Override
20829    public UserInfo getCurrentUser() {
20830        return mUserController.getCurrentUser();
20831    }
20832
20833    @Override
20834    public boolean isUserRunning(int userId, int flags) {
20835        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20836                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20837            String msg = "Permission Denial: isUserRunning() from pid="
20838                    + Binder.getCallingPid()
20839                    + ", uid=" + Binder.getCallingUid()
20840                    + " requires " + INTERACT_ACROSS_USERS;
20841            Slog.w(TAG, msg);
20842            throw new SecurityException(msg);
20843        }
20844        synchronized (this) {
20845            return mUserController.isUserRunningLocked(userId, flags);
20846        }
20847    }
20848
20849    @Override
20850    public int[] getRunningUserIds() {
20851        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20852                != PackageManager.PERMISSION_GRANTED) {
20853            String msg = "Permission Denial: isUserRunning() from pid="
20854                    + Binder.getCallingPid()
20855                    + ", uid=" + Binder.getCallingUid()
20856                    + " requires " + INTERACT_ACROSS_USERS;
20857            Slog.w(TAG, msg);
20858            throw new SecurityException(msg);
20859        }
20860        synchronized (this) {
20861            return mUserController.getStartedUserArrayLocked();
20862        }
20863    }
20864
20865    @Override
20866    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20867        mUserController.registerUserSwitchObserver(observer);
20868    }
20869
20870    @Override
20871    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20872        mUserController.unregisterUserSwitchObserver(observer);
20873    }
20874
20875    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20876        if (info == null) return null;
20877        ApplicationInfo newInfo = new ApplicationInfo(info);
20878        newInfo.initForUser(userId);
20879        return newInfo;
20880    }
20881
20882    public boolean isUserStopped(int userId) {
20883        synchronized (this) {
20884            return mUserController.getStartedUserStateLocked(userId) == null;
20885        }
20886    }
20887
20888    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20889        if (aInfo == null
20890                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20891            return aInfo;
20892        }
20893
20894        ActivityInfo info = new ActivityInfo(aInfo);
20895        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20896        return info;
20897    }
20898
20899    private boolean processSanityChecksLocked(ProcessRecord process) {
20900        if (process == null || process.thread == null) {
20901            return false;
20902        }
20903
20904        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20905        if (!isDebuggable) {
20906            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20907                return false;
20908            }
20909        }
20910
20911        return true;
20912    }
20913
20914    public boolean startBinderTracking() throws RemoteException {
20915        synchronized (this) {
20916            mBinderTransactionTrackingEnabled = true;
20917            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20918            // permission (same as profileControl).
20919            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20920                    != PackageManager.PERMISSION_GRANTED) {
20921                throw new SecurityException("Requires permission "
20922                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20923            }
20924
20925            for (int i = 0; i < mLruProcesses.size(); i++) {
20926                ProcessRecord process = mLruProcesses.get(i);
20927                if (!processSanityChecksLocked(process)) {
20928                    continue;
20929                }
20930                try {
20931                    process.thread.startBinderTracking();
20932                } catch (RemoteException e) {
20933                    Log.v(TAG, "Process disappared");
20934                }
20935            }
20936            return true;
20937        }
20938    }
20939
20940    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20941        try {
20942            synchronized (this) {
20943                mBinderTransactionTrackingEnabled = false;
20944                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20945                // permission (same as profileControl).
20946                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20947                        != PackageManager.PERMISSION_GRANTED) {
20948                    throw new SecurityException("Requires permission "
20949                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20950                }
20951
20952                if (fd == null) {
20953                    throw new IllegalArgumentException("null fd");
20954                }
20955
20956                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20957                pw.println("Binder transaction traces for all processes.\n");
20958                for (ProcessRecord process : mLruProcesses) {
20959                    if (!processSanityChecksLocked(process)) {
20960                        continue;
20961                    }
20962
20963                    pw.println("Traces for process: " + process.processName);
20964                    pw.flush();
20965                    try {
20966                        TransferPipe tp = new TransferPipe();
20967                        try {
20968                            process.thread.stopBinderTrackingAndDump(
20969                                    tp.getWriteFd().getFileDescriptor());
20970                            tp.go(fd.getFileDescriptor());
20971                        } finally {
20972                            tp.kill();
20973                        }
20974                    } catch (IOException e) {
20975                        pw.println("Failure while dumping IPC traces from " + process +
20976                                ".  Exception: " + e);
20977                        pw.flush();
20978                    } catch (RemoteException e) {
20979                        pw.println("Got a RemoteException while dumping IPC traces from " +
20980                                process + ".  Exception: " + e);
20981                        pw.flush();
20982                    }
20983                }
20984                fd = null;
20985                return true;
20986            }
20987        } finally {
20988            if (fd != null) {
20989                try {
20990                    fd.close();
20991                } catch (IOException e) {
20992                }
20993            }
20994        }
20995    }
20996
20997    private final class LocalService extends ActivityManagerInternal {
20998        @Override
20999        public void onWakefulnessChanged(int wakefulness) {
21000            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21001        }
21002
21003        @Override
21004        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21005                String processName, String abiOverride, int uid, Runnable crashHandler) {
21006            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21007                    processName, abiOverride, uid, crashHandler);
21008        }
21009
21010        @Override
21011        public SleepToken acquireSleepToken(String tag) {
21012            Preconditions.checkNotNull(tag);
21013
21014            synchronized (ActivityManagerService.this) {
21015                SleepTokenImpl token = new SleepTokenImpl(tag);
21016                mSleepTokens.add(token);
21017                updateSleepIfNeededLocked();
21018                applyVrModeIfNeededLocked(mFocusedActivity, false);
21019                return token;
21020            }
21021        }
21022
21023        @Override
21024        public ComponentName getHomeActivityForUser(int userId) {
21025            synchronized (ActivityManagerService.this) {
21026                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21027                return homeActivity == null ? null : homeActivity.realActivity;
21028            }
21029        }
21030
21031        @Override
21032        public void onUserRemoved(int userId) {
21033            synchronized (ActivityManagerService.this) {
21034                ActivityManagerService.this.onUserStoppedLocked(userId);
21035            }
21036        }
21037
21038        @Override
21039        public void onLocalVoiceInteractionStarted(IBinder activity,
21040                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21041            synchronized (ActivityManagerService.this) {
21042                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21043                        voiceSession, voiceInteractor);
21044            }
21045        }
21046
21047        @Override
21048        public void notifyStartingWindowDrawn() {
21049            synchronized (ActivityManagerService.this) {
21050                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21051            }
21052        }
21053
21054        @Override
21055        public void notifyAppTransitionStarting(int reason) {
21056            synchronized (ActivityManagerService.this) {
21057                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21058            }
21059        }
21060
21061        @Override
21062        public void notifyAppTransitionFinished() {
21063            synchronized (ActivityManagerService.this) {
21064                mStackSupervisor.notifyAppTransitionDone();
21065            }
21066        }
21067
21068        @Override
21069        public void notifyAppTransitionCancelled() {
21070            synchronized (ActivityManagerService.this) {
21071                mStackSupervisor.notifyAppTransitionDone();
21072            }
21073        }
21074
21075        @Override
21076        public List<IBinder> getTopVisibleActivities() {
21077            synchronized (ActivityManagerService.this) {
21078                return mStackSupervisor.getTopVisibleActivities();
21079            }
21080        }
21081
21082        @Override
21083        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21084            synchronized (ActivityManagerService.this) {
21085                mStackSupervisor.setDockedStackMinimized(minimized);
21086            }
21087        }
21088
21089        @Override
21090        public void killForegroundAppsForUser(int userHandle) {
21091            synchronized (ActivityManagerService.this) {
21092                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21093                final int NP = mProcessNames.getMap().size();
21094                for (int ip = 0; ip < NP; ip++) {
21095                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21096                    final int NA = apps.size();
21097                    for (int ia = 0; ia < NA; ia++) {
21098                        final ProcessRecord app = apps.valueAt(ia);
21099                        if (app.persistent) {
21100                            // We don't kill persistent processes.
21101                            continue;
21102                        }
21103                        if (app.removed) {
21104                            procs.add(app);
21105                        } else if (app.userId == userHandle && app.foregroundActivities) {
21106                            app.removed = true;
21107                            procs.add(app);
21108                        }
21109                    }
21110                }
21111
21112                final int N = procs.size();
21113                for (int i = 0; i < N; i++) {
21114                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21115                }
21116            }
21117        }
21118    }
21119
21120    private final class SleepTokenImpl extends SleepToken {
21121        private final String mTag;
21122        private final long mAcquireTime;
21123
21124        public SleepTokenImpl(String tag) {
21125            mTag = tag;
21126            mAcquireTime = SystemClock.uptimeMillis();
21127        }
21128
21129        @Override
21130        public void release() {
21131            synchronized (ActivityManagerService.this) {
21132                if (mSleepTokens.remove(this)) {
21133                    updateSleepIfNeededLocked();
21134                }
21135            }
21136        }
21137
21138        @Override
21139        public String toString() {
21140            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21141        }
21142    }
21143
21144    /**
21145     * An implementation of IAppTask, that allows an app to manage its own tasks via
21146     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21147     * only the process that calls getAppTasks() can call the AppTask methods.
21148     */
21149    class AppTaskImpl extends IAppTask.Stub {
21150        private int mTaskId;
21151        private int mCallingUid;
21152
21153        public AppTaskImpl(int taskId, int callingUid) {
21154            mTaskId = taskId;
21155            mCallingUid = callingUid;
21156        }
21157
21158        private void checkCaller() {
21159            if (mCallingUid != Binder.getCallingUid()) {
21160                throw new SecurityException("Caller " + mCallingUid
21161                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21162            }
21163        }
21164
21165        @Override
21166        public void finishAndRemoveTask() {
21167            checkCaller();
21168
21169            synchronized (ActivityManagerService.this) {
21170                long origId = Binder.clearCallingIdentity();
21171                try {
21172                    // We remove the task from recents to preserve backwards
21173                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21174                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21175                    }
21176                } finally {
21177                    Binder.restoreCallingIdentity(origId);
21178                }
21179            }
21180        }
21181
21182        @Override
21183        public ActivityManager.RecentTaskInfo getTaskInfo() {
21184            checkCaller();
21185
21186            synchronized (ActivityManagerService.this) {
21187                long origId = Binder.clearCallingIdentity();
21188                try {
21189                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21190                    if (tr == null) {
21191                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21192                    }
21193                    return createRecentTaskInfoFromTaskRecord(tr);
21194                } finally {
21195                    Binder.restoreCallingIdentity(origId);
21196                }
21197            }
21198        }
21199
21200        @Override
21201        public void moveToFront() {
21202            checkCaller();
21203            // Will bring task to front if it already has a root activity.
21204            final long origId = Binder.clearCallingIdentity();
21205            try {
21206                synchronized (this) {
21207                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21208                }
21209            } finally {
21210                Binder.restoreCallingIdentity(origId);
21211            }
21212        }
21213
21214        @Override
21215        public int startActivity(IBinder whoThread, String callingPackage,
21216                Intent intent, String resolvedType, Bundle bOptions) {
21217            checkCaller();
21218
21219            int callingUser = UserHandle.getCallingUserId();
21220            TaskRecord tr;
21221            IApplicationThread appThread;
21222            synchronized (ActivityManagerService.this) {
21223                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21224                if (tr == null) {
21225                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21226                }
21227                appThread = ApplicationThreadNative.asInterface(whoThread);
21228                if (appThread == null) {
21229                    throw new IllegalArgumentException("Bad app thread " + appThread);
21230                }
21231            }
21232            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21233                    resolvedType, null, null, null, null, 0, 0, null, null,
21234                    null, bOptions, false, callingUser, null, tr);
21235        }
21236
21237        @Override
21238        public void setExcludeFromRecents(boolean exclude) {
21239            checkCaller();
21240
21241            synchronized (ActivityManagerService.this) {
21242                long origId = Binder.clearCallingIdentity();
21243                try {
21244                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21245                    if (tr == null) {
21246                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21247                    }
21248                    Intent intent = tr.getBaseIntent();
21249                    if (exclude) {
21250                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21251                    } else {
21252                        intent.setFlags(intent.getFlags()
21253                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21254                    }
21255                } finally {
21256                    Binder.restoreCallingIdentity(origId);
21257                }
21258            }
21259        }
21260    }
21261
21262    /**
21263     * Kill processes for the user with id userId and that depend on the package named packageName
21264     */
21265    @Override
21266    public void killPackageDependents(String packageName, int userId) {
21267        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21268        if (packageName == null) {
21269            throw new NullPointerException(
21270                    "Cannot kill the dependents of a package without its name.");
21271        }
21272
21273        long callingId = Binder.clearCallingIdentity();
21274        IPackageManager pm = AppGlobals.getPackageManager();
21275        int pkgUid = -1;
21276        try {
21277            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21278        } catch (RemoteException e) {
21279        }
21280        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21281            throw new IllegalArgumentException(
21282                    "Cannot kill dependents of non-existing package " + packageName);
21283        }
21284        try {
21285            synchronized(this) {
21286                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21287                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21288                        "dep: " + packageName);
21289            }
21290        } finally {
21291            Binder.restoreCallingIdentity(callingId);
21292        }
21293    }
21294}
21295