ActivityManagerService.java revision 15e66cd5af7a08dc603de11cba40eac36d1ed580
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.Objects;
243import java.util.Set;
244import java.util.concurrent.atomic.AtomicBoolean;
245import java.util.concurrent.atomic.AtomicLong;
246
247import dalvik.system.VMRuntime;
248
249import libcore.io.IoUtils;
250import libcore.util.EmptyArray;
251
252import static android.Manifest.permission.INTERACT_ACROSS_USERS;
253import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
254import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
255import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
256import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
257import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
258import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
259import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
260import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
261import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.HOME_STACK_ID;
263import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
264import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
265import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
266import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
267import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
268import static android.content.pm.PackageManager.GET_PROVIDERS;
269import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
270import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
271import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
272import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
273import static android.content.pm.PackageManager.PERMISSION_GRANTED;
274import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
275import static android.provider.Settings.Global.DEBUG_APP;
276import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
277import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
278import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
279import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
280import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
281import static android.provider.Settings.System.FONT_SCALE;
282import static com.android.internal.util.XmlUtils.readBooleanAttribute;
283import static com.android.internal.util.XmlUtils.readIntAttribute;
284import static com.android.internal.util.XmlUtils.readLongAttribute;
285import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
286import static com.android.internal.util.XmlUtils.writeIntAttribute;
287import static com.android.internal.util.XmlUtils.writeLongAttribute;
288import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
289import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
290import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
291import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
292import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
293import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
294import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
320import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
321import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
322import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
323import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
324import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
325import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
326import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
327import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
344import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
345import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
346import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
347import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
348import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
349import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
350import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
351import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
352import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
353import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
354import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
355import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
356import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
357import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
358import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
359import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
360import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
361import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
362import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
363import static org.xmlpull.v1.XmlPullParser.START_TAG;
364
365public final class ActivityManagerService extends ActivityManagerNative
366        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
367
368    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
369    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
370    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
371    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
372    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
373    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
374    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
375    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
376    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
377    private static final String TAG_LRU = TAG + POSTFIX_LRU;
378    private static final String TAG_MU = TAG + POSTFIX_MU;
379    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
380    private static final String TAG_POWER = TAG + POSTFIX_POWER;
381    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
382    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
383    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
384    private static final String TAG_PSS = TAG + POSTFIX_PSS;
385    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
386    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
387    private static final String TAG_STACK = TAG + POSTFIX_STACK;
388    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
389    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
390    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
391    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
392    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
393
394    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
395    // here so that while the job scheduler can depend on AMS, the other way around
396    // need not be the case.
397    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
398
399    /** Control over CPU and battery monitoring */
400    // write battery stats every 30 minutes.
401    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
402    static final boolean MONITOR_CPU_USAGE = true;
403    // don't sample cpu less than every 5 seconds.
404    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
405    // wait possibly forever for next cpu sample.
406    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
407    static final boolean MONITOR_THREAD_CPU_USAGE = false;
408
409    // The flags that are set for all calls we make to the package manager.
410    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
411
412    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
413
414    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
415
416    // Amount of time after a call to stopAppSwitches() during which we will
417    // prevent further untrusted switches from happening.
418    static final long APP_SWITCH_DELAY_TIME = 5*1000;
419
420    // How long we wait for a launched process to attach to the activity manager
421    // before we decide it's never going to come up for real.
422    static final int PROC_START_TIMEOUT = 10*1000;
423    // How long we wait for an attached process to publish its content providers
424    // before we decide it must be hung.
425    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
426
427    // How long we will retain processes hosting content providers in the "last activity"
428    // state before allowing them to drop down to the regular cached LRU list.  This is
429    // to avoid thrashing of provider processes under low memory situations.
430    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
431
432    // How long we wait for a launched process to attach to the activity manager
433    // before we decide it's never going to come up for real, when the process was
434    // started with a wrapper for instrumentation (such as Valgrind) because it
435    // could take much longer than usual.
436    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
437
438    // How long to wait after going idle before forcing apps to GC.
439    static final int GC_TIMEOUT = 5*1000;
440
441    // The minimum amount of time between successive GC requests for a process.
442    static final int GC_MIN_INTERVAL = 60*1000;
443
444    // The minimum amount of time between successive PSS requests for a process.
445    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
446
447    // The minimum amount of time between successive PSS requests for a process
448    // when the request is due to the memory state being lowered.
449    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
450
451    // The rate at which we check for apps using excessive power -- 15 mins.
452    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
453
454    // The minimum sample duration we will allow before deciding we have
455    // enough data on wake locks to start killing things.
456    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
457
458    // The minimum sample duration we will allow before deciding we have
459    // enough data on CPU usage to start killing things.
460    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
461
462    // How long we allow a receiver to run before giving up on it.
463    static final int BROADCAST_FG_TIMEOUT = 10*1000;
464    static final int BROADCAST_BG_TIMEOUT = 60*1000;
465
466    // How long we wait until we timeout on key dispatching.
467    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
468
469    // How long we wait until we timeout on key dispatching during instrumentation.
470    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
471
472    // This is the amount of time an app needs to be running a foreground service before
473    // we will consider it to be doing interaction for usage stats.
474    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
475
476    // Maximum amount of time we will allow to elapse before re-reporting usage stats
477    // interaction with foreground processes.
478    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
479
480    // This is the amount of time we allow an app to settle after it goes into the background,
481    // before we start restricting what it can do.
482    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
483
484    // How long to wait in getAssistContextExtras for the activity and foreground services
485    // to respond with the result.
486    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
487
488    // How long top wait when going through the modern assist (which doesn't need to block
489    // on getting this result before starting to launch its UI).
490    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
491
492    // Maximum number of persisted Uri grants a package is allowed
493    static final int MAX_PERSISTED_URI_GRANTS = 128;
494
495    static final int MY_PID = Process.myPid();
496
497    static final String[] EMPTY_STRING_ARRAY = new String[0];
498
499    // How many bytes to write into the dropbox log before truncating
500    static final int DROPBOX_MAX_SIZE = 256 * 1024;
501
502    // Access modes for handleIncomingUser.
503    static final int ALLOW_NON_FULL = 0;
504    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
505    static final int ALLOW_FULL_ONLY = 2;
506
507    // Delay in notifying task stack change listeners (in millis)
508    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
509
510    // Necessary ApplicationInfo flags to mark an app as persistent
511    private static final int PERSISTENT_MASK =
512            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
513
514    // Intent sent when remote bugreport collection has been completed
515    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
516            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
517
518    // Delay to disable app launch boost
519    static final int APP_BOOST_MESSAGE_DELAY = 3000;
520    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
521    static final int APP_BOOST_TIMEOUT = 2500;
522
523    // Used to indicate that a task is removed it should also be removed from recents.
524    private static final boolean REMOVE_FROM_RECENTS = true;
525    // Used to indicate that an app transition should be animated.
526    static final boolean ANIMATE = true;
527
528    // Determines whether to take full screen screenshots
529    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
530    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
531
532    private static native int nativeMigrateToBoost();
533    private static native int nativeMigrateFromBoost();
534    private boolean mIsBoosted = false;
535    private long mBoostStartTime = 0;
536
537    /** All system services */
538    SystemServiceManager mSystemServiceManager;
539
540    private Installer mInstaller;
541
542    /** Run all ActivityStacks through this */
543    final ActivityStackSupervisor mStackSupervisor;
544
545    final ActivityStarter mActivityStarter;
546
547    /** Task stack change listeners. */
548    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
549            new RemoteCallbackList<ITaskStackListener>();
550
551    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
552
553    public IntentFirewall mIntentFirewall;
554
555    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
556    // default actuion automatically.  Important for devices without direct input
557    // devices.
558    private boolean mShowDialogs = true;
559    private boolean mInVrMode = false;
560
561    BroadcastQueue mFgBroadcastQueue;
562    BroadcastQueue mBgBroadcastQueue;
563    // Convenient for easy iteration over the queues. Foreground is first
564    // so that dispatch of foreground broadcasts gets precedence.
565    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
566
567    BroadcastQueue broadcastQueueForIntent(Intent intent) {
568        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
569        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
570                "Broadcast intent " + intent + " on "
571                + (isFg ? "foreground" : "background") + " queue");
572        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
573    }
574
575    /**
576     * Activity we have told the window manager to have key focus.
577     */
578    ActivityRecord mFocusedActivity = null;
579
580    /**
581     * User id of the last activity mFocusedActivity was set to.
582     */
583    private int mLastFocusedUserId;
584
585    /**
586     * If non-null, we are tracking the time the user spends in the currently focused app.
587     */
588    private AppTimeTracker mCurAppTimeTracker;
589
590    /**
591     * List of intents that were used to start the most recent tasks.
592     */
593    final RecentTasks mRecentTasks;
594
595    /**
596     * For addAppTask: cached of the last activity component that was added.
597     */
598    ComponentName mLastAddedTaskComponent;
599
600    /**
601     * For addAppTask: cached of the last activity uid that was added.
602     */
603    int mLastAddedTaskUid;
604
605    /**
606     * For addAppTask: cached of the last ActivityInfo that was added.
607     */
608    ActivityInfo mLastAddedTaskActivity;
609
610    /**
611     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
612     */
613    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
614
615    /**
616     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
617     */
618    String mDeviceOwnerName;
619
620    final UserController mUserController;
621
622    final AppErrors mAppErrors;
623
624    boolean mDoingSetFocusedActivity;
625
626    public boolean canShowErrorDialogs() {
627        return mShowDialogs && !mSleeping && !mShuttingDown;
628    }
629
630    public class PendingAssistExtras extends Binder implements Runnable {
631        public final ActivityRecord activity;
632        public final Bundle extras;
633        public final Intent intent;
634        public final String hint;
635        public final IResultReceiver receiver;
636        public final int userHandle;
637        public boolean haveResult = false;
638        public Bundle result = null;
639        public AssistStructure structure = null;
640        public AssistContent content = null;
641        public Bundle receiverExtras;
642
643        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
644                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
645            activity = _activity;
646            extras = _extras;
647            intent = _intent;
648            hint = _hint;
649            receiver = _receiver;
650            receiverExtras = _receiverExtras;
651            userHandle = _userHandle;
652        }
653        @Override
654        public void run() {
655            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
656            synchronized (this) {
657                haveResult = true;
658                notifyAll();
659            }
660            pendingAssistExtrasTimedOut(this);
661        }
662    }
663
664    final ArrayList<PendingAssistExtras> mPendingAssistExtras
665            = new ArrayList<PendingAssistExtras>();
666
667    /**
668     * Process management.
669     */
670    final ProcessList mProcessList = new ProcessList();
671
672    /**
673     * All of the applications we currently have running organized by name.
674     * The keys are strings of the application package name (as
675     * returned by the package manager), and the keys are ApplicationRecord
676     * objects.
677     */
678    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
679
680    /**
681     * Tracking long-term execution of processes to look for abuse and other
682     * bad app behavior.
683     */
684    final ProcessStatsService mProcessStats;
685
686    /**
687     * The currently running isolated processes.
688     */
689    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
690
691    /**
692     * Counter for assigning isolated process uids, to avoid frequently reusing the
693     * same ones.
694     */
695    int mNextIsolatedProcessUid = 0;
696
697    /**
698     * The currently running heavy-weight process, if any.
699     */
700    ProcessRecord mHeavyWeightProcess = null;
701
702    /**
703     * All of the processes we currently have running organized by pid.
704     * The keys are the pid running the application.
705     *
706     * <p>NOTE: This object is protected by its own lock, NOT the global
707     * activity manager lock!
708     */
709    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
710
711    /**
712     * All of the processes that have been forced to be foreground.  The key
713     * is the pid of the caller who requested it (we hold a death
714     * link on it).
715     */
716    abstract class ForegroundToken implements IBinder.DeathRecipient {
717        int pid;
718        IBinder token;
719    }
720    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
721
722    /**
723     * List of records for processes that someone had tried to start before the
724     * system was ready.  We don't start them at that point, but ensure they
725     * are started by the time booting is complete.
726     */
727    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
728
729    /**
730     * List of persistent applications that are in the process
731     * of being started.
732     */
733    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
734
735    /**
736     * Processes that are being forcibly torn down.
737     */
738    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
739
740    /**
741     * List of running applications, sorted by recent usage.
742     * The first entry in the list is the least recently used.
743     */
744    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
745
746    /**
747     * Where in mLruProcesses that the processes hosting activities start.
748     */
749    int mLruProcessActivityStart = 0;
750
751    /**
752     * Where in mLruProcesses that the processes hosting services start.
753     * This is after (lower index) than mLruProcessesActivityStart.
754     */
755    int mLruProcessServiceStart = 0;
756
757    /**
758     * List of processes that should gc as soon as things are idle.
759     */
760    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
761
762    /**
763     * Processes we want to collect PSS data from.
764     */
765    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
766
767    private boolean mBinderTransactionTrackingEnabled = false;
768
769    /**
770     * Last time we requested PSS data of all processes.
771     */
772    long mLastFullPssTime = SystemClock.uptimeMillis();
773
774    /**
775     * If set, the next time we collect PSS data we should do a full collection
776     * with data from native processes and the kernel.
777     */
778    boolean mFullPssPending = false;
779
780    /**
781     * This is the process holding what we currently consider to be
782     * the "home" activity.
783     */
784    ProcessRecord mHomeProcess;
785
786    /**
787     * This is the process holding the activity the user last visited that
788     * is in a different process from the one they are currently in.
789     */
790    ProcessRecord mPreviousProcess;
791
792    /**
793     * The time at which the previous process was last visible.
794     */
795    long mPreviousProcessVisibleTime;
796
797    /**
798     * Track all uids that have actively running processes.
799     */
800    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
801
802    /**
803     * This is for verifying the UID report flow.
804     */
805    static final boolean VALIDATE_UID_STATES = true;
806    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
807
808    /**
809     * Packages that the user has asked to have run in screen size
810     * compatibility mode instead of filling the screen.
811     */
812    final CompatModePackages mCompatModePackages;
813
814    /**
815     * Set of IntentSenderRecord objects that are currently active.
816     */
817    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
818            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
819
820    /**
821     * Fingerprints (hashCode()) of stack traces that we've
822     * already logged DropBox entries for.  Guarded by itself.  If
823     * something (rogue user app) forces this over
824     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
825     */
826    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
827    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
828
829    /**
830     * Strict Mode background batched logging state.
831     *
832     * The string buffer is guarded by itself, and its lock is also
833     * used to determine if another batched write is already
834     * in-flight.
835     */
836    private final StringBuilder mStrictModeBuffer = new StringBuilder();
837
838    /**
839     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
840     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
841     */
842    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
843
844    /**
845     * Resolver for broadcast intents to registered receivers.
846     * Holds BroadcastFilter (subclass of IntentFilter).
847     */
848    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
849            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
850        @Override
851        protected boolean allowFilterResult(
852                BroadcastFilter filter, List<BroadcastFilter> dest) {
853            IBinder target = filter.receiverList.receiver.asBinder();
854            for (int i = dest.size() - 1; i >= 0; i--) {
855                if (dest.get(i).receiverList.receiver.asBinder() == target) {
856                    return false;
857                }
858            }
859            return true;
860        }
861
862        @Override
863        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
864            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
865                    || userId == filter.owningUserId) {
866                return super.newResult(filter, match, userId);
867            }
868            return null;
869        }
870
871        @Override
872        protected BroadcastFilter[] newArray(int size) {
873            return new BroadcastFilter[size];
874        }
875
876        @Override
877        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
878            return packageName.equals(filter.packageName);
879        }
880    };
881
882    /**
883     * State of all active sticky broadcasts per user.  Keys are the action of the
884     * sticky Intent, values are an ArrayList of all broadcasted intents with
885     * that action (which should usually be one).  The SparseArray is keyed
886     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
887     * for stickies that are sent to all users.
888     */
889    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
890            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
891
892    final ActiveServices mServices;
893
894    final static class Association {
895        final int mSourceUid;
896        final String mSourceProcess;
897        final int mTargetUid;
898        final ComponentName mTargetComponent;
899        final String mTargetProcess;
900
901        int mCount;
902        long mTime;
903
904        int mNesting;
905        long mStartTime;
906
907        // states of the source process when the bind occurred.
908        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
909        long mLastStateUptime;
910        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
911                - ActivityManager.MIN_PROCESS_STATE+1];
912
913        Association(int sourceUid, String sourceProcess, int targetUid,
914                ComponentName targetComponent, String targetProcess) {
915            mSourceUid = sourceUid;
916            mSourceProcess = sourceProcess;
917            mTargetUid = targetUid;
918            mTargetComponent = targetComponent;
919            mTargetProcess = targetProcess;
920        }
921    }
922
923    /**
924     * When service association tracking is enabled, this is all of the associations we
925     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
926     * -> association data.
927     */
928    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
929            mAssociations = new SparseArray<>();
930    boolean mTrackingAssociations;
931
932    /**
933     * Backup/restore process management
934     */
935    String mBackupAppName = null;
936    BackupRecord mBackupTarget = null;
937
938    final ProviderMap mProviderMap;
939
940    /**
941     * List of content providers who have clients waiting for them.  The
942     * application is currently being launched and the provider will be
943     * removed from this list once it is published.
944     */
945    final ArrayList<ContentProviderRecord> mLaunchingProviders
946            = new ArrayList<ContentProviderRecord>();
947
948    /**
949     * File storing persisted {@link #mGrantedUriPermissions}.
950     */
951    private final AtomicFile mGrantFile;
952
953    /** XML constants used in {@link #mGrantFile} */
954    private static final String TAG_URI_GRANTS = "uri-grants";
955    private static final String TAG_URI_GRANT = "uri-grant";
956    private static final String ATTR_USER_HANDLE = "userHandle";
957    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
958    private static final String ATTR_TARGET_USER_ID = "targetUserId";
959    private static final String ATTR_SOURCE_PKG = "sourcePkg";
960    private static final String ATTR_TARGET_PKG = "targetPkg";
961    private static final String ATTR_URI = "uri";
962    private static final String ATTR_MODE_FLAGS = "modeFlags";
963    private static final String ATTR_CREATED_TIME = "createdTime";
964    private static final String ATTR_PREFIX = "prefix";
965
966    /**
967     * Global set of specific {@link Uri} permissions that have been granted.
968     * This optimized lookup structure maps from {@link UriPermission#targetUid}
969     * to {@link UriPermission#uri} to {@link UriPermission}.
970     */
971    @GuardedBy("this")
972    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
973            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
974
975    public static class GrantUri {
976        public final int sourceUserId;
977        public final Uri uri;
978        public boolean prefix;
979
980        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
981            this.sourceUserId = sourceUserId;
982            this.uri = uri;
983            this.prefix = prefix;
984        }
985
986        @Override
987        public int hashCode() {
988            int hashCode = 1;
989            hashCode = 31 * hashCode + sourceUserId;
990            hashCode = 31 * hashCode + uri.hashCode();
991            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
992            return hashCode;
993        }
994
995        @Override
996        public boolean equals(Object o) {
997            if (o instanceof GrantUri) {
998                GrantUri other = (GrantUri) o;
999                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1000                        && prefix == other.prefix;
1001            }
1002            return false;
1003        }
1004
1005        @Override
1006        public String toString() {
1007            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1008            if (prefix) result += " [prefix]";
1009            return result;
1010        }
1011
1012        public String toSafeString() {
1013            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1014            if (prefix) result += " [prefix]";
1015            return result;
1016        }
1017
1018        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1019            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1020                    ContentProvider.getUriWithoutUserId(uri), false);
1021        }
1022    }
1023
1024    CoreSettingsObserver mCoreSettingsObserver;
1025
1026    FontScaleSettingObserver mFontScaleSettingObserver;
1027
1028    private final class FontScaleSettingObserver extends ContentObserver {
1029        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1030
1031        public FontScaleSettingObserver() {
1032            super(mHandler);
1033            ContentResolver resolver = mContext.getContentResolver();
1034            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1035        }
1036
1037        @Override
1038        public void onChange(boolean selfChange, Uri uri) {
1039            if (mFontScaleUri.equals(uri)) {
1040                updateFontScaleIfNeeded();
1041            }
1042        }
1043    }
1044
1045    /**
1046     * Thread-local storage used to carry caller permissions over through
1047     * indirect content-provider access.
1048     */
1049    private class Identity {
1050        public final IBinder token;
1051        public final int pid;
1052        public final int uid;
1053
1054        Identity(IBinder _token, int _pid, int _uid) {
1055            token = _token;
1056            pid = _pid;
1057            uid = _uid;
1058        }
1059    }
1060
1061    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1062
1063    /**
1064     * All information we have collected about the runtime performance of
1065     * any user id that can impact battery performance.
1066     */
1067    final BatteryStatsService mBatteryStatsService;
1068
1069    /**
1070     * Information about component usage
1071     */
1072    UsageStatsManagerInternal mUsageStatsService;
1073
1074    /**
1075     * Access to DeviceIdleController service.
1076     */
1077    DeviceIdleController.LocalService mLocalDeviceIdleController;
1078
1079    /**
1080     * Information about and control over application operations
1081     */
1082    final AppOpsService mAppOpsService;
1083
1084    /**
1085     * Current configuration information.  HistoryRecord objects are given
1086     * a reference to this object to indicate which configuration they are
1087     * currently running in, so this object must be kept immutable.
1088     */
1089    Configuration mConfiguration = new Configuration();
1090
1091    /**
1092     * Current sequencing integer of the configuration, for skipping old
1093     * configurations.
1094     */
1095    int mConfigurationSeq = 0;
1096
1097    boolean mSuppressResizeConfigChanges = false;
1098
1099    /**
1100     * Hardware-reported OpenGLES version.
1101     */
1102    final int GL_ES_VERSION;
1103
1104    /**
1105     * List of initialization arguments to pass to all processes when binding applications to them.
1106     * For example, references to the commonly used services.
1107     */
1108    HashMap<String, IBinder> mAppBindArgs;
1109
1110    /**
1111     * Temporary to avoid allocations.  Protected by main lock.
1112     */
1113    final StringBuilder mStringBuilder = new StringBuilder(256);
1114
1115    /**
1116     * Used to control how we initialize the service.
1117     */
1118    ComponentName mTopComponent;
1119    String mTopAction = Intent.ACTION_MAIN;
1120    String mTopData;
1121
1122    volatile boolean mProcessesReady = false;
1123    volatile boolean mSystemReady = false;
1124    volatile boolean mOnBattery = false;
1125    volatile int mFactoryTest;
1126
1127    @GuardedBy("this") boolean mBooting = false;
1128    @GuardedBy("this") boolean mCallFinishBooting = false;
1129    @GuardedBy("this") boolean mBootAnimationComplete = false;
1130    @GuardedBy("this") boolean mLaunchWarningShown = false;
1131    @GuardedBy("this") boolean mCheckedForSetup = false;
1132
1133    Context mContext;
1134
1135    /**
1136     * The time at which we will allow normal application switches again,
1137     * after a call to {@link #stopAppSwitches()}.
1138     */
1139    long mAppSwitchesAllowedTime;
1140
1141    /**
1142     * This is set to true after the first switch after mAppSwitchesAllowedTime
1143     * is set; any switches after that will clear the time.
1144     */
1145    boolean mDidAppSwitch;
1146
1147    /**
1148     * Last time (in realtime) at which we checked for power usage.
1149     */
1150    long mLastPowerCheckRealtime;
1151
1152    /**
1153     * Last time (in uptime) at which we checked for power usage.
1154     */
1155    long mLastPowerCheckUptime;
1156
1157    /**
1158     * Set while we are wanting to sleep, to prevent any
1159     * activities from being started/resumed.
1160     */
1161    private boolean mSleeping = false;
1162
1163    /**
1164     * The process state used for processes that are running the top activities.
1165     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1166     */
1167    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1168
1169    /**
1170     * Set while we are running a voice interaction.  This overrides
1171     * sleeping while it is active.
1172     */
1173    private IVoiceInteractionSession mRunningVoice;
1174
1175    /**
1176     * For some direct access we need to power manager.
1177     */
1178    PowerManagerInternal mLocalPowerManager;
1179
1180    /**
1181     * We want to hold a wake lock while running a voice interaction session, since
1182     * this may happen with the screen off and we need to keep the CPU running to
1183     * be able to continue to interact with the user.
1184     */
1185    PowerManager.WakeLock mVoiceWakeLock;
1186
1187    /**
1188     * State of external calls telling us if the device is awake or asleep.
1189     */
1190    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1191
1192    /**
1193     * A list of tokens that cause the top activity to be put to sleep.
1194     * They are used by components that may hide and block interaction with underlying
1195     * activities.
1196     */
1197    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1198
1199    static final int LOCK_SCREEN_HIDDEN = 0;
1200    static final int LOCK_SCREEN_LEAVING = 1;
1201    static final int LOCK_SCREEN_SHOWN = 2;
1202    /**
1203     * State of external call telling us if the lock screen is shown.
1204     */
1205    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1206
1207    /**
1208     * Set if we are shutting down the system, similar to sleeping.
1209     */
1210    boolean mShuttingDown = false;
1211
1212    /**
1213     * Current sequence id for oom_adj computation traversal.
1214     */
1215    int mAdjSeq = 0;
1216
1217    /**
1218     * Current sequence id for process LRU updating.
1219     */
1220    int mLruSeq = 0;
1221
1222    /**
1223     * Keep track of the non-cached/empty process we last found, to help
1224     * determine how to distribute cached/empty processes next time.
1225     */
1226    int mNumNonCachedProcs = 0;
1227
1228    /**
1229     * Keep track of the number of cached hidden procs, to balance oom adj
1230     * distribution between those and empty procs.
1231     */
1232    int mNumCachedHiddenProcs = 0;
1233
1234    /**
1235     * Keep track of the number of service processes we last found, to
1236     * determine on the next iteration which should be B services.
1237     */
1238    int mNumServiceProcs = 0;
1239    int mNewNumAServiceProcs = 0;
1240    int mNewNumServiceProcs = 0;
1241
1242    /**
1243     * Allow the current computed overall memory level of the system to go down?
1244     * This is set to false when we are killing processes for reasons other than
1245     * memory management, so that the now smaller process list will not be taken as
1246     * an indication that memory is tighter.
1247     */
1248    boolean mAllowLowerMemLevel = false;
1249
1250    /**
1251     * The last computed memory level, for holding when we are in a state that
1252     * processes are going away for other reasons.
1253     */
1254    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1255
1256    /**
1257     * The last total number of process we have, to determine if changes actually look
1258     * like a shrinking number of process due to lower RAM.
1259     */
1260    int mLastNumProcesses;
1261
1262    /**
1263     * The uptime of the last time we performed idle maintenance.
1264     */
1265    long mLastIdleTime = SystemClock.uptimeMillis();
1266
1267    /**
1268     * Total time spent with RAM that has been added in the past since the last idle time.
1269     */
1270    long mLowRamTimeSinceLastIdle = 0;
1271
1272    /**
1273     * If RAM is currently low, when that horrible situation started.
1274     */
1275    long mLowRamStartTime = 0;
1276
1277    /**
1278     * For reporting to battery stats the current top application.
1279     */
1280    private String mCurResumedPackage = null;
1281    private int mCurResumedUid = -1;
1282
1283    /**
1284     * For reporting to battery stats the apps currently running foreground
1285     * service.  The ProcessMap is package/uid tuples; each of these contain
1286     * an array of the currently foreground processes.
1287     */
1288    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1289            = new ProcessMap<ArrayList<ProcessRecord>>();
1290
1291    /**
1292     * This is set if we had to do a delayed dexopt of an app before launching
1293     * it, to increase the ANR timeouts in that case.
1294     */
1295    boolean mDidDexOpt;
1296
1297    /**
1298     * Set if the systemServer made a call to enterSafeMode.
1299     */
1300    boolean mSafeMode;
1301
1302    /**
1303     * If true, we are running under a test environment so will sample PSS from processes
1304     * much more rapidly to try to collect better data when the tests are rapidly
1305     * running through apps.
1306     */
1307    boolean mTestPssMode = false;
1308
1309    String mDebugApp = null;
1310    boolean mWaitForDebugger = false;
1311    boolean mDebugTransient = false;
1312    String mOrigDebugApp = null;
1313    boolean mOrigWaitForDebugger = false;
1314    boolean mAlwaysFinishActivities = false;
1315    boolean mLenientBackgroundCheck = false;
1316    boolean mForceResizableActivities;
1317    boolean mSupportsMultiWindow;
1318    boolean mSupportsFreeformWindowManagement;
1319    boolean mSupportsPictureInPicture;
1320    Rect mDefaultPinnedStackBounds;
1321    IActivityController mController = null;
1322    boolean mControllerIsAMonkey = false;
1323    String mProfileApp = null;
1324    ProcessRecord mProfileProc = null;
1325    String mProfileFile;
1326    ParcelFileDescriptor mProfileFd;
1327    int mSamplingInterval = 0;
1328    boolean mAutoStopProfiler = false;
1329    int mProfileType = 0;
1330    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1331    String mMemWatchDumpProcName;
1332    String mMemWatchDumpFile;
1333    int mMemWatchDumpPid;
1334    int mMemWatchDumpUid;
1335    String mTrackAllocationApp = null;
1336    String mNativeDebuggingApp = null;
1337
1338    final long[] mTmpLong = new long[2];
1339
1340    static final class ProcessChangeItem {
1341        static final int CHANGE_ACTIVITIES = 1<<0;
1342        static final int CHANGE_PROCESS_STATE = 1<<1;
1343        int changes;
1344        int uid;
1345        int pid;
1346        int processState;
1347        boolean foregroundActivities;
1348    }
1349
1350    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1351    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1352
1353    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1354    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1355
1356    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1357    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1358
1359    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1360    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1361
1362    /**
1363     * Runtime CPU use collection thread.  This object's lock is used to
1364     * perform synchronization with the thread (notifying it to run).
1365     */
1366    final Thread mProcessCpuThread;
1367
1368    /**
1369     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1370     * Must acquire this object's lock when accessing it.
1371     * NOTE: this lock will be held while doing long operations (trawling
1372     * through all processes in /proc), so it should never be acquired by
1373     * any critical paths such as when holding the main activity manager lock.
1374     */
1375    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1376            MONITOR_THREAD_CPU_USAGE);
1377    final AtomicLong mLastCpuTime = new AtomicLong(0);
1378    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1379
1380    long mLastWriteTime = 0;
1381
1382    /**
1383     * Used to retain an update lock when the foreground activity is in
1384     * immersive mode.
1385     */
1386    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1387
1388    /**
1389     * Set to true after the system has finished booting.
1390     */
1391    boolean mBooted = false;
1392
1393    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1394    int mProcessLimitOverride = -1;
1395
1396    WindowManagerService mWindowManager;
1397    final ActivityThread mSystemThread;
1398
1399    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1400        final ProcessRecord mApp;
1401        final int mPid;
1402        final IApplicationThread mAppThread;
1403
1404        AppDeathRecipient(ProcessRecord app, int pid,
1405                IApplicationThread thread) {
1406            if (DEBUG_ALL) Slog.v(
1407                TAG, "New death recipient " + this
1408                + " for thread " + thread.asBinder());
1409            mApp = app;
1410            mPid = pid;
1411            mAppThread = thread;
1412        }
1413
1414        @Override
1415        public void binderDied() {
1416            if (DEBUG_ALL) Slog.v(
1417                TAG, "Death received in " + this
1418                + " for thread " + mAppThread.asBinder());
1419            synchronized(ActivityManagerService.this) {
1420                appDiedLocked(mApp, mPid, mAppThread, true);
1421            }
1422        }
1423    }
1424
1425    static final int SHOW_ERROR_UI_MSG = 1;
1426    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1427    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1428    static final int UPDATE_CONFIGURATION_MSG = 4;
1429    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1430    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1431    static final int SERVICE_TIMEOUT_MSG = 12;
1432    static final int UPDATE_TIME_ZONE = 13;
1433    static final int SHOW_UID_ERROR_UI_MSG = 14;
1434    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1435    static final int PROC_START_TIMEOUT_MSG = 20;
1436    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1437    static final int KILL_APPLICATION_MSG = 22;
1438    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1439    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1440    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1441    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1442    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1443    static final int CLEAR_DNS_CACHE_MSG = 28;
1444    static final int UPDATE_HTTP_PROXY_MSG = 29;
1445    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1446    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1447    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1448    static final int REPORT_MEM_USAGE_MSG = 33;
1449    static final int REPORT_USER_SWITCH_MSG = 34;
1450    static final int CONTINUE_USER_SWITCH_MSG = 35;
1451    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1452    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1453    static final int PERSIST_URI_GRANTS_MSG = 38;
1454    static final int REQUEST_ALL_PSS_MSG = 39;
1455    static final int START_PROFILES_MSG = 40;
1456    static final int UPDATE_TIME = 41;
1457    static final int SYSTEM_USER_START_MSG = 42;
1458    static final int SYSTEM_USER_CURRENT_MSG = 43;
1459    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1460    static final int FINISH_BOOTING_MSG = 45;
1461    static final int START_USER_SWITCH_UI_MSG = 46;
1462    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1463    static final int DISMISS_DIALOG_UI_MSG = 48;
1464    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1465    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1466    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1467    static final int DELETE_DUMPHEAP_MSG = 52;
1468    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1469    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1470    static final int REPORT_TIME_TRACKER_MSG = 55;
1471    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1472    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1473    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1474    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1475    static final int IDLE_UIDS_MSG = 60;
1476    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1477    static final int LOG_STACK_STATE = 62;
1478    static final int VR_MODE_CHANGE_MSG = 63;
1479    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1480    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1481    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1482    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1483    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1484    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1485
1486    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1487    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1488    static final int FIRST_COMPAT_MODE_MSG = 300;
1489    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1490
1491    static ServiceThread sKillThread = null;
1492    static KillHandler sKillHandler = null;
1493
1494    CompatModeDialog mCompatModeDialog;
1495    long mLastMemUsageReportTime = 0;
1496
1497    /**
1498     * Flag whether the current user is a "monkey", i.e. whether
1499     * the UI is driven by a UI automation tool.
1500     */
1501    private boolean mUserIsMonkey;
1502
1503    /** Flag whether the device has a Recents UI */
1504    boolean mHasRecents;
1505
1506    /** The dimensions of the thumbnails in the Recents UI. */
1507    int mThumbnailWidth;
1508    int mThumbnailHeight;
1509    float mFullscreenThumbnailScale;
1510
1511    final ServiceThread mHandlerThread;
1512    final MainHandler mHandler;
1513    final UiHandler mUiHandler;
1514
1515    PackageManagerInternal mPackageManagerInt;
1516
1517    // VoiceInteraction session ID that changes for each new request except when
1518    // being called for multiwindow assist in a single session.
1519    private int mViSessionId = 1000;
1520
1521    final class KillHandler extends Handler {
1522        static final int KILL_PROCESS_GROUP_MSG = 4000;
1523
1524        public KillHandler(Looper looper) {
1525            super(looper, null, true);
1526        }
1527
1528        @Override
1529        public void handleMessage(Message msg) {
1530            switch (msg.what) {
1531                case KILL_PROCESS_GROUP_MSG:
1532                {
1533                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1534                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1535                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1536                }
1537                break;
1538
1539                default:
1540                    super.handleMessage(msg);
1541            }
1542        }
1543    }
1544
1545    final class UiHandler extends Handler {
1546        public UiHandler() {
1547            super(com.android.server.UiThread.get().getLooper(), null, true);
1548        }
1549
1550        @Override
1551        public void handleMessage(Message msg) {
1552            switch (msg.what) {
1553            case SHOW_ERROR_UI_MSG: {
1554                mAppErrors.handleShowAppErrorUi(msg);
1555                ensureBootCompleted();
1556            } break;
1557            case SHOW_NOT_RESPONDING_UI_MSG: {
1558                mAppErrors.handleShowAnrUi(msg);
1559                ensureBootCompleted();
1560            } break;
1561            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1562                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1563                synchronized (ActivityManagerService.this) {
1564                    ProcessRecord proc = (ProcessRecord) data.get("app");
1565                    if (proc == null) {
1566                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1567                        break;
1568                    }
1569                    if (proc.crashDialog != null) {
1570                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1571                        return;
1572                    }
1573                    AppErrorResult res = (AppErrorResult) data.get("result");
1574                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1575                        Dialog d = new StrictModeViolationDialog(mContext,
1576                                ActivityManagerService.this, res, proc);
1577                        d.show();
1578                        proc.crashDialog = d;
1579                    } else {
1580                        // The device is asleep, so just pretend that the user
1581                        // saw a crash dialog and hit "force quit".
1582                        res.set(0);
1583                    }
1584                }
1585                ensureBootCompleted();
1586            } break;
1587            case SHOW_FACTORY_ERROR_UI_MSG: {
1588                Dialog d = new FactoryErrorDialog(
1589                    mContext, msg.getData().getCharSequence("msg"));
1590                d.show();
1591                ensureBootCompleted();
1592            } break;
1593            case WAIT_FOR_DEBUGGER_UI_MSG: {
1594                synchronized (ActivityManagerService.this) {
1595                    ProcessRecord app = (ProcessRecord)msg.obj;
1596                    if (msg.arg1 != 0) {
1597                        if (!app.waitedForDebugger) {
1598                            Dialog d = new AppWaitingForDebuggerDialog(
1599                                    ActivityManagerService.this,
1600                                    mContext, app);
1601                            app.waitDialog = d;
1602                            app.waitedForDebugger = true;
1603                            d.show();
1604                        }
1605                    } else {
1606                        if (app.waitDialog != null) {
1607                            app.waitDialog.dismiss();
1608                            app.waitDialog = null;
1609                        }
1610                    }
1611                }
1612            } break;
1613            case SHOW_UID_ERROR_UI_MSG: {
1614                if (mShowDialogs) {
1615                    AlertDialog d = new BaseErrorDialog(mContext);
1616                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1617                    d.setCancelable(false);
1618                    d.setTitle(mContext.getText(R.string.android_system_label));
1619                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1620                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1621                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1622                    d.show();
1623                }
1624            } break;
1625            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1626                if (mShowDialogs) {
1627                    AlertDialog d = new BaseErrorDialog(mContext);
1628                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1629                    d.setCancelable(false);
1630                    d.setTitle(mContext.getText(R.string.android_system_label));
1631                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1632                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1633                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1634                    d.show();
1635                }
1636            } break;
1637            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1638                synchronized (ActivityManagerService.this) {
1639                    ActivityRecord ar = (ActivityRecord) msg.obj;
1640                    if (mCompatModeDialog != null) {
1641                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1642                                ar.info.applicationInfo.packageName)) {
1643                            return;
1644                        }
1645                        mCompatModeDialog.dismiss();
1646                        mCompatModeDialog = null;
1647                    }
1648                    if (ar != null && false) {
1649                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1650                                ar.packageName)) {
1651                            int mode = mCompatModePackages.computeCompatModeLocked(
1652                                    ar.info.applicationInfo);
1653                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1654                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1655                                mCompatModeDialog = new CompatModeDialog(
1656                                        ActivityManagerService.this, mContext,
1657                                        ar.info.applicationInfo);
1658                                mCompatModeDialog.show();
1659                            }
1660                        }
1661                    }
1662                }
1663                break;
1664            }
1665            case START_USER_SWITCH_UI_MSG: {
1666                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1667                break;
1668            }
1669            case DISMISS_DIALOG_UI_MSG: {
1670                final Dialog d = (Dialog) msg.obj;
1671                d.dismiss();
1672                break;
1673            }
1674            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1675                dispatchProcessesChanged();
1676                break;
1677            }
1678            case DISPATCH_PROCESS_DIED_UI_MSG: {
1679                final int pid = msg.arg1;
1680                final int uid = msg.arg2;
1681                dispatchProcessDied(pid, uid);
1682                break;
1683            }
1684            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1685                dispatchUidsChanged();
1686            } break;
1687            }
1688        }
1689    }
1690
1691    final class MainHandler extends Handler {
1692        public MainHandler(Looper looper) {
1693            super(looper, null, true);
1694        }
1695
1696        @Override
1697        public void handleMessage(Message msg) {
1698            switch (msg.what) {
1699            case UPDATE_CONFIGURATION_MSG: {
1700                final ContentResolver resolver = mContext.getContentResolver();
1701                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1702                        msg.arg1);
1703            } break;
1704            case GC_BACKGROUND_PROCESSES_MSG: {
1705                synchronized (ActivityManagerService.this) {
1706                    performAppGcsIfAppropriateLocked();
1707                }
1708            } break;
1709            case SERVICE_TIMEOUT_MSG: {
1710                if (mDidDexOpt) {
1711                    mDidDexOpt = false;
1712                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1713                    nmsg.obj = msg.obj;
1714                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1715                    return;
1716                }
1717                mServices.serviceTimeout((ProcessRecord)msg.obj);
1718            } break;
1719            case UPDATE_TIME_ZONE: {
1720                synchronized (ActivityManagerService.this) {
1721                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1722                        ProcessRecord r = mLruProcesses.get(i);
1723                        if (r.thread != null) {
1724                            try {
1725                                r.thread.updateTimeZone();
1726                            } catch (RemoteException ex) {
1727                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1728                            }
1729                        }
1730                    }
1731                }
1732            } break;
1733            case CLEAR_DNS_CACHE_MSG: {
1734                synchronized (ActivityManagerService.this) {
1735                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1736                        ProcessRecord r = mLruProcesses.get(i);
1737                        if (r.thread != null) {
1738                            try {
1739                                r.thread.clearDnsCache();
1740                            } catch (RemoteException ex) {
1741                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1742                            }
1743                        }
1744                    }
1745                }
1746            } break;
1747            case UPDATE_HTTP_PROXY_MSG: {
1748                ProxyInfo proxy = (ProxyInfo)msg.obj;
1749                String host = "";
1750                String port = "";
1751                String exclList = "";
1752                Uri pacFileUrl = Uri.EMPTY;
1753                if (proxy != null) {
1754                    host = proxy.getHost();
1755                    port = Integer.toString(proxy.getPort());
1756                    exclList = proxy.getExclusionListAsString();
1757                    pacFileUrl = proxy.getPacFileUrl();
1758                }
1759                synchronized (ActivityManagerService.this) {
1760                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1761                        ProcessRecord r = mLruProcesses.get(i);
1762                        if (r.thread != null) {
1763                            try {
1764                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1765                            } catch (RemoteException ex) {
1766                                Slog.w(TAG, "Failed to update http proxy for: " +
1767                                        r.info.processName);
1768                            }
1769                        }
1770                    }
1771                }
1772            } break;
1773            case PROC_START_TIMEOUT_MSG: {
1774                if (mDidDexOpt) {
1775                    mDidDexOpt = false;
1776                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1777                    nmsg.obj = msg.obj;
1778                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1779                    return;
1780                }
1781                ProcessRecord app = (ProcessRecord)msg.obj;
1782                synchronized (ActivityManagerService.this) {
1783                    processStartTimedOutLocked(app);
1784                }
1785            } break;
1786            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1787                ProcessRecord app = (ProcessRecord)msg.obj;
1788                synchronized (ActivityManagerService.this) {
1789                    processContentProviderPublishTimedOutLocked(app);
1790                }
1791            } break;
1792            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1793                synchronized (ActivityManagerService.this) {
1794                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1795                }
1796            } break;
1797            case KILL_APPLICATION_MSG: {
1798                synchronized (ActivityManagerService.this) {
1799                    int appid = msg.arg1;
1800                    boolean restart = (msg.arg2 == 1);
1801                    Bundle bundle = (Bundle)msg.obj;
1802                    String pkg = bundle.getString("pkg");
1803                    String reason = bundle.getString("reason");
1804                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1805                            false, UserHandle.USER_ALL, reason);
1806                }
1807            } break;
1808            case FINALIZE_PENDING_INTENT_MSG: {
1809                ((PendingIntentRecord)msg.obj).completeFinalize();
1810            } break;
1811            case POST_HEAVY_NOTIFICATION_MSG: {
1812                INotificationManager inm = NotificationManager.getService();
1813                if (inm == null) {
1814                    return;
1815                }
1816
1817                ActivityRecord root = (ActivityRecord)msg.obj;
1818                ProcessRecord process = root.app;
1819                if (process == null) {
1820                    return;
1821                }
1822
1823                try {
1824                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1825                    String text = mContext.getString(R.string.heavy_weight_notification,
1826                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1827                    Notification notification = new Notification.Builder(context)
1828                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1829                            .setWhen(0)
1830                            .setOngoing(true)
1831                            .setTicker(text)
1832                            .setColor(mContext.getColor(
1833                                    com.android.internal.R.color.system_notification_accent_color))
1834                            .setContentTitle(text)
1835                            .setContentText(
1836                                    mContext.getText(R.string.heavy_weight_notification_detail))
1837                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1838                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1839                                    new UserHandle(root.userId)))
1840                            .build();
1841                    try {
1842                        int[] outId = new int[1];
1843                        inm.enqueueNotificationWithTag("android", "android", null,
1844                                R.string.heavy_weight_notification,
1845                                notification, outId, root.userId);
1846                    } catch (RuntimeException e) {
1847                        Slog.w(ActivityManagerService.TAG,
1848                                "Error showing notification for heavy-weight app", e);
1849                    } catch (RemoteException e) {
1850                    }
1851                } catch (NameNotFoundException e) {
1852                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1853                }
1854            } break;
1855            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1856                INotificationManager inm = NotificationManager.getService();
1857                if (inm == null) {
1858                    return;
1859                }
1860                try {
1861                    inm.cancelNotificationWithTag("android", null,
1862                            R.string.heavy_weight_notification,  msg.arg1);
1863                } catch (RuntimeException e) {
1864                    Slog.w(ActivityManagerService.TAG,
1865                            "Error canceling notification for service", e);
1866                } catch (RemoteException e) {
1867                }
1868            } break;
1869            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1870                synchronized (ActivityManagerService.this) {
1871                    checkExcessivePowerUsageLocked(true);
1872                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1873                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1874                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1875                }
1876            } break;
1877            case REPORT_MEM_USAGE_MSG: {
1878                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1879                Thread thread = new Thread() {
1880                    @Override public void run() {
1881                        reportMemUsage(memInfos);
1882                    }
1883                };
1884                thread.start();
1885                break;
1886            }
1887            case REPORT_USER_SWITCH_MSG: {
1888                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1889                break;
1890            }
1891            case CONTINUE_USER_SWITCH_MSG: {
1892                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1893                break;
1894            }
1895            case USER_SWITCH_TIMEOUT_MSG: {
1896                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1897                break;
1898            }
1899            case IMMERSIVE_MODE_LOCK_MSG: {
1900                final boolean nextState = (msg.arg1 != 0);
1901                if (mUpdateLock.isHeld() != nextState) {
1902                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1903                            "Applying new update lock state '" + nextState
1904                            + "' for " + (ActivityRecord)msg.obj);
1905                    if (nextState) {
1906                        mUpdateLock.acquire();
1907                    } else {
1908                        mUpdateLock.release();
1909                    }
1910                }
1911                break;
1912            }
1913            case PERSIST_URI_GRANTS_MSG: {
1914                writeGrantedUriPermissions();
1915                break;
1916            }
1917            case REQUEST_ALL_PSS_MSG: {
1918                synchronized (ActivityManagerService.this) {
1919                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1920                }
1921                break;
1922            }
1923            case START_PROFILES_MSG: {
1924                synchronized (ActivityManagerService.this) {
1925                    mUserController.startProfilesLocked();
1926                }
1927                break;
1928            }
1929            case UPDATE_TIME: {
1930                synchronized (ActivityManagerService.this) {
1931                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1932                        ProcessRecord r = mLruProcesses.get(i);
1933                        if (r.thread != null) {
1934                            try {
1935                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1936                            } catch (RemoteException ex) {
1937                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1938                            }
1939                        }
1940                    }
1941                }
1942                break;
1943            }
1944            case SYSTEM_USER_START_MSG: {
1945                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1946                        Integer.toString(msg.arg1), msg.arg1);
1947                mSystemServiceManager.startUser(msg.arg1);
1948                break;
1949            }
1950            case SYSTEM_USER_UNLOCK_MSG: {
1951                final int userId = msg.arg1;
1952                mSystemServiceManager.unlockUser(userId);
1953                synchronized (ActivityManagerService.this) {
1954                    mRecentTasks.loadUserRecentsLocked(userId);
1955                }
1956                if (userId == UserHandle.USER_SYSTEM) {
1957                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1958                }
1959                installEncryptionUnawareProviders(userId);
1960                mUserController.finishUserUnlocked((UserState) msg.obj);
1961                break;
1962            }
1963            case SYSTEM_USER_CURRENT_MSG: {
1964                mBatteryStatsService.noteEvent(
1965                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1966                        Integer.toString(msg.arg2), msg.arg2);
1967                mBatteryStatsService.noteEvent(
1968                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1969                        Integer.toString(msg.arg1), msg.arg1);
1970                mSystemServiceManager.switchUser(msg.arg1);
1971                break;
1972            }
1973            case ENTER_ANIMATION_COMPLETE_MSG: {
1974                synchronized (ActivityManagerService.this) {
1975                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1976                    if (r != null && r.app != null && r.app.thread != null) {
1977                        try {
1978                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1979                        } catch (RemoteException e) {
1980                        }
1981                    }
1982                }
1983                break;
1984            }
1985            case FINISH_BOOTING_MSG: {
1986                if (msg.arg1 != 0) {
1987                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1988                    finishBooting();
1989                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1990                }
1991                if (msg.arg2 != 0) {
1992                    enableScreenAfterBoot();
1993                }
1994                break;
1995            }
1996            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1997                try {
1998                    Locale l = (Locale) msg.obj;
1999                    IBinder service = ServiceManager.getService("mount");
2000                    IMountService mountService = IMountService.Stub.asInterface(service);
2001                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2002                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2003                } catch (RemoteException e) {
2004                    Log.e(TAG, "Error storing locale for decryption UI", e);
2005                }
2006                break;
2007            }
2008            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2009                synchronized (ActivityManagerService.this) {
2010                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2011                        try {
2012                            // Make a one-way callback to the listener
2013                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2014                        } catch (RemoteException e){
2015                            // Handled by the RemoteCallbackList
2016                        }
2017                    }
2018                    mTaskStackListeners.finishBroadcast();
2019                }
2020                break;
2021            }
2022            case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2023                synchronized (ActivityManagerService.this) {
2024                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2025                        try {
2026                            // Make a one-way callback to the listener
2027                            mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2028                        } catch (RemoteException e){
2029                            // Handled by the RemoteCallbackList
2030                        }
2031                    }
2032                    mTaskStackListeners.finishBroadcast();
2033                }
2034                break;
2035            }
2036            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2037                synchronized (ActivityManagerService.this) {
2038                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2039                        try {
2040                            // Make a one-way callback to the listener
2041                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2042                        } catch (RemoteException e){
2043                            // Handled by the RemoteCallbackList
2044                        }
2045                    }
2046                    mTaskStackListeners.finishBroadcast();
2047                }
2048                break;
2049            }
2050            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2051                synchronized (ActivityManagerService.this) {
2052                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2053                        try {
2054                            // Make a one-way callback to the listener
2055                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2056                        } catch (RemoteException e){
2057                            // Handled by the RemoteCallbackList
2058                        }
2059                    }
2060                    mTaskStackListeners.finishBroadcast();
2061                }
2062                break;
2063            }
2064            case NOTIFY_FORCED_RESIZABLE_MSG: {
2065                synchronized (ActivityManagerService.this) {
2066                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2067                        try {
2068                            // Make a one-way callback to the listener
2069                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2070                                    (String) msg.obj, msg.arg1);
2071                        } catch (RemoteException e){
2072                            // Handled by the RemoteCallbackList
2073                        }
2074                    }
2075                    mTaskStackListeners.finishBroadcast();
2076                }
2077                break;
2078            }
2079                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2080                    synchronized (ActivityManagerService.this) {
2081                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2082                            try {
2083                                // Make a one-way callback to the listener
2084                                mTaskStackListeners.getBroadcastItem(i)
2085                                        .onActivityDismissingDockedStack();
2086                            } catch (RemoteException e){
2087                                // Handled by the RemoteCallbackList
2088                            }
2089                        }
2090                        mTaskStackListeners.finishBroadcast();
2091                    }
2092                    break;
2093                }
2094            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2095                final int uid = msg.arg1;
2096                final byte[] firstPacket = (byte[]) msg.obj;
2097
2098                synchronized (mPidsSelfLocked) {
2099                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2100                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2101                        if (p.uid == uid) {
2102                            try {
2103                                p.thread.notifyCleartextNetwork(firstPacket);
2104                            } catch (RemoteException ignored) {
2105                            }
2106                        }
2107                    }
2108                }
2109                break;
2110            }
2111            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2112                final String procName;
2113                final int uid;
2114                final long memLimit;
2115                final String reportPackage;
2116                synchronized (ActivityManagerService.this) {
2117                    procName = mMemWatchDumpProcName;
2118                    uid = mMemWatchDumpUid;
2119                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2120                    if (val == null) {
2121                        val = mMemWatchProcesses.get(procName, 0);
2122                    }
2123                    if (val != null) {
2124                        memLimit = val.first;
2125                        reportPackage = val.second;
2126                    } else {
2127                        memLimit = 0;
2128                        reportPackage = null;
2129                    }
2130                }
2131                if (procName == null) {
2132                    return;
2133                }
2134
2135                if (DEBUG_PSS) Slog.d(TAG_PSS,
2136                        "Showing dump heap notification from " + procName + "/" + uid);
2137
2138                INotificationManager inm = NotificationManager.getService();
2139                if (inm == null) {
2140                    return;
2141                }
2142
2143                String text = mContext.getString(R.string.dump_heap_notification, procName);
2144
2145
2146                Intent deleteIntent = new Intent();
2147                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2148                Intent intent = new Intent();
2149                intent.setClassName("android", DumpHeapActivity.class.getName());
2150                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2151                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2152                if (reportPackage != null) {
2153                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2154                }
2155                int userId = UserHandle.getUserId(uid);
2156                Notification notification = new Notification.Builder(mContext)
2157                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2158                        .setWhen(0)
2159                        .setOngoing(true)
2160                        .setAutoCancel(true)
2161                        .setTicker(text)
2162                        .setColor(mContext.getColor(
2163                                com.android.internal.R.color.system_notification_accent_color))
2164                        .setContentTitle(text)
2165                        .setContentText(
2166                                mContext.getText(R.string.dump_heap_notification_detail))
2167                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2168                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2169                                new UserHandle(userId)))
2170                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2171                                deleteIntent, 0, UserHandle.SYSTEM))
2172                        .build();
2173
2174                try {
2175                    int[] outId = new int[1];
2176                    inm.enqueueNotificationWithTag("android", "android", null,
2177                            R.string.dump_heap_notification,
2178                            notification, outId, userId);
2179                } catch (RuntimeException e) {
2180                    Slog.w(ActivityManagerService.TAG,
2181                            "Error showing notification for dump heap", e);
2182                } catch (RemoteException e) {
2183                }
2184            } break;
2185            case DELETE_DUMPHEAP_MSG: {
2186                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2187                        DumpHeapActivity.JAVA_URI,
2188                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2189                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2190                        UserHandle.myUserId());
2191                synchronized (ActivityManagerService.this) {
2192                    mMemWatchDumpFile = null;
2193                    mMemWatchDumpProcName = null;
2194                    mMemWatchDumpPid = -1;
2195                    mMemWatchDumpUid = -1;
2196                }
2197            } break;
2198            case FOREGROUND_PROFILE_CHANGED_MSG: {
2199                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2200            } break;
2201            case REPORT_TIME_TRACKER_MSG: {
2202                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2203                tracker.deliverResult(mContext);
2204            } break;
2205            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2206                mUserController.dispatchUserSwitchComplete(msg.arg1);
2207            } break;
2208            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2209                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2210                try {
2211                    connection.shutdown();
2212                } catch (RemoteException e) {
2213                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2214                }
2215                // Only a UiAutomation can set this flag and now that
2216                // it is finished we make sure it is reset to its default.
2217                mUserIsMonkey = false;
2218            } break;
2219            case APP_BOOST_DEACTIVATE_MSG: {
2220                synchronized(ActivityManagerService.this) {
2221                    if (mIsBoosted) {
2222                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2223                            nativeMigrateFromBoost();
2224                            mIsBoosted = false;
2225                            mBoostStartTime = 0;
2226                        } else {
2227                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2228                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2229                        }
2230                    }
2231                }
2232            } break;
2233            case IDLE_UIDS_MSG: {
2234                idleUids();
2235            } break;
2236            case LOG_STACK_STATE: {
2237                synchronized (ActivityManagerService.this) {
2238                    mStackSupervisor.logStackState();
2239                }
2240            } break;
2241            case VR_MODE_CHANGE_MSG: {
2242                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2243                final ActivityRecord r = (ActivityRecord) msg.obj;
2244                boolean vrMode;
2245                ComponentName requestedPackage;
2246                ComponentName callingPackage;
2247                int userId;
2248                synchronized (ActivityManagerService.this) {
2249                    vrMode = r.requestedVrComponent != null;
2250                    requestedPackage = r.requestedVrComponent;
2251                    userId = r.userId;
2252                    callingPackage = r.info.getComponentName();
2253                    if (mInVrMode != vrMode) {
2254                        mInVrMode = vrMode;
2255                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2256                    }
2257                }
2258                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2259            } break;
2260            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2261                final ActivityRecord r = (ActivityRecord) msg.obj;
2262                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2263                if (needsVrMode) {
2264                    VrManagerInternal vrService =
2265                            LocalServices.getService(VrManagerInternal.class);
2266                    boolean enable = msg.arg1 == 1;
2267                    vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2268                            r.info.getComponentName());
2269                }
2270            } break;
2271            }
2272        }
2273    };
2274
2275    static final int COLLECT_PSS_BG_MSG = 1;
2276
2277    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2278        @Override
2279        public void handleMessage(Message msg) {
2280            switch (msg.what) {
2281            case COLLECT_PSS_BG_MSG: {
2282                long start = SystemClock.uptimeMillis();
2283                MemInfoReader memInfo = null;
2284                synchronized (ActivityManagerService.this) {
2285                    if (mFullPssPending) {
2286                        mFullPssPending = false;
2287                        memInfo = new MemInfoReader();
2288                    }
2289                }
2290                if (memInfo != null) {
2291                    updateCpuStatsNow();
2292                    long nativeTotalPss = 0;
2293                    synchronized (mProcessCpuTracker) {
2294                        final int N = mProcessCpuTracker.countStats();
2295                        for (int j=0; j<N; j++) {
2296                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2297                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2298                                // This is definitely an application process; skip it.
2299                                continue;
2300                            }
2301                            synchronized (mPidsSelfLocked) {
2302                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2303                                    // This is one of our own processes; skip it.
2304                                    continue;
2305                                }
2306                            }
2307                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2308                        }
2309                    }
2310                    memInfo.readMemInfo();
2311                    synchronized (ActivityManagerService.this) {
2312                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2313                                + (SystemClock.uptimeMillis()-start) + "ms");
2314                        final long cachedKb = memInfo.getCachedSizeKb();
2315                        final long freeKb = memInfo.getFreeSizeKb();
2316                        final long zramKb = memInfo.getZramTotalSizeKb();
2317                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2318                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2319                                kernelKb*1024, nativeTotalPss*1024);
2320                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2321                                nativeTotalPss);
2322                    }
2323                }
2324
2325                int num = 0;
2326                long[] tmp = new long[2];
2327                do {
2328                    ProcessRecord proc;
2329                    int procState;
2330                    int pid;
2331                    long lastPssTime;
2332                    synchronized (ActivityManagerService.this) {
2333                        if (mPendingPssProcesses.size() <= 0) {
2334                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2335                                    "Collected PSS of " + num + " processes in "
2336                                    + (SystemClock.uptimeMillis() - start) + "ms");
2337                            mPendingPssProcesses.clear();
2338                            return;
2339                        }
2340                        proc = mPendingPssProcesses.remove(0);
2341                        procState = proc.pssProcState;
2342                        lastPssTime = proc.lastPssTime;
2343                        if (proc.thread != null && procState == proc.setProcState
2344                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2345                                        < SystemClock.uptimeMillis()) {
2346                            pid = proc.pid;
2347                        } else {
2348                            proc = null;
2349                            pid = 0;
2350                        }
2351                    }
2352                    if (proc != null) {
2353                        long pss = Debug.getPss(pid, tmp, null);
2354                        synchronized (ActivityManagerService.this) {
2355                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2356                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2357                                num++;
2358                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2359                                        SystemClock.uptimeMillis());
2360                            }
2361                        }
2362                    }
2363                } while (true);
2364            }
2365            }
2366        }
2367    };
2368
2369    public void setSystemProcess() {
2370        try {
2371            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2372            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2373            ServiceManager.addService("meminfo", new MemBinder(this));
2374            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2375            ServiceManager.addService("dbinfo", new DbBinder(this));
2376            if (MONITOR_CPU_USAGE) {
2377                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2378            }
2379            ServiceManager.addService("permission", new PermissionController(this));
2380            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2381
2382            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2383                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2384            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2385
2386            synchronized (this) {
2387                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2388                app.persistent = true;
2389                app.pid = MY_PID;
2390                app.maxAdj = ProcessList.SYSTEM_ADJ;
2391                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2392                synchronized (mPidsSelfLocked) {
2393                    mPidsSelfLocked.put(app.pid, app);
2394                }
2395                updateLruProcessLocked(app, false, null);
2396                updateOomAdjLocked();
2397            }
2398        } catch (PackageManager.NameNotFoundException e) {
2399            throw new RuntimeException(
2400                    "Unable to find android system package", e);
2401        }
2402    }
2403
2404    public void setWindowManager(WindowManagerService wm) {
2405        mWindowManager = wm;
2406        mStackSupervisor.setWindowManager(wm);
2407        mActivityStarter.setWindowManager(wm);
2408    }
2409
2410    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2411        mUsageStatsService = usageStatsManager;
2412    }
2413
2414    public void startObservingNativeCrashes() {
2415        final NativeCrashListener ncl = new NativeCrashListener(this);
2416        ncl.start();
2417    }
2418
2419    public IAppOpsService getAppOpsService() {
2420        return mAppOpsService;
2421    }
2422
2423    static class MemBinder extends Binder {
2424        ActivityManagerService mActivityManagerService;
2425        MemBinder(ActivityManagerService activityManagerService) {
2426            mActivityManagerService = activityManagerService;
2427        }
2428
2429        @Override
2430        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2431            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2432                    != PackageManager.PERMISSION_GRANTED) {
2433                pw.println("Permission Denial: can't dump meminfo from from pid="
2434                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2435                        + " without permission " + android.Manifest.permission.DUMP);
2436                return;
2437            }
2438
2439            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2440        }
2441    }
2442
2443    static class GraphicsBinder extends Binder {
2444        ActivityManagerService mActivityManagerService;
2445        GraphicsBinder(ActivityManagerService activityManagerService) {
2446            mActivityManagerService = activityManagerService;
2447        }
2448
2449        @Override
2450        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2451            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2452                    != PackageManager.PERMISSION_GRANTED) {
2453                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2454                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2455                        + " without permission " + android.Manifest.permission.DUMP);
2456                return;
2457            }
2458
2459            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2460        }
2461    }
2462
2463    static class DbBinder extends Binder {
2464        ActivityManagerService mActivityManagerService;
2465        DbBinder(ActivityManagerService activityManagerService) {
2466            mActivityManagerService = activityManagerService;
2467        }
2468
2469        @Override
2470        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2471            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2472                    != PackageManager.PERMISSION_GRANTED) {
2473                pw.println("Permission Denial: can't dump dbinfo from from pid="
2474                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2475                        + " without permission " + android.Manifest.permission.DUMP);
2476                return;
2477            }
2478
2479            mActivityManagerService.dumpDbInfo(fd, pw, args);
2480        }
2481    }
2482
2483    static class CpuBinder extends Binder {
2484        ActivityManagerService mActivityManagerService;
2485        CpuBinder(ActivityManagerService activityManagerService) {
2486            mActivityManagerService = activityManagerService;
2487        }
2488
2489        @Override
2490        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2491            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2492                    != PackageManager.PERMISSION_GRANTED) {
2493                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2494                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2495                        + " without permission " + android.Manifest.permission.DUMP);
2496                return;
2497            }
2498
2499            synchronized (mActivityManagerService.mProcessCpuTracker) {
2500                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2501                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2502                        SystemClock.uptimeMillis()));
2503            }
2504        }
2505    }
2506
2507    public static final class Lifecycle extends SystemService {
2508        private final ActivityManagerService mService;
2509
2510        public Lifecycle(Context context) {
2511            super(context);
2512            mService = new ActivityManagerService(context);
2513        }
2514
2515        @Override
2516        public void onStart() {
2517            mService.start();
2518        }
2519
2520        public ActivityManagerService getService() {
2521            return mService;
2522        }
2523    }
2524
2525    // Note: This method is invoked on the main thread but may need to attach various
2526    // handlers to other threads.  So take care to be explicit about the looper.
2527    public ActivityManagerService(Context systemContext) {
2528        mContext = systemContext;
2529        mFactoryTest = FactoryTest.getMode();
2530        mSystemThread = ActivityThread.currentActivityThread();
2531
2532        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2533
2534        mHandlerThread = new ServiceThread(TAG,
2535                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2536        mHandlerThread.start();
2537        mHandler = new MainHandler(mHandlerThread.getLooper());
2538        mUiHandler = new UiHandler();
2539
2540        /* static; one-time init here */
2541        if (sKillHandler == null) {
2542            sKillThread = new ServiceThread(TAG + ":kill",
2543                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2544            sKillThread.start();
2545            sKillHandler = new KillHandler(sKillThread.getLooper());
2546        }
2547
2548        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2549                "foreground", BROADCAST_FG_TIMEOUT, false);
2550        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2551                "background", BROADCAST_BG_TIMEOUT, true);
2552        mBroadcastQueues[0] = mFgBroadcastQueue;
2553        mBroadcastQueues[1] = mBgBroadcastQueue;
2554
2555        mServices = new ActiveServices(this);
2556        mProviderMap = new ProviderMap(this);
2557        mAppErrors = new AppErrors(mContext, this);
2558
2559        // TODO: Move creation of battery stats service outside of activity manager service.
2560        File dataDir = Environment.getDataDirectory();
2561        File systemDir = new File(dataDir, "system");
2562        systemDir.mkdirs();
2563        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2564        mBatteryStatsService.getActiveStatistics().readLocked();
2565        mBatteryStatsService.scheduleWriteToDisk();
2566        mOnBattery = DEBUG_POWER ? true
2567                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2568        mBatteryStatsService.getActiveStatistics().setCallback(this);
2569
2570        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2571
2572        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2573        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2574                new IAppOpsCallback.Stub() {
2575                    @Override public void opChanged(int op, int uid, String packageName) {
2576                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2577                            if (mAppOpsService.checkOperation(op, uid, packageName)
2578                                    != AppOpsManager.MODE_ALLOWED) {
2579                                runInBackgroundDisabled(uid);
2580                            }
2581                        }
2582                    }
2583                });
2584
2585        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2586
2587        mUserController = new UserController(this);
2588
2589        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2590            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2591
2592        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2593
2594        mConfiguration.setToDefaults();
2595        mConfiguration.setLocales(LocaleList.getDefault());
2596
2597        mConfigurationSeq = mConfiguration.seq = 1;
2598        mProcessCpuTracker.init();
2599
2600        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2601        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2602        mStackSupervisor = new ActivityStackSupervisor(this);
2603        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2604        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2605
2606        mProcessCpuThread = new Thread("CpuTracker") {
2607            @Override
2608            public void run() {
2609                while (true) {
2610                    try {
2611                        try {
2612                            synchronized(this) {
2613                                final long now = SystemClock.uptimeMillis();
2614                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2615                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2616                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2617                                //        + ", write delay=" + nextWriteDelay);
2618                                if (nextWriteDelay < nextCpuDelay) {
2619                                    nextCpuDelay = nextWriteDelay;
2620                                }
2621                                if (nextCpuDelay > 0) {
2622                                    mProcessCpuMutexFree.set(true);
2623                                    this.wait(nextCpuDelay);
2624                                }
2625                            }
2626                        } catch (InterruptedException e) {
2627                        }
2628                        updateCpuStatsNow();
2629                    } catch (Exception e) {
2630                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2631                    }
2632                }
2633            }
2634        };
2635
2636        Watchdog.getInstance().addMonitor(this);
2637        Watchdog.getInstance().addThread(mHandler);
2638    }
2639
2640    public void setSystemServiceManager(SystemServiceManager mgr) {
2641        mSystemServiceManager = mgr;
2642    }
2643
2644    public void setInstaller(Installer installer) {
2645        mInstaller = installer;
2646    }
2647
2648    private void start() {
2649        Process.removeAllProcessGroups();
2650        mProcessCpuThread.start();
2651
2652        mBatteryStatsService.publish(mContext);
2653        mAppOpsService.publish(mContext);
2654        Slog.d("AppOps", "AppOpsService published");
2655        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2656    }
2657
2658    void onUserStoppedLocked(int userId) {
2659        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2660    }
2661
2662    public void initPowerManagement() {
2663        mStackSupervisor.initPowerManagement();
2664        mBatteryStatsService.initPowerManagement();
2665        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2666        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2667        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2668        mVoiceWakeLock.setReferenceCounted(false);
2669    }
2670
2671    @Override
2672    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2673            throws RemoteException {
2674        if (code == SYSPROPS_TRANSACTION) {
2675            // We need to tell all apps about the system property change.
2676            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2677            synchronized(this) {
2678                final int NP = mProcessNames.getMap().size();
2679                for (int ip=0; ip<NP; ip++) {
2680                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2681                    final int NA = apps.size();
2682                    for (int ia=0; ia<NA; ia++) {
2683                        ProcessRecord app = apps.valueAt(ia);
2684                        if (app.thread != null) {
2685                            procs.add(app.thread.asBinder());
2686                        }
2687                    }
2688                }
2689            }
2690
2691            int N = procs.size();
2692            for (int i=0; i<N; i++) {
2693                Parcel data2 = Parcel.obtain();
2694                try {
2695                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2696                } catch (RemoteException e) {
2697                }
2698                data2.recycle();
2699            }
2700        }
2701        try {
2702            return super.onTransact(code, data, reply, flags);
2703        } catch (RuntimeException e) {
2704            // The activity manager only throws security exceptions, so let's
2705            // log all others.
2706            if (!(e instanceof SecurityException)) {
2707                Slog.wtf(TAG, "Activity Manager Crash", e);
2708            }
2709            throw e;
2710        }
2711    }
2712
2713    void updateCpuStats() {
2714        final long now = SystemClock.uptimeMillis();
2715        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2716            return;
2717        }
2718        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2719            synchronized (mProcessCpuThread) {
2720                mProcessCpuThread.notify();
2721            }
2722        }
2723    }
2724
2725    void updateCpuStatsNow() {
2726        synchronized (mProcessCpuTracker) {
2727            mProcessCpuMutexFree.set(false);
2728            final long now = SystemClock.uptimeMillis();
2729            boolean haveNewCpuStats = false;
2730
2731            if (MONITOR_CPU_USAGE &&
2732                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2733                mLastCpuTime.set(now);
2734                mProcessCpuTracker.update();
2735                if (mProcessCpuTracker.hasGoodLastStats()) {
2736                    haveNewCpuStats = true;
2737                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2738                    //Slog.i(TAG, "Total CPU usage: "
2739                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2740
2741                    // Slog the cpu usage if the property is set.
2742                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2743                        int user = mProcessCpuTracker.getLastUserTime();
2744                        int system = mProcessCpuTracker.getLastSystemTime();
2745                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2746                        int irq = mProcessCpuTracker.getLastIrqTime();
2747                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2748                        int idle = mProcessCpuTracker.getLastIdleTime();
2749
2750                        int total = user + system + iowait + irq + softIrq + idle;
2751                        if (total == 0) total = 1;
2752
2753                        EventLog.writeEvent(EventLogTags.CPU,
2754                                ((user+system+iowait+irq+softIrq) * 100) / total,
2755                                (user * 100) / total,
2756                                (system * 100) / total,
2757                                (iowait * 100) / total,
2758                                (irq * 100) / total,
2759                                (softIrq * 100) / total);
2760                    }
2761                }
2762            }
2763
2764            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2765            synchronized(bstats) {
2766                synchronized(mPidsSelfLocked) {
2767                    if (haveNewCpuStats) {
2768                        if (bstats.startAddingCpuLocked()) {
2769                            int totalUTime = 0;
2770                            int totalSTime = 0;
2771                            final int N = mProcessCpuTracker.countStats();
2772                            for (int i=0; i<N; i++) {
2773                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2774                                if (!st.working) {
2775                                    continue;
2776                                }
2777                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2778                                totalUTime += st.rel_utime;
2779                                totalSTime += st.rel_stime;
2780                                if (pr != null) {
2781                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2782                                    if (ps == null || !ps.isActive()) {
2783                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2784                                                pr.info.uid, pr.processName);
2785                                    }
2786                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2787                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2788                                } else {
2789                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2790                                    if (ps == null || !ps.isActive()) {
2791                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2792                                                bstats.mapUid(st.uid), st.name);
2793                                    }
2794                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2795                                }
2796                            }
2797                            final int userTime = mProcessCpuTracker.getLastUserTime();
2798                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2799                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2800                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2801                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2802                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2803                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2804                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2805                        }
2806                    }
2807                }
2808
2809                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2810                    mLastWriteTime = now;
2811                    mBatteryStatsService.scheduleWriteToDisk();
2812                }
2813            }
2814        }
2815    }
2816
2817    @Override
2818    public void batteryNeedsCpuUpdate() {
2819        updateCpuStatsNow();
2820    }
2821
2822    @Override
2823    public void batteryPowerChanged(boolean onBattery) {
2824        // When plugging in, update the CPU stats first before changing
2825        // the plug state.
2826        updateCpuStatsNow();
2827        synchronized (this) {
2828            synchronized(mPidsSelfLocked) {
2829                mOnBattery = DEBUG_POWER ? true : onBattery;
2830            }
2831        }
2832    }
2833
2834    @Override
2835    public void batterySendBroadcast(Intent intent) {
2836        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2837                AppOpsManager.OP_NONE, null, false, false,
2838                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2839    }
2840
2841    /**
2842     * Initialize the application bind args. These are passed to each
2843     * process when the bindApplication() IPC is sent to the process. They're
2844     * lazily setup to make sure the services are running when they're asked for.
2845     */
2846    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2847        if (mAppBindArgs == null) {
2848            mAppBindArgs = new HashMap<>();
2849
2850            // Isolated processes won't get this optimization, so that we don't
2851            // violate the rules about which services they have access to.
2852            if (!isolated) {
2853                // Setup the application init args
2854                mAppBindArgs.put("package", ServiceManager.getService("package"));
2855                mAppBindArgs.put("window", ServiceManager.getService("window"));
2856                mAppBindArgs.put(Context.ALARM_SERVICE,
2857                        ServiceManager.getService(Context.ALARM_SERVICE));
2858            }
2859        }
2860        return mAppBindArgs;
2861    }
2862
2863    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2864        if (r == null || mFocusedActivity == r) {
2865            return false;
2866        }
2867
2868        if (!r.isFocusable()) {
2869            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2870            return false;
2871        }
2872
2873        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2874
2875        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2876        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2877                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2878        mDoingSetFocusedActivity = true;
2879
2880        final ActivityRecord last = mFocusedActivity;
2881        mFocusedActivity = r;
2882        if (r.task.isApplicationTask()) {
2883            if (mCurAppTimeTracker != r.appTimeTracker) {
2884                // We are switching app tracking.  Complete the current one.
2885                if (mCurAppTimeTracker != null) {
2886                    mCurAppTimeTracker.stop();
2887                    mHandler.obtainMessage(
2888                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2889                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2890                    mCurAppTimeTracker = null;
2891                }
2892                if (r.appTimeTracker != null) {
2893                    mCurAppTimeTracker = r.appTimeTracker;
2894                    startTimeTrackingFocusedActivityLocked();
2895                }
2896            } else {
2897                startTimeTrackingFocusedActivityLocked();
2898            }
2899        } else {
2900            r.appTimeTracker = null;
2901        }
2902        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2903        // TODO: Probably not, because we don't want to resume voice on switching
2904        // back to this activity
2905        if (r.task.voiceInteractor != null) {
2906            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2907        } else {
2908            finishRunningVoiceLocked();
2909            IVoiceInteractionSession session;
2910            if (last != null && ((session = last.task.voiceSession) != null
2911                    || (session = last.voiceSession) != null)) {
2912                // We had been in a voice interaction session, but now focused has
2913                // move to something different.  Just finish the session, we can't
2914                // return to it and retain the proper state and synchronization with
2915                // the voice interaction service.
2916                finishVoiceTask(session);
2917            }
2918        }
2919        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2920            mWindowManager.setFocusedApp(r.appToken, true);
2921        }
2922        applyUpdateLockStateLocked(r);
2923        applyUpdateVrModeLocked(r);
2924        if (mFocusedActivity.userId != mLastFocusedUserId) {
2925            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2926            mHandler.obtainMessage(
2927                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2928            mLastFocusedUserId = mFocusedActivity.userId;
2929        }
2930
2931        // Log a warning if the focused app is changed during the process. This could
2932        // indicate a problem of the focus setting logic!
2933        if (mFocusedActivity != r) Slog.w(TAG,
2934                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2935        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2936
2937        EventLogTags.writeAmFocusedActivity(
2938                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2939                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2940                reason);
2941        return true;
2942    }
2943
2944    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2945        if (mFocusedActivity != goingAway) {
2946            return;
2947        }
2948
2949        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2950        if (focusedStack != null) {
2951            final ActivityRecord top = focusedStack.topActivity();
2952            if (top != null && top.userId != mLastFocusedUserId) {
2953                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2954                mHandler.sendMessage(
2955                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2956                mLastFocusedUserId = top.userId;
2957            }
2958        }
2959
2960        // Try to move focus to another activity if possible.
2961        if (setFocusedActivityLocked(
2962                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2963            return;
2964        }
2965
2966        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2967                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2968        mFocusedActivity = null;
2969        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2970    }
2971
2972    @Override
2973    public void setFocusedStack(int stackId) {
2974        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2975        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2976        final long callingId = Binder.clearCallingIdentity();
2977        try {
2978            synchronized (this) {
2979                final ActivityStack stack = mStackSupervisor.getStack(stackId);
2980                if (stack == null) {
2981                    return;
2982                }
2983                final ActivityRecord r = stack.topRunningActivityLocked();
2984                if (setFocusedActivityLocked(r, "setFocusedStack")) {
2985                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
2986                }
2987            }
2988        } finally {
2989            Binder.restoreCallingIdentity(callingId);
2990        }
2991    }
2992
2993    @Override
2994    public void setFocusedTask(int taskId) {
2995        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2996        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2997        final long callingId = Binder.clearCallingIdentity();
2998        try {
2999            synchronized (this) {
3000                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3001                if (task == null) {
3002                    return;
3003                }
3004                final ActivityRecord r = task.topRunningActivityLocked();
3005                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3006                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3007                }
3008            }
3009        } finally {
3010            Binder.restoreCallingIdentity(callingId);
3011        }
3012    }
3013
3014    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3015    @Override
3016    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3017        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3018        synchronized (this) {
3019            if (listener != null) {
3020                mTaskStackListeners.register(listener);
3021            }
3022        }
3023    }
3024
3025    @Override
3026    public void notifyActivityDrawn(IBinder token) {
3027        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3028        synchronized (this) {
3029            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3030            if (r != null) {
3031                r.task.stack.notifyActivityDrawnLocked(r);
3032            }
3033        }
3034    }
3035
3036    final void applyUpdateLockStateLocked(ActivityRecord r) {
3037        // Modifications to the UpdateLock state are done on our handler, outside
3038        // the activity manager's locks.  The new state is determined based on the
3039        // state *now* of the relevant activity record.  The object is passed to
3040        // the handler solely for logging detail, not to be consulted/modified.
3041        final boolean nextState = r != null && r.immersive;
3042        mHandler.sendMessage(
3043                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3044    }
3045
3046    final void applyUpdateVrModeLocked(ActivityRecord r) {
3047        mHandler.sendMessage(
3048                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3049    }
3050
3051    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3052        mHandler.sendMessage(
3053                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3054    }
3055
3056    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3057        Message msg = Message.obtain();
3058        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3059        msg.obj = r.task.askedCompatMode ? null : r;
3060        mUiHandler.sendMessage(msg);
3061    }
3062
3063    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3064            String what, Object obj, ProcessRecord srcApp) {
3065        app.lastActivityTime = now;
3066
3067        if (app.activities.size() > 0) {
3068            // Don't want to touch dependent processes that are hosting activities.
3069            return index;
3070        }
3071
3072        int lrui = mLruProcesses.lastIndexOf(app);
3073        if (lrui < 0) {
3074            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3075                    + what + " " + obj + " from " + srcApp);
3076            return index;
3077        }
3078
3079        if (lrui >= index) {
3080            // Don't want to cause this to move dependent processes *back* in the
3081            // list as if they were less frequently used.
3082            return index;
3083        }
3084
3085        if (lrui >= mLruProcessActivityStart) {
3086            // Don't want to touch dependent processes that are hosting activities.
3087            return index;
3088        }
3089
3090        mLruProcesses.remove(lrui);
3091        if (index > 0) {
3092            index--;
3093        }
3094        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3095                + " in LRU list: " + app);
3096        mLruProcesses.add(index, app);
3097        return index;
3098    }
3099
3100    static void killProcessGroup(int uid, int pid) {
3101        if (sKillHandler != null) {
3102            sKillHandler.sendMessage(
3103                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3104        } else {
3105            Slog.w(TAG, "Asked to kill process group before system bringup!");
3106            Process.killProcessGroup(uid, pid);
3107        }
3108    }
3109
3110    final void removeLruProcessLocked(ProcessRecord app) {
3111        int lrui = mLruProcesses.lastIndexOf(app);
3112        if (lrui >= 0) {
3113            if (!app.killed) {
3114                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3115                Process.killProcessQuiet(app.pid);
3116                killProcessGroup(app.uid, app.pid);
3117            }
3118            if (lrui <= mLruProcessActivityStart) {
3119                mLruProcessActivityStart--;
3120            }
3121            if (lrui <= mLruProcessServiceStart) {
3122                mLruProcessServiceStart--;
3123            }
3124            mLruProcesses.remove(lrui);
3125        }
3126    }
3127
3128    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3129            ProcessRecord client) {
3130        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3131                || app.treatLikeActivity;
3132        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3133        if (!activityChange && hasActivity) {
3134            // The process has activities, so we are only allowing activity-based adjustments
3135            // to move it.  It should be kept in the front of the list with other
3136            // processes that have activities, and we don't want those to change their
3137            // order except due to activity operations.
3138            return;
3139        }
3140
3141        mLruSeq++;
3142        final long now = SystemClock.uptimeMillis();
3143        app.lastActivityTime = now;
3144
3145        // First a quick reject: if the app is already at the position we will
3146        // put it, then there is nothing to do.
3147        if (hasActivity) {
3148            final int N = mLruProcesses.size();
3149            if (N > 0 && mLruProcesses.get(N-1) == app) {
3150                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3151                return;
3152            }
3153        } else {
3154            if (mLruProcessServiceStart > 0
3155                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3156                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3157                return;
3158            }
3159        }
3160
3161        int lrui = mLruProcesses.lastIndexOf(app);
3162
3163        if (app.persistent && lrui >= 0) {
3164            // We don't care about the position of persistent processes, as long as
3165            // they are in the list.
3166            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3167            return;
3168        }
3169
3170        /* In progress: compute new position first, so we can avoid doing work
3171           if the process is not actually going to move.  Not yet working.
3172        int addIndex;
3173        int nextIndex;
3174        boolean inActivity = false, inService = false;
3175        if (hasActivity) {
3176            // Process has activities, put it at the very tipsy-top.
3177            addIndex = mLruProcesses.size();
3178            nextIndex = mLruProcessServiceStart;
3179            inActivity = true;
3180        } else if (hasService) {
3181            // Process has services, put it at the top of the service list.
3182            addIndex = mLruProcessActivityStart;
3183            nextIndex = mLruProcessServiceStart;
3184            inActivity = true;
3185            inService = true;
3186        } else  {
3187            // Process not otherwise of interest, it goes to the top of the non-service area.
3188            addIndex = mLruProcessServiceStart;
3189            if (client != null) {
3190                int clientIndex = mLruProcesses.lastIndexOf(client);
3191                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3192                        + app);
3193                if (clientIndex >= 0 && addIndex > clientIndex) {
3194                    addIndex = clientIndex;
3195                }
3196            }
3197            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3198        }
3199
3200        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3201                + mLruProcessActivityStart + "): " + app);
3202        */
3203
3204        if (lrui >= 0) {
3205            if (lrui < mLruProcessActivityStart) {
3206                mLruProcessActivityStart--;
3207            }
3208            if (lrui < mLruProcessServiceStart) {
3209                mLruProcessServiceStart--;
3210            }
3211            /*
3212            if (addIndex > lrui) {
3213                addIndex--;
3214            }
3215            if (nextIndex > lrui) {
3216                nextIndex--;
3217            }
3218            */
3219            mLruProcesses.remove(lrui);
3220        }
3221
3222        /*
3223        mLruProcesses.add(addIndex, app);
3224        if (inActivity) {
3225            mLruProcessActivityStart++;
3226        }
3227        if (inService) {
3228            mLruProcessActivityStart++;
3229        }
3230        */
3231
3232        int nextIndex;
3233        if (hasActivity) {
3234            final int N = mLruProcesses.size();
3235            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3236                // Process doesn't have activities, but has clients with
3237                // activities...  move it up, but one below the top (the top
3238                // should always have a real activity).
3239                if (DEBUG_LRU) Slog.d(TAG_LRU,
3240                        "Adding to second-top of LRU activity list: " + app);
3241                mLruProcesses.add(N - 1, app);
3242                // To keep it from spamming the LRU list (by making a bunch of clients),
3243                // we will push down any other entries owned by the app.
3244                final int uid = app.info.uid;
3245                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3246                    ProcessRecord subProc = mLruProcesses.get(i);
3247                    if (subProc.info.uid == uid) {
3248                        // We want to push this one down the list.  If the process after
3249                        // it is for the same uid, however, don't do so, because we don't
3250                        // want them internally to be re-ordered.
3251                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3252                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3253                                    "Pushing uid " + uid + " swapping at " + i + ": "
3254                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3255                            ProcessRecord tmp = mLruProcesses.get(i);
3256                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3257                            mLruProcesses.set(i - 1, tmp);
3258                            i--;
3259                        }
3260                    } else {
3261                        // A gap, we can stop here.
3262                        break;
3263                    }
3264                }
3265            } else {
3266                // Process has activities, put it at the very tipsy-top.
3267                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3268                mLruProcesses.add(app);
3269            }
3270            nextIndex = mLruProcessServiceStart;
3271        } else if (hasService) {
3272            // Process has services, put it at the top of the service list.
3273            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3274            mLruProcesses.add(mLruProcessActivityStart, app);
3275            nextIndex = mLruProcessServiceStart;
3276            mLruProcessActivityStart++;
3277        } else  {
3278            // Process not otherwise of interest, it goes to the top of the non-service area.
3279            int index = mLruProcessServiceStart;
3280            if (client != null) {
3281                // If there is a client, don't allow the process to be moved up higher
3282                // in the list than that client.
3283                int clientIndex = mLruProcesses.lastIndexOf(client);
3284                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3285                        + " when updating " + app);
3286                if (clientIndex <= lrui) {
3287                    // Don't allow the client index restriction to push it down farther in the
3288                    // list than it already is.
3289                    clientIndex = lrui;
3290                }
3291                if (clientIndex >= 0 && index > clientIndex) {
3292                    index = clientIndex;
3293                }
3294            }
3295            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3296            mLruProcesses.add(index, app);
3297            nextIndex = index-1;
3298            mLruProcessActivityStart++;
3299            mLruProcessServiceStart++;
3300        }
3301
3302        // If the app is currently using a content provider or service,
3303        // bump those processes as well.
3304        for (int j=app.connections.size()-1; j>=0; j--) {
3305            ConnectionRecord cr = app.connections.valueAt(j);
3306            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3307                    && cr.binding.service.app != null
3308                    && cr.binding.service.app.lruSeq != mLruSeq
3309                    && !cr.binding.service.app.persistent) {
3310                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3311                        "service connection", cr, app);
3312            }
3313        }
3314        for (int j=app.conProviders.size()-1; j>=0; j--) {
3315            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3316            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3317                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3318                        "provider reference", cpr, app);
3319            }
3320        }
3321    }
3322
3323    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3324        if (uid == Process.SYSTEM_UID) {
3325            // The system gets to run in any process.  If there are multiple
3326            // processes with the same uid, just pick the first (this
3327            // should never happen).
3328            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3329            if (procs == null) return null;
3330            final int procCount = procs.size();
3331            for (int i = 0; i < procCount; i++) {
3332                final int procUid = procs.keyAt(i);
3333                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3334                    // Don't use an app process or different user process for system component.
3335                    continue;
3336                }
3337                return procs.valueAt(i);
3338            }
3339        }
3340        ProcessRecord proc = mProcessNames.get(processName, uid);
3341        if (false && proc != null && !keepIfLarge
3342                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3343                && proc.lastCachedPss >= 4000) {
3344            // Turn this condition on to cause killing to happen regularly, for testing.
3345            if (proc.baseProcessTracker != null) {
3346                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3347            }
3348            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3349        } else if (proc != null && !keepIfLarge
3350                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3351                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3352            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3353            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3354                if (proc.baseProcessTracker != null) {
3355                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3356                }
3357                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3358            }
3359        }
3360        return proc;
3361    }
3362
3363    void notifyPackageUse(String packageName, int reason) {
3364        IPackageManager pm = AppGlobals.getPackageManager();
3365        try {
3366            pm.notifyPackageUse(packageName, reason);
3367        } catch (RemoteException e) {
3368        }
3369    }
3370
3371    boolean isNextTransitionForward() {
3372        int transit = mWindowManager.getPendingAppTransition();
3373        return transit == TRANSIT_ACTIVITY_OPEN
3374                || transit == TRANSIT_TASK_OPEN
3375                || transit == TRANSIT_TASK_TO_FRONT;
3376    }
3377
3378    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3379            String processName, String abiOverride, int uid, Runnable crashHandler) {
3380        synchronized(this) {
3381            ApplicationInfo info = new ApplicationInfo();
3382            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3383            // For isolated processes, the former contains the parent's uid and the latter the
3384            // actual uid of the isolated process.
3385            // In the special case introduced by this method (which is, starting an isolated
3386            // process directly from the SystemServer without an actual parent app process) the
3387            // closest thing to a parent's uid is SYSTEM_UID.
3388            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3389            // the |isolated| logic in the ProcessRecord constructor.
3390            info.uid = Process.SYSTEM_UID;
3391            info.processName = processName;
3392            info.className = entryPoint;
3393            info.packageName = "android";
3394            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3395                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3396                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3397                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3398                    crashHandler);
3399            return proc != null ? proc.pid : 0;
3400        }
3401    }
3402
3403    final ProcessRecord startProcessLocked(String processName,
3404            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3405            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3406            boolean isolated, boolean keepIfLarge) {
3407        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3408                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3409                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3410                null /* crashHandler */);
3411    }
3412
3413    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3414            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3415            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3416            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3417        long startTime = SystemClock.elapsedRealtime();
3418        ProcessRecord app;
3419        if (!isolated) {
3420            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3421            checkTime(startTime, "startProcess: after getProcessRecord");
3422
3423            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3424                // If we are in the background, then check to see if this process
3425                // is bad.  If so, we will just silently fail.
3426                if (mAppErrors.isBadProcessLocked(info)) {
3427                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3428                            + "/" + info.processName);
3429                    return null;
3430                }
3431            } else {
3432                // When the user is explicitly starting a process, then clear its
3433                // crash count so that we won't make it bad until they see at
3434                // least one crash dialog again, and make the process good again
3435                // if it had been bad.
3436                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3437                        + "/" + info.processName);
3438                mAppErrors.resetProcessCrashTimeLocked(info);
3439                if (mAppErrors.isBadProcessLocked(info)) {
3440                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3441                            UserHandle.getUserId(info.uid), info.uid,
3442                            info.processName);
3443                    mAppErrors.clearBadProcessLocked(info);
3444                    if (app != null) {
3445                        app.bad = false;
3446                    }
3447                }
3448            }
3449        } else {
3450            // If this is an isolated process, it can't re-use an existing process.
3451            app = null;
3452        }
3453
3454        // app launch boost for big.little configurations
3455        // use cpusets to migrate freshly launched tasks to big cores
3456        synchronized(ActivityManagerService.this) {
3457            nativeMigrateToBoost();
3458            mIsBoosted = true;
3459            mBoostStartTime = SystemClock.uptimeMillis();
3460            Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3461            mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3462        }
3463
3464        // We don't have to do anything more if:
3465        // (1) There is an existing application record; and
3466        // (2) The caller doesn't think it is dead, OR there is no thread
3467        //     object attached to it so we know it couldn't have crashed; and
3468        // (3) There is a pid assigned to it, so it is either starting or
3469        //     already running.
3470        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3471                + " app=" + app + " knownToBeDead=" + knownToBeDead
3472                + " thread=" + (app != null ? app.thread : null)
3473                + " pid=" + (app != null ? app.pid : -1));
3474        if (app != null && app.pid > 0) {
3475            if (!knownToBeDead || app.thread == null) {
3476                // We already have the app running, or are waiting for it to
3477                // come up (we have a pid but not yet its thread), so keep it.
3478                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3479                // If this is a new package in the process, add the package to the list
3480                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3481                checkTime(startTime, "startProcess: done, added package to proc");
3482                return app;
3483            }
3484
3485            // An application record is attached to a previous process,
3486            // clean it up now.
3487            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3488            checkTime(startTime, "startProcess: bad proc running, killing");
3489            killProcessGroup(app.uid, app.pid);
3490            handleAppDiedLocked(app, true, true);
3491            checkTime(startTime, "startProcess: done killing old proc");
3492        }
3493
3494        String hostingNameStr = hostingName != null
3495                ? hostingName.flattenToShortString() : null;
3496
3497        if (app == null) {
3498            checkTime(startTime, "startProcess: creating new process record");
3499            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3500            if (app == null) {
3501                Slog.w(TAG, "Failed making new process record for "
3502                        + processName + "/" + info.uid + " isolated=" + isolated);
3503                return null;
3504            }
3505            app.crashHandler = crashHandler;
3506            checkTime(startTime, "startProcess: done creating new process record");
3507        } else {
3508            // If this is a new package in the process, add the package to the list
3509            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3510            checkTime(startTime, "startProcess: added package to existing proc");
3511        }
3512
3513        // If the system is not ready yet, then hold off on starting this
3514        // process until it is.
3515        if (!mProcessesReady
3516                && !isAllowedWhileBooting(info)
3517                && !allowWhileBooting) {
3518            if (!mProcessesOnHold.contains(app)) {
3519                mProcessesOnHold.add(app);
3520            }
3521            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3522                    "System not ready, putting on hold: " + app);
3523            checkTime(startTime, "startProcess: returning with proc on hold");
3524            return app;
3525        }
3526
3527        checkTime(startTime, "startProcess: stepping in to startProcess");
3528        startProcessLocked(
3529                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3530        checkTime(startTime, "startProcess: done starting proc!");
3531        return (app.pid != 0) ? app : null;
3532    }
3533
3534    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3535        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3536    }
3537
3538    private final void startProcessLocked(ProcessRecord app,
3539            String hostingType, String hostingNameStr) {
3540        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3541                null /* entryPoint */, null /* entryPointArgs */);
3542    }
3543
3544    private final void startProcessLocked(ProcessRecord app, String hostingType,
3545            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3546        long startTime = SystemClock.elapsedRealtime();
3547        if (app.pid > 0 && app.pid != MY_PID) {
3548            checkTime(startTime, "startProcess: removing from pids map");
3549            synchronized (mPidsSelfLocked) {
3550                mPidsSelfLocked.remove(app.pid);
3551                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3552            }
3553            checkTime(startTime, "startProcess: done removing from pids map");
3554            app.setPid(0);
3555        }
3556
3557        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3558                "startProcessLocked removing on hold: " + app);
3559        mProcessesOnHold.remove(app);
3560
3561        checkTime(startTime, "startProcess: starting to update cpu stats");
3562        updateCpuStats();
3563        checkTime(startTime, "startProcess: done updating cpu stats");
3564
3565        try {
3566            try {
3567                final int userId = UserHandle.getUserId(app.uid);
3568                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3569            } catch (RemoteException e) {
3570                throw e.rethrowAsRuntimeException();
3571            }
3572
3573            int uid = app.uid;
3574            int[] gids = null;
3575            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3576            if (!app.isolated) {
3577                int[] permGids = null;
3578                try {
3579                    checkTime(startTime, "startProcess: getting gids from package manager");
3580                    final IPackageManager pm = AppGlobals.getPackageManager();
3581                    permGids = pm.getPackageGids(app.info.packageName,
3582                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3583                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3584                            MountServiceInternal.class);
3585                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3586                            app.info.packageName);
3587                } catch (RemoteException e) {
3588                    throw e.rethrowAsRuntimeException();
3589                }
3590
3591                /*
3592                 * Add shared application and profile GIDs so applications can share some
3593                 * resources like shared libraries and access user-wide resources
3594                 */
3595                if (ArrayUtils.isEmpty(permGids)) {
3596                    gids = new int[2];
3597                } else {
3598                    gids = new int[permGids.length + 2];
3599                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3600                }
3601                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3602                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3603            }
3604            checkTime(startTime, "startProcess: building args");
3605            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3606                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3607                        && mTopComponent != null
3608                        && app.processName.equals(mTopComponent.getPackageName())) {
3609                    uid = 0;
3610                }
3611                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3612                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3613                    uid = 0;
3614                }
3615            }
3616            int debugFlags = 0;
3617            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3618                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3619                // Also turn on CheckJNI for debuggable apps. It's quite
3620                // awkward to turn on otherwise.
3621                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3622            }
3623            // Run the app in safe mode if its manifest requests so or the
3624            // system is booted in safe mode.
3625            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3626                mSafeMode == true) {
3627                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3628            }
3629            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3630                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3631            }
3632            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3633            if ("true".equals(genDebugInfoProperty)) {
3634                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3635            }
3636            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3637                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3638            }
3639            if ("1".equals(SystemProperties.get("debug.assert"))) {
3640                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3641            }
3642            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3643                // Enable all debug flags required by the native debugger.
3644                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3645                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3646                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3647                mNativeDebuggingApp = null;
3648            }
3649
3650            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3651            if (requiredAbi == null) {
3652                requiredAbi = Build.SUPPORTED_ABIS[0];
3653            }
3654
3655            String instructionSet = null;
3656            if (app.info.primaryCpuAbi != null) {
3657                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3658            }
3659
3660            app.gids = gids;
3661            app.requiredAbi = requiredAbi;
3662            app.instructionSet = instructionSet;
3663
3664            // Start the process.  It will either succeed and return a result containing
3665            // the PID of the new process, or else throw a RuntimeException.
3666            boolean isActivityProcess = (entryPoint == null);
3667            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3668            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3669                    app.processName);
3670            checkTime(startTime, "startProcess: asking zygote to start proc");
3671            Process.ProcessStartResult startResult = Process.start(entryPoint,
3672                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3673                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3674                    app.info.dataDir, entryPointArgs);
3675            checkTime(startTime, "startProcess: returned from zygote!");
3676            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3677
3678            if (app.isolated) {
3679                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3680            }
3681            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3682            checkTime(startTime, "startProcess: done updating battery stats");
3683
3684            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3685                    UserHandle.getUserId(uid), startResult.pid, uid,
3686                    app.processName, hostingType,
3687                    hostingNameStr != null ? hostingNameStr : "");
3688
3689            try {
3690                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3691                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3692            } catch (RemoteException ex) {
3693                // Ignore
3694            }
3695
3696            if (app.persistent) {
3697                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3698            }
3699
3700            checkTime(startTime, "startProcess: building log message");
3701            StringBuilder buf = mStringBuilder;
3702            buf.setLength(0);
3703            buf.append("Start proc ");
3704            buf.append(startResult.pid);
3705            buf.append(':');
3706            buf.append(app.processName);
3707            buf.append('/');
3708            UserHandle.formatUid(buf, uid);
3709            if (!isActivityProcess) {
3710                buf.append(" [");
3711                buf.append(entryPoint);
3712                buf.append("]");
3713            }
3714            buf.append(" for ");
3715            buf.append(hostingType);
3716            if (hostingNameStr != null) {
3717                buf.append(" ");
3718                buf.append(hostingNameStr);
3719            }
3720            Slog.i(TAG, buf.toString());
3721            app.setPid(startResult.pid);
3722            app.usingWrapper = startResult.usingWrapper;
3723            app.removed = false;
3724            app.killed = false;
3725            app.killedByAm = false;
3726            checkTime(startTime, "startProcess: starting to update pids map");
3727            synchronized (mPidsSelfLocked) {
3728                this.mPidsSelfLocked.put(startResult.pid, app);
3729                if (isActivityProcess) {
3730                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3731                    msg.obj = app;
3732                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3733                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3734                }
3735            }
3736            checkTime(startTime, "startProcess: done updating pids map");
3737        } catch (RuntimeException e) {
3738            Slog.e(TAG, "Failure starting process " + app.processName, e);
3739
3740            // Something went very wrong while trying to start this process; one
3741            // common case is when the package is frozen due to an active
3742            // upgrade. To recover, clean up any active bookkeeping related to
3743            // starting this process. (We already invoked this method once when
3744            // the package was initially frozen through KILL_APPLICATION_MSG, so
3745            // it doesn't hurt to use it again.)
3746            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3747                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3748        }
3749    }
3750
3751    void updateUsageStats(ActivityRecord component, boolean resumed) {
3752        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3753                "updateUsageStats: comp=" + component + "res=" + resumed);
3754        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3755        if (resumed) {
3756            if (mUsageStatsService != null) {
3757                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3758                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3759            }
3760            synchronized (stats) {
3761                stats.noteActivityResumedLocked(component.app.uid);
3762            }
3763        } else {
3764            if (mUsageStatsService != null) {
3765                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3766                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3767            }
3768            synchronized (stats) {
3769                stats.noteActivityPausedLocked(component.app.uid);
3770            }
3771        }
3772    }
3773
3774    Intent getHomeIntent() {
3775        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3776        intent.setComponent(mTopComponent);
3777        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3778        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3779            intent.addCategory(Intent.CATEGORY_HOME);
3780        }
3781        return intent;
3782    }
3783
3784    boolean startHomeActivityLocked(int userId, String reason) {
3785        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3786                && mTopAction == null) {
3787            // We are running in factory test mode, but unable to find
3788            // the factory test app, so just sit around displaying the
3789            // error message and don't try to start anything.
3790            return false;
3791        }
3792        Intent intent = getHomeIntent();
3793        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3794        if (aInfo != null) {
3795            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3796            // Don't do this if the home app is currently being
3797            // instrumented.
3798            aInfo = new ActivityInfo(aInfo);
3799            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3800            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3801                    aInfo.applicationInfo.uid, true);
3802            if (app == null || app.instrumentationClass == null) {
3803                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3804                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3805            }
3806        } else {
3807            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3808        }
3809
3810        return true;
3811    }
3812
3813    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3814        ActivityInfo ai = null;
3815        ComponentName comp = intent.getComponent();
3816        try {
3817            if (comp != null) {
3818                // Factory test.
3819                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3820            } else {
3821                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3822                        intent,
3823                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3824                        flags, userId);
3825
3826                if (info != null) {
3827                    ai = info.activityInfo;
3828                }
3829            }
3830        } catch (RemoteException e) {
3831            // ignore
3832        }
3833
3834        return ai;
3835    }
3836
3837    /**
3838     * Starts the "new version setup screen" if appropriate.
3839     */
3840    void startSetupActivityLocked() {
3841        // Only do this once per boot.
3842        if (mCheckedForSetup) {
3843            return;
3844        }
3845
3846        // We will show this screen if the current one is a different
3847        // version than the last one shown, and we are not running in
3848        // low-level factory test mode.
3849        final ContentResolver resolver = mContext.getContentResolver();
3850        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3851                Settings.Global.getInt(resolver,
3852                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3853            mCheckedForSetup = true;
3854
3855            // See if we should be showing the platform update setup UI.
3856            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3857            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3858                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3859            if (!ris.isEmpty()) {
3860                final ResolveInfo ri = ris.get(0);
3861                String vers = ri.activityInfo.metaData != null
3862                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3863                        : null;
3864                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3865                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3866                            Intent.METADATA_SETUP_VERSION);
3867                }
3868                String lastVers = Settings.Secure.getString(
3869                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3870                if (vers != null && !vers.equals(lastVers)) {
3871                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3872                    intent.setComponent(new ComponentName(
3873                            ri.activityInfo.packageName, ri.activityInfo.name));
3874                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3875                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3876                            null, 0, 0, 0, null, false, false, null, null, null);
3877                }
3878            }
3879        }
3880    }
3881
3882    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3883        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3884    }
3885
3886    void enforceNotIsolatedCaller(String caller) {
3887        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3888            throw new SecurityException("Isolated process not allowed to call " + caller);
3889        }
3890    }
3891
3892    void enforceShellRestriction(String restriction, int userHandle) {
3893        if (Binder.getCallingUid() == Process.SHELL_UID) {
3894            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3895                throw new SecurityException("Shell does not have permission to access user "
3896                        + userHandle);
3897            }
3898        }
3899    }
3900
3901    @Override
3902    public int getFrontActivityScreenCompatMode() {
3903        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3904        synchronized (this) {
3905            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3906        }
3907    }
3908
3909    @Override
3910    public void setFrontActivityScreenCompatMode(int mode) {
3911        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3912                "setFrontActivityScreenCompatMode");
3913        synchronized (this) {
3914            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3915        }
3916    }
3917
3918    @Override
3919    public int getPackageScreenCompatMode(String packageName) {
3920        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3921        synchronized (this) {
3922            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3923        }
3924    }
3925
3926    @Override
3927    public void setPackageScreenCompatMode(String packageName, int mode) {
3928        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3929                "setPackageScreenCompatMode");
3930        synchronized (this) {
3931            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3932        }
3933    }
3934
3935    @Override
3936    public boolean getPackageAskScreenCompat(String packageName) {
3937        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3938        synchronized (this) {
3939            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3940        }
3941    }
3942
3943    @Override
3944    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3945        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3946                "setPackageAskScreenCompat");
3947        synchronized (this) {
3948            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3949        }
3950    }
3951
3952    private boolean hasUsageStatsPermission(String callingPackage) {
3953        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3954                Binder.getCallingUid(), callingPackage);
3955        if (mode == AppOpsManager.MODE_DEFAULT) {
3956            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3957                    == PackageManager.PERMISSION_GRANTED;
3958        }
3959        return mode == AppOpsManager.MODE_ALLOWED;
3960    }
3961
3962    @Override
3963    public int getPackageProcessState(String packageName, String callingPackage) {
3964        if (!hasUsageStatsPermission(callingPackage)) {
3965            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3966                    "getPackageProcessState");
3967        }
3968
3969        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3970        synchronized (this) {
3971            for (int i=mLruProcesses.size()-1; i>=0; i--) {
3972                final ProcessRecord proc = mLruProcesses.get(i);
3973                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3974                        || procState > proc.setProcState) {
3975                    boolean found = false;
3976                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3977                        if (proc.pkgList.keyAt(j).equals(packageName)) {
3978                            procState = proc.setProcState;
3979                            found = true;
3980                        }
3981                    }
3982                    if (proc.pkgDeps != null && !found) {
3983                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3984                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3985                                procState = proc.setProcState;
3986                                break;
3987                            }
3988                        }
3989                    }
3990                }
3991            }
3992        }
3993        return procState;
3994    }
3995
3996    @Override
3997    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3998        synchronized (this) {
3999            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4000            if (app == null) {
4001                return false;
4002            }
4003            if (app.trimMemoryLevel < level && app.thread != null &&
4004                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4005                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4006                try {
4007                    app.thread.scheduleTrimMemory(level);
4008                    app.trimMemoryLevel = level;
4009                    return true;
4010                } catch (RemoteException e) {
4011                    // Fallthrough to failure case.
4012                }
4013            }
4014        }
4015        return false;
4016    }
4017
4018    private void dispatchProcessesChanged() {
4019        int N;
4020        synchronized (this) {
4021            N = mPendingProcessChanges.size();
4022            if (mActiveProcessChanges.length < N) {
4023                mActiveProcessChanges = new ProcessChangeItem[N];
4024            }
4025            mPendingProcessChanges.toArray(mActiveProcessChanges);
4026            mPendingProcessChanges.clear();
4027            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4028                    "*** Delivering " + N + " process changes");
4029        }
4030
4031        int i = mProcessObservers.beginBroadcast();
4032        while (i > 0) {
4033            i--;
4034            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4035            if (observer != null) {
4036                try {
4037                    for (int j=0; j<N; j++) {
4038                        ProcessChangeItem item = mActiveProcessChanges[j];
4039                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4040                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4041                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4042                                    + item.uid + ": " + item.foregroundActivities);
4043                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4044                                    item.foregroundActivities);
4045                        }
4046                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4047                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4048                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4049                                    + ": " + item.processState);
4050                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4051                        }
4052                    }
4053                } catch (RemoteException e) {
4054                }
4055            }
4056        }
4057        mProcessObservers.finishBroadcast();
4058
4059        synchronized (this) {
4060            for (int j=0; j<N; j++) {
4061                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4062            }
4063        }
4064    }
4065
4066    private void dispatchProcessDied(int pid, int uid) {
4067        int i = mProcessObservers.beginBroadcast();
4068        while (i > 0) {
4069            i--;
4070            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4071            if (observer != null) {
4072                try {
4073                    observer.onProcessDied(pid, uid);
4074                } catch (RemoteException e) {
4075                }
4076            }
4077        }
4078        mProcessObservers.finishBroadcast();
4079    }
4080
4081    private void dispatchUidsChanged() {
4082        int N;
4083        synchronized (this) {
4084            N = mPendingUidChanges.size();
4085            if (mActiveUidChanges.length < N) {
4086                mActiveUidChanges = new UidRecord.ChangeItem[N];
4087            }
4088            for (int i=0; i<N; i++) {
4089                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4090                mActiveUidChanges[i] = change;
4091                if (change.uidRecord != null) {
4092                    change.uidRecord.pendingChange = null;
4093                    change.uidRecord = null;
4094                }
4095            }
4096            mPendingUidChanges.clear();
4097            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4098                    "*** Delivering " + N + " uid changes");
4099        }
4100
4101        if (mLocalPowerManager != null) {
4102            for (int j=0; j<N; j++) {
4103                UidRecord.ChangeItem item = mActiveUidChanges[j];
4104                if (item.change == UidRecord.CHANGE_GONE
4105                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4106                    mLocalPowerManager.uidGone(item.uid);
4107                } else {
4108                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4109                }
4110            }
4111        }
4112
4113        int i = mUidObservers.beginBroadcast();
4114        while (i > 0) {
4115            i--;
4116            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4117            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4118            if (observer != null) {
4119                try {
4120                    for (int j=0; j<N; j++) {
4121                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4122                        final int change = item.change;
4123                        UidRecord validateUid = null;
4124                        if (VALIDATE_UID_STATES && i == 0) {
4125                            validateUid = mValidateUids.get(item.uid);
4126                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4127                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4128                                validateUid = new UidRecord(item.uid);
4129                                mValidateUids.put(item.uid, validateUid);
4130                            }
4131                        }
4132                        if (change == UidRecord.CHANGE_IDLE
4133                                || change == UidRecord.CHANGE_GONE_IDLE) {
4134                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4135                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4136                                        "UID idle uid=" + item.uid);
4137                                observer.onUidIdle(item.uid);
4138                            }
4139                            if (VALIDATE_UID_STATES && i == 0) {
4140                                if (validateUid != null) {
4141                                    validateUid.idle = true;
4142                                }
4143                            }
4144                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4145                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4146                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4147                                        "UID active uid=" + item.uid);
4148                                observer.onUidActive(item.uid);
4149                            }
4150                            if (VALIDATE_UID_STATES && i == 0) {
4151                                validateUid.idle = false;
4152                            }
4153                        }
4154                        if (change == UidRecord.CHANGE_GONE
4155                                || change == UidRecord.CHANGE_GONE_IDLE) {
4156                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4157                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4158                                        "UID gone uid=" + item.uid);
4159                                observer.onUidGone(item.uid);
4160                            }
4161                            if (VALIDATE_UID_STATES && i == 0) {
4162                                if (validateUid != null) {
4163                                    mValidateUids.remove(item.uid);
4164                                }
4165                            }
4166                        } else {
4167                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4168                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4169                                        "UID CHANGED uid=" + item.uid
4170                                                + ": " + item.processState);
4171                                observer.onUidStateChanged(item.uid, item.processState);
4172                            }
4173                            if (VALIDATE_UID_STATES && i == 0) {
4174                                validateUid.curProcState = validateUid.setProcState
4175                                        = item.processState;
4176                            }
4177                        }
4178                    }
4179                } catch (RemoteException e) {
4180                }
4181            }
4182        }
4183        mUidObservers.finishBroadcast();
4184
4185        synchronized (this) {
4186            for (int j=0; j<N; j++) {
4187                mAvailUidChanges.add(mActiveUidChanges[j]);
4188            }
4189        }
4190    }
4191
4192    @Override
4193    public final int startActivity(IApplicationThread caller, String callingPackage,
4194            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4195            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4196        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4197                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4198                UserHandle.getCallingUserId());
4199    }
4200
4201    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4202        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4203        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4204                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4205                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4206
4207        // TODO: Switch to user app stacks here.
4208        String mimeType = intent.getType();
4209        final Uri data = intent.getData();
4210        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4211            mimeType = getProviderMimeType(data, userId);
4212        }
4213        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4214
4215        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4216        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4217                null, 0, 0, null, null, null, null, false, userId, container, null);
4218    }
4219
4220    @Override
4221    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4222            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4223            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4224        enforceNotIsolatedCaller("startActivity");
4225        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4226                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4227        // TODO: Switch to user app stacks here.
4228        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4229                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4230                profilerInfo, null, null, bOptions, false, userId, null, null);
4231    }
4232
4233    @Override
4234    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4235            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4236            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4237            int userId) {
4238
4239        // This is very dangerous -- it allows you to perform a start activity (including
4240        // permission grants) as any app that may launch one of your own activities.  So
4241        // we will only allow this to be done from activities that are part of the core framework,
4242        // and then only when they are running as the system.
4243        final ActivityRecord sourceRecord;
4244        final int targetUid;
4245        final String targetPackage;
4246        synchronized (this) {
4247            if (resultTo == null) {
4248                throw new SecurityException("Must be called from an activity");
4249            }
4250            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4251            if (sourceRecord == null) {
4252                throw new SecurityException("Called with bad activity token: " + resultTo);
4253            }
4254            if (!sourceRecord.info.packageName.equals("android")) {
4255                throw new SecurityException(
4256                        "Must be called from an activity that is declared in the android package");
4257            }
4258            if (sourceRecord.app == null) {
4259                throw new SecurityException("Called without a process attached to activity");
4260            }
4261            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4262                // This is still okay, as long as this activity is running under the
4263                // uid of the original calling activity.
4264                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4265                    throw new SecurityException(
4266                            "Calling activity in uid " + sourceRecord.app.uid
4267                                    + " must be system uid or original calling uid "
4268                                    + sourceRecord.launchedFromUid);
4269                }
4270            }
4271            if (ignoreTargetSecurity) {
4272                if (intent.getComponent() == null) {
4273                    throw new SecurityException(
4274                            "Component must be specified with ignoreTargetSecurity");
4275                }
4276                if (intent.getSelector() != null) {
4277                    throw new SecurityException(
4278                            "Selector not allowed with ignoreTargetSecurity");
4279                }
4280            }
4281            targetUid = sourceRecord.launchedFromUid;
4282            targetPackage = sourceRecord.launchedFromPackage;
4283        }
4284
4285        if (userId == UserHandle.USER_NULL) {
4286            userId = UserHandle.getUserId(sourceRecord.app.uid);
4287        }
4288
4289        // TODO: Switch to user app stacks here.
4290        try {
4291            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4292                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4293                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4294            return ret;
4295        } catch (SecurityException e) {
4296            // XXX need to figure out how to propagate to original app.
4297            // A SecurityException here is generally actually a fault of the original
4298            // calling activity (such as a fairly granting permissions), so propagate it
4299            // back to them.
4300            /*
4301            StringBuilder msg = new StringBuilder();
4302            msg.append("While launching");
4303            msg.append(intent.toString());
4304            msg.append(": ");
4305            msg.append(e.getMessage());
4306            */
4307            throw e;
4308        }
4309    }
4310
4311    @Override
4312    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4313            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4314            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4315        enforceNotIsolatedCaller("startActivityAndWait");
4316        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4317                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4318        WaitResult res = new WaitResult();
4319        // TODO: Switch to user app stacks here.
4320        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4321                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4322                bOptions, false, userId, null, null);
4323        return res;
4324    }
4325
4326    @Override
4327    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4328            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4329            int startFlags, Configuration config, Bundle bOptions, int userId) {
4330        enforceNotIsolatedCaller("startActivityWithConfig");
4331        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4332                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4333        // TODO: Switch to user app stacks here.
4334        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4335                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4336                null, null, config, bOptions, false, userId, null, null);
4337        return ret;
4338    }
4339
4340    @Override
4341    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4342            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4343            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4344            throws TransactionTooLargeException {
4345        enforceNotIsolatedCaller("startActivityIntentSender");
4346        // Refuse possible leaked file descriptors
4347        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4348            throw new IllegalArgumentException("File descriptors passed in Intent");
4349        }
4350
4351        IIntentSender sender = intent.getTarget();
4352        if (!(sender instanceof PendingIntentRecord)) {
4353            throw new IllegalArgumentException("Bad PendingIntent object");
4354        }
4355
4356        PendingIntentRecord pir = (PendingIntentRecord)sender;
4357
4358        synchronized (this) {
4359            // If this is coming from the currently resumed activity, it is
4360            // effectively saying that app switches are allowed at this point.
4361            final ActivityStack stack = getFocusedStack();
4362            if (stack.mResumedActivity != null &&
4363                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4364                mAppSwitchesAllowedTime = 0;
4365            }
4366        }
4367        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4368                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4369        return ret;
4370    }
4371
4372    @Override
4373    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4374            Intent intent, String resolvedType, IVoiceInteractionSession session,
4375            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4376            Bundle bOptions, int userId) {
4377        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4378                != PackageManager.PERMISSION_GRANTED) {
4379            String msg = "Permission Denial: startVoiceActivity() from pid="
4380                    + Binder.getCallingPid()
4381                    + ", uid=" + Binder.getCallingUid()
4382                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4383            Slog.w(TAG, msg);
4384            throw new SecurityException(msg);
4385        }
4386        if (session == null || interactor == null) {
4387            throw new NullPointerException("null session or interactor");
4388        }
4389        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4390                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4391        // TODO: Switch to user app stacks here.
4392        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4393                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4394                null, bOptions, false, userId, null, null);
4395    }
4396
4397    @Override
4398    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4399            throws RemoteException {
4400        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4401        synchronized (this) {
4402            ActivityRecord activity = getFocusedStack().topActivity();
4403            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4404                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4405            }
4406            if (mRunningVoice != null || activity.task.voiceSession != null
4407                    || activity.voiceSession != null) {
4408                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4409                return;
4410            }
4411            if (activity.pendingVoiceInteractionStart) {
4412                Slog.w(TAG, "Pending start of voice interaction already.");
4413                return;
4414            }
4415            activity.pendingVoiceInteractionStart = true;
4416        }
4417        LocalServices.getService(VoiceInteractionManagerInternal.class)
4418                .startLocalVoiceInteraction(callingActivity, options);
4419    }
4420
4421    @Override
4422    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4423        LocalServices.getService(VoiceInteractionManagerInternal.class)
4424                .stopLocalVoiceInteraction(callingActivity);
4425    }
4426
4427    @Override
4428    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4429        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4430                .supportsLocalVoiceInteraction();
4431    }
4432
4433    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4434            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4435        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4436        if (activityToCallback == null) return;
4437        activityToCallback.setVoiceSessionLocked(voiceSession);
4438
4439        // Inform the activity
4440        try {
4441            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4442                    voiceInteractor);
4443            long token = Binder.clearCallingIdentity();
4444            try {
4445                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4446            } finally {
4447                Binder.restoreCallingIdentity(token);
4448            }
4449            // TODO: VI Should we cache the activity so that it's easier to find later
4450            // rather than scan through all the stacks and activities?
4451        } catch (RemoteException re) {
4452            activityToCallback.clearVoiceSessionLocked();
4453            // TODO: VI Should this terminate the voice session?
4454        }
4455    }
4456
4457    @Override
4458    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4459        synchronized (this) {
4460            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4461                if (keepAwake) {
4462                    mVoiceWakeLock.acquire();
4463                } else {
4464                    mVoiceWakeLock.release();
4465                }
4466            }
4467        }
4468    }
4469
4470    @Override
4471    public boolean startNextMatchingActivity(IBinder callingActivity,
4472            Intent intent, Bundle bOptions) {
4473        // Refuse possible leaked file descriptors
4474        if (intent != null && intent.hasFileDescriptors() == true) {
4475            throw new IllegalArgumentException("File descriptors passed in Intent");
4476        }
4477        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4478
4479        synchronized (this) {
4480            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4481            if (r == null) {
4482                ActivityOptions.abort(options);
4483                return false;
4484            }
4485            if (r.app == null || r.app.thread == null) {
4486                // The caller is not running...  d'oh!
4487                ActivityOptions.abort(options);
4488                return false;
4489            }
4490            intent = new Intent(intent);
4491            // The caller is not allowed to change the data.
4492            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4493            // And we are resetting to find the next component...
4494            intent.setComponent(null);
4495
4496            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4497
4498            ActivityInfo aInfo = null;
4499            try {
4500                List<ResolveInfo> resolves =
4501                    AppGlobals.getPackageManager().queryIntentActivities(
4502                            intent, r.resolvedType,
4503                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4504                            UserHandle.getCallingUserId()).getList();
4505
4506                // Look for the original activity in the list...
4507                final int N = resolves != null ? resolves.size() : 0;
4508                for (int i=0; i<N; i++) {
4509                    ResolveInfo rInfo = resolves.get(i);
4510                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4511                            && rInfo.activityInfo.name.equals(r.info.name)) {
4512                        // We found the current one...  the next matching is
4513                        // after it.
4514                        i++;
4515                        if (i<N) {
4516                            aInfo = resolves.get(i).activityInfo;
4517                        }
4518                        if (debug) {
4519                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4520                                    + "/" + r.info.name);
4521                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4522                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4523                        }
4524                        break;
4525                    }
4526                }
4527            } catch (RemoteException e) {
4528            }
4529
4530            if (aInfo == null) {
4531                // Nobody who is next!
4532                ActivityOptions.abort(options);
4533                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4534                return false;
4535            }
4536
4537            intent.setComponent(new ComponentName(
4538                    aInfo.applicationInfo.packageName, aInfo.name));
4539            intent.setFlags(intent.getFlags()&~(
4540                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4541                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4542                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4543                    Intent.FLAG_ACTIVITY_NEW_TASK));
4544
4545            // Okay now we need to start the new activity, replacing the
4546            // currently running activity.  This is a little tricky because
4547            // we want to start the new one as if the current one is finished,
4548            // but not finish the current one first so that there is no flicker.
4549            // And thus...
4550            final boolean wasFinishing = r.finishing;
4551            r.finishing = true;
4552
4553            // Propagate reply information over to the new activity.
4554            final ActivityRecord resultTo = r.resultTo;
4555            final String resultWho = r.resultWho;
4556            final int requestCode = r.requestCode;
4557            r.resultTo = null;
4558            if (resultTo != null) {
4559                resultTo.removeResultsLocked(r, resultWho, requestCode);
4560            }
4561
4562            final long origId = Binder.clearCallingIdentity();
4563            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4564                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4565                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4566                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4567                    false, false, null, null, null);
4568            Binder.restoreCallingIdentity(origId);
4569
4570            r.finishing = wasFinishing;
4571            if (res != ActivityManager.START_SUCCESS) {
4572                return false;
4573            }
4574            return true;
4575        }
4576    }
4577
4578    @Override
4579    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4580        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4581            String msg = "Permission Denial: startActivityFromRecents called without " +
4582                    START_TASKS_FROM_RECENTS;
4583            Slog.w(TAG, msg);
4584            throw new SecurityException(msg);
4585        }
4586        final long origId = Binder.clearCallingIdentity();
4587        try {
4588            synchronized (this) {
4589                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4590            }
4591        } finally {
4592            Binder.restoreCallingIdentity(origId);
4593        }
4594    }
4595
4596    final int startActivityInPackage(int uid, String callingPackage,
4597            Intent intent, String resolvedType, IBinder resultTo,
4598            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4599            IActivityContainer container, TaskRecord inTask) {
4600
4601        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4602                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4603
4604        // TODO: Switch to user app stacks here.
4605        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4606                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4607                null, null, null, bOptions, false, userId, container, inTask);
4608        return ret;
4609    }
4610
4611    @Override
4612    public final int startActivities(IApplicationThread caller, String callingPackage,
4613            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4614            int userId) {
4615        enforceNotIsolatedCaller("startActivities");
4616        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4617                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4618        // TODO: Switch to user app stacks here.
4619        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4620                resolvedTypes, resultTo, bOptions, userId);
4621        return ret;
4622    }
4623
4624    final int startActivitiesInPackage(int uid, String callingPackage,
4625            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4626            Bundle bOptions, int userId) {
4627
4628        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4629                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4630        // TODO: Switch to user app stacks here.
4631        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4632                resultTo, bOptions, userId);
4633        return ret;
4634    }
4635
4636    @Override
4637    public void reportActivityFullyDrawn(IBinder token) {
4638        synchronized (this) {
4639            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4640            if (r == null) {
4641                return;
4642            }
4643            r.reportFullyDrawnLocked();
4644        }
4645    }
4646
4647    @Override
4648    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4649        synchronized (this) {
4650            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4651            if (r == null) {
4652                return;
4653            }
4654            TaskRecord task = r.task;
4655            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4656                // Fixed screen orientation isn't supported when activities aren't in full screen
4657                // mode.
4658                return;
4659            }
4660            final long origId = Binder.clearCallingIdentity();
4661            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4662            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4663                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4664            if (config != null) {
4665                r.frozenBeforeDestroy = true;
4666                if (!updateConfigurationLocked(config, r, false)) {
4667                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4668                }
4669            }
4670            Binder.restoreCallingIdentity(origId);
4671        }
4672    }
4673
4674    @Override
4675    public int getRequestedOrientation(IBinder token) {
4676        synchronized (this) {
4677            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4678            if (r == null) {
4679                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4680            }
4681            return mWindowManager.getAppOrientation(r.appToken);
4682        }
4683    }
4684
4685    /**
4686     * This is the internal entry point for handling Activity.finish().
4687     *
4688     * @param token The Binder token referencing the Activity we want to finish.
4689     * @param resultCode Result code, if any, from this Activity.
4690     * @param resultData Result data (Intent), if any, from this Activity.
4691     * @param finishTask Whether to finish the task associated with this Activity.
4692     *
4693     * @return Returns true if the activity successfully finished, or false if it is still running.
4694     */
4695    @Override
4696    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4697            int finishTask) {
4698        // Refuse possible leaked file descriptors
4699        if (resultData != null && resultData.hasFileDescriptors() == true) {
4700            throw new IllegalArgumentException("File descriptors passed in Intent");
4701        }
4702
4703        synchronized(this) {
4704            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4705            if (r == null) {
4706                return true;
4707            }
4708            // Keep track of the root activity of the task before we finish it
4709            TaskRecord tr = r.task;
4710            ActivityRecord rootR = tr.getRootActivity();
4711            if (rootR == null) {
4712                Slog.w(TAG, "Finishing task with all activities already finished");
4713            }
4714            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4715            // finish.
4716            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4717                    mStackSupervisor.isLastLockedTask(tr)) {
4718                Slog.i(TAG, "Not finishing task in lock task mode");
4719                mStackSupervisor.showLockTaskToast();
4720                return false;
4721            }
4722            if (mController != null) {
4723                // Find the first activity that is not finishing.
4724                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4725                if (next != null) {
4726                    // ask watcher if this is allowed
4727                    boolean resumeOK = true;
4728                    try {
4729                        resumeOK = mController.activityResuming(next.packageName);
4730                    } catch (RemoteException e) {
4731                        mController = null;
4732                        Watchdog.getInstance().setActivityController(null);
4733                    }
4734
4735                    if (!resumeOK) {
4736                        Slog.i(TAG, "Not finishing activity because controller resumed");
4737                        return false;
4738                    }
4739                }
4740            }
4741            final long origId = Binder.clearCallingIdentity();
4742            try {
4743                boolean res;
4744                final boolean finishWithRootActivity =
4745                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4746                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4747                        || (finishWithRootActivity && r == rootR)) {
4748                    // If requested, remove the task that is associated to this activity only if it
4749                    // was the root activity in the task. The result code and data is ignored
4750                    // because we don't support returning them across task boundaries. Also, to
4751                    // keep backwards compatibility we remove the task from recents when finishing
4752                    // task with root activity.
4753                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4754                    if (!res) {
4755                        Slog.i(TAG, "Removing task failed to finish activity");
4756                    }
4757                } else {
4758                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4759                            resultData, "app-request", true);
4760                    if (!res) {
4761                        Slog.i(TAG, "Failed to finish by app-request");
4762                    }
4763                }
4764                return res;
4765            } finally {
4766                Binder.restoreCallingIdentity(origId);
4767            }
4768        }
4769    }
4770
4771    @Override
4772    public final void finishHeavyWeightApp() {
4773        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4774                != PackageManager.PERMISSION_GRANTED) {
4775            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4776                    + Binder.getCallingPid()
4777                    + ", uid=" + Binder.getCallingUid()
4778                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4779            Slog.w(TAG, msg);
4780            throw new SecurityException(msg);
4781        }
4782
4783        synchronized(this) {
4784            if (mHeavyWeightProcess == null) {
4785                return;
4786            }
4787
4788            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4789            for (int i = 0; i < activities.size(); i++) {
4790                ActivityRecord r = activities.get(i);
4791                if (!r.finishing && r.isInStackLocked()) {
4792                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4793                            null, "finish-heavy", true);
4794                }
4795            }
4796
4797            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4798                    mHeavyWeightProcess.userId, 0));
4799            mHeavyWeightProcess = null;
4800        }
4801    }
4802
4803    @Override
4804    public void crashApplication(int uid, int initialPid, String packageName,
4805            String message) {
4806        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4807                != PackageManager.PERMISSION_GRANTED) {
4808            String msg = "Permission Denial: crashApplication() from pid="
4809                    + Binder.getCallingPid()
4810                    + ", uid=" + Binder.getCallingUid()
4811                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4812            Slog.w(TAG, msg);
4813            throw new SecurityException(msg);
4814        }
4815
4816        synchronized(this) {
4817            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4818        }
4819    }
4820
4821    @Override
4822    public final void finishSubActivity(IBinder token, String resultWho,
4823            int requestCode) {
4824        synchronized(this) {
4825            final long origId = Binder.clearCallingIdentity();
4826            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4827            if (r != null) {
4828                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4829            }
4830            Binder.restoreCallingIdentity(origId);
4831        }
4832    }
4833
4834    @Override
4835    public boolean finishActivityAffinity(IBinder token) {
4836        synchronized(this) {
4837            final long origId = Binder.clearCallingIdentity();
4838            try {
4839                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4840                if (r == null) {
4841                    return false;
4842                }
4843
4844                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4845                // can finish.
4846                final TaskRecord task = r.task;
4847                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4848                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4849                    mStackSupervisor.showLockTaskToast();
4850                    return false;
4851                }
4852                return task.stack.finishActivityAffinityLocked(r);
4853            } finally {
4854                Binder.restoreCallingIdentity(origId);
4855            }
4856        }
4857    }
4858
4859    @Override
4860    public void finishVoiceTask(IVoiceInteractionSession session) {
4861        synchronized (this) {
4862            final long origId = Binder.clearCallingIdentity();
4863            try {
4864                // TODO: VI Consider treating local voice interactions and voice tasks
4865                // differently here
4866                mStackSupervisor.finishVoiceTask(session);
4867            } finally {
4868                Binder.restoreCallingIdentity(origId);
4869            }
4870        }
4871
4872    }
4873
4874    @Override
4875    public boolean releaseActivityInstance(IBinder token) {
4876        synchronized(this) {
4877            final long origId = Binder.clearCallingIdentity();
4878            try {
4879                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4880                if (r == null) {
4881                    return false;
4882                }
4883                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4884            } finally {
4885                Binder.restoreCallingIdentity(origId);
4886            }
4887        }
4888    }
4889
4890    @Override
4891    public void releaseSomeActivities(IApplicationThread appInt) {
4892        synchronized(this) {
4893            final long origId = Binder.clearCallingIdentity();
4894            try {
4895                ProcessRecord app = getRecordForAppLocked(appInt);
4896                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4897            } finally {
4898                Binder.restoreCallingIdentity(origId);
4899            }
4900        }
4901    }
4902
4903    @Override
4904    public boolean willActivityBeVisible(IBinder token) {
4905        synchronized(this) {
4906            ActivityStack stack = ActivityRecord.getStackLocked(token);
4907            if (stack != null) {
4908                return stack.willActivityBeVisibleLocked(token);
4909            }
4910            return false;
4911        }
4912    }
4913
4914    @Override
4915    public void overridePendingTransition(IBinder token, String packageName,
4916            int enterAnim, int exitAnim) {
4917        synchronized(this) {
4918            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4919            if (self == null) {
4920                return;
4921            }
4922
4923            final long origId = Binder.clearCallingIdentity();
4924
4925            if (self.state == ActivityState.RESUMED
4926                    || self.state == ActivityState.PAUSING) {
4927                mWindowManager.overridePendingAppTransition(packageName,
4928                        enterAnim, exitAnim, null);
4929            }
4930
4931            Binder.restoreCallingIdentity(origId);
4932        }
4933    }
4934
4935    /**
4936     * Main function for removing an existing process from the activity manager
4937     * as a result of that process going away.  Clears out all connections
4938     * to the process.
4939     */
4940    private final void handleAppDiedLocked(ProcessRecord app,
4941            boolean restarting, boolean allowRestart) {
4942        int pid = app.pid;
4943        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4944        if (!kept && !restarting) {
4945            removeLruProcessLocked(app);
4946            if (pid > 0) {
4947                ProcessList.remove(pid);
4948            }
4949        }
4950
4951        if (mProfileProc == app) {
4952            clearProfilerLocked();
4953        }
4954
4955        // Remove this application's activities from active lists.
4956        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4957
4958        app.activities.clear();
4959
4960        if (app.instrumentationClass != null) {
4961            Slog.w(TAG, "Crash of app " + app.processName
4962                  + " running instrumentation " + app.instrumentationClass);
4963            Bundle info = new Bundle();
4964            info.putString("shortMsg", "Process crashed.");
4965            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4966        }
4967
4968        if (!restarting && hasVisibleActivities
4969                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4970            // If there was nothing to resume, and we are not already restarting this process, but
4971            // there is a visible activity that is hosted by the process...  then make sure all
4972            // visible activities are running, taking care of restarting this process.
4973            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4974        }
4975    }
4976
4977    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4978        IBinder threadBinder = thread.asBinder();
4979        // Find the application record.
4980        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4981            ProcessRecord rec = mLruProcesses.get(i);
4982            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4983                return i;
4984            }
4985        }
4986        return -1;
4987    }
4988
4989    final ProcessRecord getRecordForAppLocked(
4990            IApplicationThread thread) {
4991        if (thread == null) {
4992            return null;
4993        }
4994
4995        int appIndex = getLRURecordIndexForAppLocked(thread);
4996        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4997    }
4998
4999    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5000        // If there are no longer any background processes running,
5001        // and the app that died was not running instrumentation,
5002        // then tell everyone we are now low on memory.
5003        boolean haveBg = false;
5004        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5005            ProcessRecord rec = mLruProcesses.get(i);
5006            if (rec.thread != null
5007                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5008                haveBg = true;
5009                break;
5010            }
5011        }
5012
5013        if (!haveBg) {
5014            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5015            if (doReport) {
5016                long now = SystemClock.uptimeMillis();
5017                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5018                    doReport = false;
5019                } else {
5020                    mLastMemUsageReportTime = now;
5021                }
5022            }
5023            final ArrayList<ProcessMemInfo> memInfos
5024                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5025            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5026            long now = SystemClock.uptimeMillis();
5027            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5028                ProcessRecord rec = mLruProcesses.get(i);
5029                if (rec == dyingProc || rec.thread == null) {
5030                    continue;
5031                }
5032                if (doReport) {
5033                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5034                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5035                }
5036                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5037                    // The low memory report is overriding any current
5038                    // state for a GC request.  Make sure to do
5039                    // heavy/important/visible/foreground processes first.
5040                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5041                        rec.lastRequestedGc = 0;
5042                    } else {
5043                        rec.lastRequestedGc = rec.lastLowMemory;
5044                    }
5045                    rec.reportLowMemory = true;
5046                    rec.lastLowMemory = now;
5047                    mProcessesToGc.remove(rec);
5048                    addProcessToGcListLocked(rec);
5049                }
5050            }
5051            if (doReport) {
5052                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5053                mHandler.sendMessage(msg);
5054            }
5055            scheduleAppGcsLocked();
5056        }
5057    }
5058
5059    final void appDiedLocked(ProcessRecord app) {
5060       appDiedLocked(app, app.pid, app.thread, false);
5061    }
5062
5063    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5064            boolean fromBinderDied) {
5065        // First check if this ProcessRecord is actually active for the pid.
5066        synchronized (mPidsSelfLocked) {
5067            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5068            if (curProc != app) {
5069                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5070                return;
5071            }
5072        }
5073
5074        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5075        synchronized (stats) {
5076            stats.noteProcessDiedLocked(app.info.uid, pid);
5077        }
5078
5079        if (!app.killed) {
5080            if (!fromBinderDied) {
5081                Process.killProcessQuiet(pid);
5082            }
5083            killProcessGroup(app.uid, pid);
5084            app.killed = true;
5085        }
5086
5087        // Clean up already done if the process has been re-started.
5088        if (app.pid == pid && app.thread != null &&
5089                app.thread.asBinder() == thread.asBinder()) {
5090            boolean doLowMem = app.instrumentationClass == null;
5091            boolean doOomAdj = doLowMem;
5092            if (!app.killedByAm) {
5093                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5094                        + ") has died");
5095                mAllowLowerMemLevel = true;
5096            } else {
5097                // Note that we always want to do oom adj to update our state with the
5098                // new number of procs.
5099                mAllowLowerMemLevel = false;
5100                doLowMem = false;
5101            }
5102            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5103            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5104                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5105            handleAppDiedLocked(app, false, true);
5106
5107            if (doOomAdj) {
5108                updateOomAdjLocked();
5109            }
5110            if (doLowMem) {
5111                doLowMemReportIfNeededLocked(app);
5112            }
5113        } else if (app.pid != pid) {
5114            // A new process has already been started.
5115            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5116                    + ") has died and restarted (pid " + app.pid + ").");
5117            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5118        } else if (DEBUG_PROCESSES) {
5119            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5120                    + thread.asBinder());
5121        }
5122    }
5123
5124    /**
5125     * If a stack trace dump file is configured, dump process stack traces.
5126     * @param clearTraces causes the dump file to be erased prior to the new
5127     *    traces being written, if true; when false, the new traces will be
5128     *    appended to any existing file content.
5129     * @param firstPids of dalvik VM processes to dump stack traces for first
5130     * @param lastPids of dalvik VM processes to dump stack traces for last
5131     * @param nativeProcs optional list of native process names to dump stack crawls
5132     * @return file containing stack traces, or null if no dump file is configured
5133     */
5134    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5135            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5136        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5137        if (tracesPath == null || tracesPath.length() == 0) {
5138            return null;
5139        }
5140
5141        File tracesFile = new File(tracesPath);
5142        try {
5143            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5144            tracesFile.createNewFile();
5145            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5146        } catch (IOException e) {
5147            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5148            return null;
5149        }
5150
5151        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5152        return tracesFile;
5153    }
5154
5155    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5156            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5157        // Use a FileObserver to detect when traces finish writing.
5158        // The order of traces is considered important to maintain for legibility.
5159        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5160            @Override
5161            public synchronized void onEvent(int event, String path) { notify(); }
5162        };
5163
5164        try {
5165            observer.startWatching();
5166
5167            // First collect all of the stacks of the most important pids.
5168            if (firstPids != null) {
5169                try {
5170                    int num = firstPids.size();
5171                    for (int i = 0; i < num; i++) {
5172                        synchronized (observer) {
5173                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5174                                    + firstPids.get(i));
5175                            final long sime = SystemClock.elapsedRealtime();
5176                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5177                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5178                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5179                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5180                        }
5181                    }
5182                } catch (InterruptedException e) {
5183                    Slog.wtf(TAG, e);
5184                }
5185            }
5186
5187            // Next collect the stacks of the native pids
5188            if (nativeProcs != null) {
5189                int[] pids = Process.getPidsForCommands(nativeProcs);
5190                if (pids != null) {
5191                    for (int pid : pids) {
5192                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5193                        final long sime = SystemClock.elapsedRealtime();
5194                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5195                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5196                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5197                    }
5198                }
5199            }
5200
5201            // Lastly, measure CPU usage.
5202            if (processCpuTracker != null) {
5203                processCpuTracker.init();
5204                System.gc();
5205                processCpuTracker.update();
5206                try {
5207                    synchronized (processCpuTracker) {
5208                        processCpuTracker.wait(500); // measure over 1/2 second.
5209                    }
5210                } catch (InterruptedException e) {
5211                }
5212                processCpuTracker.update();
5213
5214                // We'll take the stack crawls of just the top apps using CPU.
5215                final int N = processCpuTracker.countWorkingStats();
5216                int numProcs = 0;
5217                for (int i=0; i<N && numProcs<5; i++) {
5218                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5219                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5220                        numProcs++;
5221                        try {
5222                            synchronized (observer) {
5223                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5224                                        + stats.pid);
5225                                final long stime = SystemClock.elapsedRealtime();
5226                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5227                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5228                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5229                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5230                            }
5231                        } catch (InterruptedException e) {
5232                            Slog.wtf(TAG, e);
5233                        }
5234                    } else if (DEBUG_ANR) {
5235                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5236                                + stats.pid);
5237                    }
5238                }
5239            }
5240        } finally {
5241            observer.stopWatching();
5242        }
5243    }
5244
5245    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5246        if (true || IS_USER_BUILD) {
5247            return;
5248        }
5249        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5250        if (tracesPath == null || tracesPath.length() == 0) {
5251            return;
5252        }
5253
5254        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5255        StrictMode.allowThreadDiskWrites();
5256        try {
5257            final File tracesFile = new File(tracesPath);
5258            final File tracesDir = tracesFile.getParentFile();
5259            final File tracesTmp = new File(tracesDir, "__tmp__");
5260            try {
5261                if (tracesFile.exists()) {
5262                    tracesTmp.delete();
5263                    tracesFile.renameTo(tracesTmp);
5264                }
5265                StringBuilder sb = new StringBuilder();
5266                Time tobj = new Time();
5267                tobj.set(System.currentTimeMillis());
5268                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5269                sb.append(": ");
5270                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5271                sb.append(" since ");
5272                sb.append(msg);
5273                FileOutputStream fos = new FileOutputStream(tracesFile);
5274                fos.write(sb.toString().getBytes());
5275                if (app == null) {
5276                    fos.write("\n*** No application process!".getBytes());
5277                }
5278                fos.close();
5279                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5280            } catch (IOException e) {
5281                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5282                return;
5283            }
5284
5285            if (app != null) {
5286                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5287                firstPids.add(app.pid);
5288                dumpStackTraces(tracesPath, firstPids, null, null, null);
5289            }
5290
5291            File lastTracesFile = null;
5292            File curTracesFile = null;
5293            for (int i=9; i>=0; i--) {
5294                String name = String.format(Locale.US, "slow%02d.txt", i);
5295                curTracesFile = new File(tracesDir, name);
5296                if (curTracesFile.exists()) {
5297                    if (lastTracesFile != null) {
5298                        curTracesFile.renameTo(lastTracesFile);
5299                    } else {
5300                        curTracesFile.delete();
5301                    }
5302                }
5303                lastTracesFile = curTracesFile;
5304            }
5305            tracesFile.renameTo(curTracesFile);
5306            if (tracesTmp.exists()) {
5307                tracesTmp.renameTo(tracesFile);
5308            }
5309        } finally {
5310            StrictMode.setThreadPolicy(oldPolicy);
5311        }
5312    }
5313
5314    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5315        if (!mLaunchWarningShown) {
5316            mLaunchWarningShown = true;
5317            mUiHandler.post(new Runnable() {
5318                @Override
5319                public void run() {
5320                    synchronized (ActivityManagerService.this) {
5321                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5322                        d.show();
5323                        mUiHandler.postDelayed(new Runnable() {
5324                            @Override
5325                            public void run() {
5326                                synchronized (ActivityManagerService.this) {
5327                                    d.dismiss();
5328                                    mLaunchWarningShown = false;
5329                                }
5330                            }
5331                        }, 4000);
5332                    }
5333                }
5334            });
5335        }
5336    }
5337
5338    @Override
5339    public boolean clearApplicationUserData(final String packageName,
5340            final IPackageDataObserver observer, int userId) {
5341        enforceNotIsolatedCaller("clearApplicationUserData");
5342        int uid = Binder.getCallingUid();
5343        int pid = Binder.getCallingPid();
5344        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5345                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5346
5347        final DevicePolicyManagerInternal dpmi = LocalServices
5348                .getService(DevicePolicyManagerInternal.class);
5349        if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5350            throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5351        }
5352
5353        long callingId = Binder.clearCallingIdentity();
5354        try {
5355            IPackageManager pm = AppGlobals.getPackageManager();
5356            int pkgUid = -1;
5357            synchronized(this) {
5358                try {
5359                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5360                } catch (RemoteException e) {
5361                }
5362                if (pkgUid == -1) {
5363                    Slog.w(TAG, "Invalid packageName: " + packageName);
5364                    if (observer != null) {
5365                        try {
5366                            observer.onRemoveCompleted(packageName, false);
5367                        } catch (RemoteException e) {
5368                            Slog.i(TAG, "Observer no longer exists.");
5369                        }
5370                    }
5371                    return false;
5372                }
5373                if (uid == pkgUid || checkComponentPermission(
5374                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5375                        pid, uid, -1, true)
5376                        == PackageManager.PERMISSION_GRANTED) {
5377                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5378                } else {
5379                    throw new SecurityException("PID " + pid + " does not have permission "
5380                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5381                                    + " of package " + packageName);
5382                }
5383
5384                // Remove all tasks match the cleared application package and user
5385                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5386                    final TaskRecord tr = mRecentTasks.get(i);
5387                    final String taskPackageName =
5388                            tr.getBaseIntent().getComponent().getPackageName();
5389                    if (tr.userId != userId) continue;
5390                    if (!taskPackageName.equals(packageName)) continue;
5391                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5392                }
5393            }
5394
5395            try {
5396                // Clear application user data
5397                pm.clearApplicationUserData(packageName, observer, userId);
5398
5399                synchronized(this) {
5400                    // Remove all permissions granted from/to this package
5401                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5402                }
5403
5404                // Remove all zen rules created by this package; revoke it's zen access.
5405                INotificationManager inm = NotificationManager.getService();
5406                inm.removeAutomaticZenRules(packageName);
5407                inm.setNotificationPolicyAccessGranted(packageName, false);
5408
5409                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5410                        Uri.fromParts("package", packageName, null));
5411                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5412                intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5413                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5414                        null, null, 0, null, null, null, null, false, false, userId);
5415            } catch (RemoteException e) {
5416            }
5417        } finally {
5418            Binder.restoreCallingIdentity(callingId);
5419        }
5420        return true;
5421    }
5422
5423    @Override
5424    public void killBackgroundProcesses(final String packageName, int userId) {
5425        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5426                != PackageManager.PERMISSION_GRANTED &&
5427                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5428                        != PackageManager.PERMISSION_GRANTED) {
5429            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5430                    + Binder.getCallingPid()
5431                    + ", uid=" + Binder.getCallingUid()
5432                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5433            Slog.w(TAG, msg);
5434            throw new SecurityException(msg);
5435        }
5436
5437        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5438                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5439        long callingId = Binder.clearCallingIdentity();
5440        try {
5441            IPackageManager pm = AppGlobals.getPackageManager();
5442            synchronized(this) {
5443                int appId = -1;
5444                try {
5445                    appId = UserHandle.getAppId(
5446                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5447                } catch (RemoteException e) {
5448                }
5449                if (appId == -1) {
5450                    Slog.w(TAG, "Invalid packageName: " + packageName);
5451                    return;
5452                }
5453                killPackageProcessesLocked(packageName, appId, userId,
5454                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5455            }
5456        } finally {
5457            Binder.restoreCallingIdentity(callingId);
5458        }
5459    }
5460
5461    @Override
5462    public void killAllBackgroundProcesses() {
5463        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5464                != PackageManager.PERMISSION_GRANTED) {
5465            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5466                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5467                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5468            Slog.w(TAG, msg);
5469            throw new SecurityException(msg);
5470        }
5471
5472        final long callingId = Binder.clearCallingIdentity();
5473        try {
5474            synchronized (this) {
5475                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5476                final int NP = mProcessNames.getMap().size();
5477                for (int ip = 0; ip < NP; ip++) {
5478                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5479                    final int NA = apps.size();
5480                    for (int ia = 0; ia < NA; ia++) {
5481                        final ProcessRecord app = apps.valueAt(ia);
5482                        if (app.persistent) {
5483                            // We don't kill persistent processes.
5484                            continue;
5485                        }
5486                        if (app.removed) {
5487                            procs.add(app);
5488                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5489                            app.removed = true;
5490                            procs.add(app);
5491                        }
5492                    }
5493                }
5494
5495                final int N = procs.size();
5496                for (int i = 0; i < N; i++) {
5497                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5498                }
5499
5500                mAllowLowerMemLevel = true;
5501
5502                updateOomAdjLocked();
5503                doLowMemReportIfNeededLocked(null);
5504            }
5505        } finally {
5506            Binder.restoreCallingIdentity(callingId);
5507        }
5508    }
5509
5510    /**
5511     * Kills all background processes, except those matching any of the
5512     * specified properties.
5513     *
5514     * @param minTargetSdk the target SDK version at or above which to preserve
5515     *                     processes, or {@code -1} to ignore the target SDK
5516     * @param maxProcState the process state at or below which to preserve
5517     *                     processes, or {@code -1} to ignore the process state
5518     */
5519    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5520        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5521                != PackageManager.PERMISSION_GRANTED) {
5522            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5523                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5524                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5525            Slog.w(TAG, msg);
5526            throw new SecurityException(msg);
5527        }
5528
5529        final long callingId = Binder.clearCallingIdentity();
5530        try {
5531            synchronized (this) {
5532                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5533                final int NP = mProcessNames.getMap().size();
5534                for (int ip = 0; ip < NP; ip++) {
5535                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5536                    final int NA = apps.size();
5537                    for (int ia = 0; ia < NA; ia++) {
5538                        final ProcessRecord app = apps.valueAt(ia);
5539                        if (app.removed) {
5540                            procs.add(app);
5541                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5542                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5543                            app.removed = true;
5544                            procs.add(app);
5545                        }
5546                    }
5547                }
5548
5549                final int N = procs.size();
5550                for (int i = 0; i < N; i++) {
5551                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5552                }
5553            }
5554        } finally {
5555            Binder.restoreCallingIdentity(callingId);
5556        }
5557    }
5558
5559    @Override
5560    public void forceStopPackage(final String packageName, int userId) {
5561        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5562                != PackageManager.PERMISSION_GRANTED) {
5563            String msg = "Permission Denial: forceStopPackage() from pid="
5564                    + Binder.getCallingPid()
5565                    + ", uid=" + Binder.getCallingUid()
5566                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5567            Slog.w(TAG, msg);
5568            throw new SecurityException(msg);
5569        }
5570        final int callingPid = Binder.getCallingPid();
5571        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5572                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5573        long callingId = Binder.clearCallingIdentity();
5574        try {
5575            IPackageManager pm = AppGlobals.getPackageManager();
5576            synchronized(this) {
5577                int[] users = userId == UserHandle.USER_ALL
5578                        ? mUserController.getUsers() : new int[] { userId };
5579                for (int user : users) {
5580                    int pkgUid = -1;
5581                    try {
5582                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5583                                user);
5584                    } catch (RemoteException e) {
5585                    }
5586                    if (pkgUid == -1) {
5587                        Slog.w(TAG, "Invalid packageName: " + packageName);
5588                        continue;
5589                    }
5590                    try {
5591                        pm.setPackageStoppedState(packageName, true, user);
5592                    } catch (RemoteException e) {
5593                    } catch (IllegalArgumentException e) {
5594                        Slog.w(TAG, "Failed trying to unstop package "
5595                                + packageName + ": " + e);
5596                    }
5597                    if (mUserController.isUserRunningLocked(user, 0)) {
5598                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5599                    }
5600                }
5601            }
5602        } finally {
5603            Binder.restoreCallingIdentity(callingId);
5604        }
5605    }
5606
5607    @Override
5608    public void addPackageDependency(String packageName) {
5609        synchronized (this) {
5610            int callingPid = Binder.getCallingPid();
5611            if (callingPid == Process.myPid()) {
5612                //  Yeah, um, no.
5613                return;
5614            }
5615            ProcessRecord proc;
5616            synchronized (mPidsSelfLocked) {
5617                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5618            }
5619            if (proc != null) {
5620                if (proc.pkgDeps == null) {
5621                    proc.pkgDeps = new ArraySet<String>(1);
5622                }
5623                proc.pkgDeps.add(packageName);
5624            }
5625        }
5626    }
5627
5628    /*
5629     * The pkg name and app id have to be specified.
5630     */
5631    @Override
5632    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5633        if (pkg == null) {
5634            return;
5635        }
5636        // Make sure the uid is valid.
5637        if (appid < 0) {
5638            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5639            return;
5640        }
5641        int callerUid = Binder.getCallingUid();
5642        // Only the system server can kill an application
5643        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5644            // Post an aysnc message to kill the application
5645            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5646            msg.arg1 = appid;
5647            msg.arg2 = 0;
5648            Bundle bundle = new Bundle();
5649            bundle.putString("pkg", pkg);
5650            bundle.putString("reason", reason);
5651            msg.obj = bundle;
5652            mHandler.sendMessage(msg);
5653        } else {
5654            throw new SecurityException(callerUid + " cannot kill pkg: " +
5655                    pkg);
5656        }
5657    }
5658
5659    @Override
5660    public void closeSystemDialogs(String reason) {
5661        enforceNotIsolatedCaller("closeSystemDialogs");
5662
5663        final int pid = Binder.getCallingPid();
5664        final int uid = Binder.getCallingUid();
5665        final long origId = Binder.clearCallingIdentity();
5666        try {
5667            synchronized (this) {
5668                // Only allow this from foreground processes, so that background
5669                // applications can't abuse it to prevent system UI from being shown.
5670                if (uid >= Process.FIRST_APPLICATION_UID) {
5671                    ProcessRecord proc;
5672                    synchronized (mPidsSelfLocked) {
5673                        proc = mPidsSelfLocked.get(pid);
5674                    }
5675                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5676                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5677                                + " from background process " + proc);
5678                        return;
5679                    }
5680                }
5681                closeSystemDialogsLocked(reason);
5682            }
5683        } finally {
5684            Binder.restoreCallingIdentity(origId);
5685        }
5686    }
5687
5688    void closeSystemDialogsLocked(String reason) {
5689        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5690        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5691                | Intent.FLAG_RECEIVER_FOREGROUND);
5692        if (reason != null) {
5693            intent.putExtra("reason", reason);
5694        }
5695        mWindowManager.closeSystemDialogs(reason);
5696
5697        mStackSupervisor.closeSystemDialogsLocked();
5698
5699        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5700                AppOpsManager.OP_NONE, null, false, false,
5701                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5702    }
5703
5704    @Override
5705    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5706        enforceNotIsolatedCaller("getProcessMemoryInfo");
5707        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5708        for (int i=pids.length-1; i>=0; i--) {
5709            ProcessRecord proc;
5710            int oomAdj;
5711            synchronized (this) {
5712                synchronized (mPidsSelfLocked) {
5713                    proc = mPidsSelfLocked.get(pids[i]);
5714                    oomAdj = proc != null ? proc.setAdj : 0;
5715                }
5716            }
5717            infos[i] = new Debug.MemoryInfo();
5718            Debug.getMemoryInfo(pids[i], infos[i]);
5719            if (proc != null) {
5720                synchronized (this) {
5721                    if (proc.thread != null && proc.setAdj == oomAdj) {
5722                        // Record this for posterity if the process has been stable.
5723                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5724                                infos[i].getTotalUss(), false, proc.pkgList);
5725                    }
5726                }
5727            }
5728        }
5729        return infos;
5730    }
5731
5732    @Override
5733    public long[] getProcessPss(int[] pids) {
5734        enforceNotIsolatedCaller("getProcessPss");
5735        long[] pss = new long[pids.length];
5736        for (int i=pids.length-1; i>=0; i--) {
5737            ProcessRecord proc;
5738            int oomAdj;
5739            synchronized (this) {
5740                synchronized (mPidsSelfLocked) {
5741                    proc = mPidsSelfLocked.get(pids[i]);
5742                    oomAdj = proc != null ? proc.setAdj : 0;
5743                }
5744            }
5745            long[] tmpUss = new long[1];
5746            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5747            if (proc != null) {
5748                synchronized (this) {
5749                    if (proc.thread != null && proc.setAdj == oomAdj) {
5750                        // Record this for posterity if the process has been stable.
5751                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5752                    }
5753                }
5754            }
5755        }
5756        return pss;
5757    }
5758
5759    @Override
5760    public void killApplicationProcess(String processName, int uid) {
5761        if (processName == null) {
5762            return;
5763        }
5764
5765        int callerUid = Binder.getCallingUid();
5766        // Only the system server can kill an application
5767        if (callerUid == Process.SYSTEM_UID) {
5768            synchronized (this) {
5769                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5770                if (app != null && app.thread != null) {
5771                    try {
5772                        app.thread.scheduleSuicide();
5773                    } catch (RemoteException e) {
5774                        // If the other end already died, then our work here is done.
5775                    }
5776                } else {
5777                    Slog.w(TAG, "Process/uid not found attempting kill of "
5778                            + processName + " / " + uid);
5779                }
5780            }
5781        } else {
5782            throw new SecurityException(callerUid + " cannot kill app process: " +
5783                    processName);
5784        }
5785    }
5786
5787    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5788        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5789                false, true, false, false, UserHandle.getUserId(uid), reason);
5790        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5791                Uri.fromParts("package", packageName, null));
5792        if (!mProcessesReady) {
5793            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5794                    | Intent.FLAG_RECEIVER_FOREGROUND);
5795        }
5796        intent.putExtra(Intent.EXTRA_UID, uid);
5797        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5798        broadcastIntentLocked(null, null, intent,
5799                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5800                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5801    }
5802
5803
5804    private final boolean killPackageProcessesLocked(String packageName, int appId,
5805            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5806            boolean doit, boolean evenPersistent, String reason) {
5807        ArrayList<ProcessRecord> procs = new ArrayList<>();
5808
5809        // Remove all processes this package may have touched: all with the
5810        // same UID (except for the system or root user), and all whose name
5811        // matches the package name.
5812        final int NP = mProcessNames.getMap().size();
5813        for (int ip=0; ip<NP; ip++) {
5814            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5815            final int NA = apps.size();
5816            for (int ia=0; ia<NA; ia++) {
5817                ProcessRecord app = apps.valueAt(ia);
5818                if (app.persistent && !evenPersistent) {
5819                    // we don't kill persistent processes
5820                    continue;
5821                }
5822                if (app.removed) {
5823                    if (doit) {
5824                        procs.add(app);
5825                    }
5826                    continue;
5827                }
5828
5829                // Skip process if it doesn't meet our oom adj requirement.
5830                if (app.setAdj < minOomAdj) {
5831                    continue;
5832                }
5833
5834                // If no package is specified, we call all processes under the
5835                // give user id.
5836                if (packageName == null) {
5837                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5838                        continue;
5839                    }
5840                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5841                        continue;
5842                    }
5843                // Package has been specified, we want to hit all processes
5844                // that match it.  We need to qualify this by the processes
5845                // that are running under the specified app and user ID.
5846                } else {
5847                    final boolean isDep = app.pkgDeps != null
5848                            && app.pkgDeps.contains(packageName);
5849                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5850                        continue;
5851                    }
5852                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5853                        continue;
5854                    }
5855                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5856                        continue;
5857                    }
5858                }
5859
5860                // Process has passed all conditions, kill it!
5861                if (!doit) {
5862                    return true;
5863                }
5864                app.removed = true;
5865                procs.add(app);
5866            }
5867        }
5868
5869        int N = procs.size();
5870        for (int i=0; i<N; i++) {
5871            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5872        }
5873        updateOomAdjLocked();
5874        return N > 0;
5875    }
5876
5877    private void cleanupDisabledPackageComponentsLocked(
5878            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5879
5880        Set<String> disabledClasses = null;
5881        boolean packageDisabled = false;
5882        IPackageManager pm = AppGlobals.getPackageManager();
5883
5884        if (changedClasses == null) {
5885            // Nothing changed...
5886            return;
5887        }
5888
5889        // Determine enable/disable state of the package and its components.
5890        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5891        for (int i = changedClasses.length - 1; i >= 0; i--) {
5892            final String changedClass = changedClasses[i];
5893
5894            if (changedClass.equals(packageName)) {
5895                try {
5896                    // Entire package setting changed
5897                    enabled = pm.getApplicationEnabledSetting(packageName,
5898                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5899                } catch (Exception e) {
5900                    // No such package/component; probably racing with uninstall.  In any
5901                    // event it means we have nothing further to do here.
5902                    return;
5903                }
5904                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5905                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5906                if (packageDisabled) {
5907                    // Entire package is disabled.
5908                    // No need to continue to check component states.
5909                    disabledClasses = null;
5910                    break;
5911                }
5912            } else {
5913                try {
5914                    enabled = pm.getComponentEnabledSetting(
5915                            new ComponentName(packageName, changedClass),
5916                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5917                } catch (Exception e) {
5918                    // As above, probably racing with uninstall.
5919                    return;
5920                }
5921                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5922                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5923                    if (disabledClasses == null) {
5924                        disabledClasses = new ArraySet<>(changedClasses.length);
5925                    }
5926                    disabledClasses.add(changedClass);
5927                }
5928            }
5929        }
5930
5931        if (!packageDisabled && disabledClasses == null) {
5932            // Nothing to do here...
5933            return;
5934        }
5935
5936        // Clean-up disabled activities.
5937        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5938                packageName, disabledClasses, true, false, userId) && mBooted) {
5939            mStackSupervisor.resumeFocusedStackTopActivityLocked();
5940            mStackSupervisor.scheduleIdleLocked();
5941        }
5942
5943        // Clean-up disabled tasks
5944        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5945
5946        // Clean-up disabled services.
5947        mServices.bringDownDisabledPackageServicesLocked(
5948                packageName, disabledClasses, userId, false, killProcess, true);
5949
5950        // Clean-up disabled providers.
5951        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5952        mProviderMap.collectPackageProvidersLocked(
5953                packageName, disabledClasses, true, false, userId, providers);
5954        for (int i = providers.size() - 1; i >= 0; i--) {
5955            removeDyingProviderLocked(null, providers.get(i), true);
5956        }
5957
5958        // Clean-up disabled broadcast receivers.
5959        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5960            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5961                    packageName, disabledClasses, userId, true);
5962        }
5963
5964    }
5965
5966    final boolean clearBroadcastQueueForUserLocked(int userId) {
5967        boolean didSomething = false;
5968        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5969            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5970                    null, null, userId, true);
5971        }
5972        return didSomething;
5973    }
5974
5975    final boolean forceStopPackageLocked(String packageName, int appId,
5976            boolean callerWillRestart, boolean purgeCache, boolean doit,
5977            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5978        int i;
5979
5980        if (userId == UserHandle.USER_ALL && packageName == null) {
5981            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5982        }
5983
5984        if (appId < 0 && packageName != null) {
5985            try {
5986                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5987                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5988            } catch (RemoteException e) {
5989            }
5990        }
5991
5992        if (doit) {
5993            if (packageName != null) {
5994                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5995                        + " user=" + userId + ": " + reason);
5996            } else {
5997                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5998            }
5999
6000            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6001        }
6002
6003        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6004                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6005                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6006
6007        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6008                packageName, null, doit, evenPersistent, userId)) {
6009            if (!doit) {
6010                return true;
6011            }
6012            didSomething = true;
6013        }
6014
6015        if (mServices.bringDownDisabledPackageServicesLocked(
6016                packageName, null, userId, evenPersistent, true, doit)) {
6017            if (!doit) {
6018                return true;
6019            }
6020            didSomething = true;
6021        }
6022
6023        if (packageName == null) {
6024            // Remove all sticky broadcasts from this user.
6025            mStickyBroadcasts.remove(userId);
6026        }
6027
6028        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6029        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6030                userId, providers)) {
6031            if (!doit) {
6032                return true;
6033            }
6034            didSomething = true;
6035        }
6036        for (i = providers.size() - 1; i >= 0; i--) {
6037            removeDyingProviderLocked(null, providers.get(i), true);
6038        }
6039
6040        // Remove transient permissions granted from/to this package/user
6041        removeUriPermissionsForPackageLocked(packageName, userId, false);
6042
6043        if (doit) {
6044            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6045                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6046                        packageName, null, userId, doit);
6047            }
6048        }
6049
6050        if (packageName == null || uninstalling) {
6051            // Remove pending intents.  For now we only do this when force
6052            // stopping users, because we have some problems when doing this
6053            // for packages -- app widgets are not currently cleaned up for
6054            // such packages, so they can be left with bad pending intents.
6055            if (mIntentSenderRecords.size() > 0) {
6056                Iterator<WeakReference<PendingIntentRecord>> it
6057                        = mIntentSenderRecords.values().iterator();
6058                while (it.hasNext()) {
6059                    WeakReference<PendingIntentRecord> wpir = it.next();
6060                    if (wpir == null) {
6061                        it.remove();
6062                        continue;
6063                    }
6064                    PendingIntentRecord pir = wpir.get();
6065                    if (pir == null) {
6066                        it.remove();
6067                        continue;
6068                    }
6069                    if (packageName == null) {
6070                        // Stopping user, remove all objects for the user.
6071                        if (pir.key.userId != userId) {
6072                            // Not the same user, skip it.
6073                            continue;
6074                        }
6075                    } else {
6076                        if (UserHandle.getAppId(pir.uid) != appId) {
6077                            // Different app id, skip it.
6078                            continue;
6079                        }
6080                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6081                            // Different user, skip it.
6082                            continue;
6083                        }
6084                        if (!pir.key.packageName.equals(packageName)) {
6085                            // Different package, skip it.
6086                            continue;
6087                        }
6088                    }
6089                    if (!doit) {
6090                        return true;
6091                    }
6092                    didSomething = true;
6093                    it.remove();
6094                    pir.canceled = true;
6095                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6096                        pir.key.activity.pendingResults.remove(pir.ref);
6097                    }
6098                }
6099            }
6100        }
6101
6102        if (doit) {
6103            if (purgeCache && packageName != null) {
6104                AttributeCache ac = AttributeCache.instance();
6105                if (ac != null) {
6106                    ac.removePackage(packageName);
6107                }
6108            }
6109            if (mBooted) {
6110                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6111                mStackSupervisor.scheduleIdleLocked();
6112            }
6113        }
6114
6115        return didSomething;
6116    }
6117
6118    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6119        ProcessRecord old = mProcessNames.remove(name, uid);
6120        if (old != null) {
6121            old.uidRecord.numProcs--;
6122            if (old.uidRecord.numProcs == 0) {
6123                // No more processes using this uid, tell clients it is gone.
6124                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6125                        "No more processes in " + old.uidRecord);
6126                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6127                mActiveUids.remove(uid);
6128                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6129            }
6130            old.uidRecord = null;
6131        }
6132        mIsolatedProcesses.remove(uid);
6133        return old;
6134    }
6135
6136    private final void addProcessNameLocked(ProcessRecord proc) {
6137        // We shouldn't already have a process under this name, but just in case we
6138        // need to clean up whatever may be there now.
6139        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6140        if (old == proc && proc.persistent) {
6141            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6142            Slog.w(TAG, "Re-adding persistent process " + proc);
6143        } else if (old != null) {
6144            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6145        }
6146        UidRecord uidRec = mActiveUids.get(proc.uid);
6147        if (uidRec == null) {
6148            uidRec = new UidRecord(proc.uid);
6149            // This is the first appearance of the uid, report it now!
6150            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6151                    "Creating new process uid: " + uidRec);
6152            mActiveUids.put(proc.uid, uidRec);
6153            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6154            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6155        }
6156        proc.uidRecord = uidRec;
6157        uidRec.numProcs++;
6158        mProcessNames.put(proc.processName, proc.uid, proc);
6159        if (proc.isolated) {
6160            mIsolatedProcesses.put(proc.uid, proc);
6161        }
6162    }
6163
6164    boolean removeProcessLocked(ProcessRecord app,
6165            boolean callerWillRestart, boolean allowRestart, String reason) {
6166        final String name = app.processName;
6167        final int uid = app.uid;
6168        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6169            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6170
6171        ProcessRecord old = mProcessNames.get(name, uid);
6172        if (old != app) {
6173            // This process is no longer active, so nothing to do.
6174            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6175            return false;
6176        }
6177        removeProcessNameLocked(name, uid);
6178        if (mHeavyWeightProcess == app) {
6179            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6180                    mHeavyWeightProcess.userId, 0));
6181            mHeavyWeightProcess = null;
6182        }
6183        boolean needRestart = false;
6184        if (app.pid > 0 && app.pid != MY_PID) {
6185            int pid = app.pid;
6186            synchronized (mPidsSelfLocked) {
6187                mPidsSelfLocked.remove(pid);
6188                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6189            }
6190            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6191            if (app.isolated) {
6192                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6193            }
6194            boolean willRestart = false;
6195            if (app.persistent && !app.isolated) {
6196                if (!callerWillRestart) {
6197                    willRestart = true;
6198                } else {
6199                    needRestart = true;
6200                }
6201            }
6202            app.kill(reason, true);
6203            handleAppDiedLocked(app, willRestart, allowRestart);
6204            if (willRestart) {
6205                removeLruProcessLocked(app);
6206                addAppLocked(app.info, false, null /* ABI override */);
6207            }
6208        } else {
6209            mRemovedProcesses.add(app);
6210        }
6211
6212        return needRestart;
6213    }
6214
6215    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6216        cleanupAppInLaunchingProvidersLocked(app, true);
6217        removeProcessLocked(app, false, true, "timeout publishing content providers");
6218    }
6219
6220    private final void processStartTimedOutLocked(ProcessRecord app) {
6221        final int pid = app.pid;
6222        boolean gone = false;
6223        synchronized (mPidsSelfLocked) {
6224            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6225            if (knownApp != null && knownApp.thread == null) {
6226                mPidsSelfLocked.remove(pid);
6227                gone = true;
6228            }
6229        }
6230
6231        if (gone) {
6232            Slog.w(TAG, "Process " + app + " failed to attach");
6233            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6234                    pid, app.uid, app.processName);
6235            removeProcessNameLocked(app.processName, app.uid);
6236            if (mHeavyWeightProcess == app) {
6237                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6238                        mHeavyWeightProcess.userId, 0));
6239                mHeavyWeightProcess = null;
6240            }
6241            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6242            if (app.isolated) {
6243                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6244            }
6245            // Take care of any launching providers waiting for this process.
6246            cleanupAppInLaunchingProvidersLocked(app, true);
6247            // Take care of any services that are waiting for the process.
6248            mServices.processStartTimedOutLocked(app);
6249            app.kill("start timeout", true);
6250            removeLruProcessLocked(app);
6251            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6252                Slog.w(TAG, "Unattached app died before backup, skipping");
6253                try {
6254                    IBackupManager bm = IBackupManager.Stub.asInterface(
6255                            ServiceManager.getService(Context.BACKUP_SERVICE));
6256                    bm.agentDisconnected(app.info.packageName);
6257                } catch (RemoteException e) {
6258                    // Can't happen; the backup manager is local
6259                }
6260            }
6261            if (isPendingBroadcastProcessLocked(pid)) {
6262                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6263                skipPendingBroadcastLocked(pid);
6264            }
6265        } else {
6266            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6267        }
6268    }
6269
6270    private final boolean attachApplicationLocked(IApplicationThread thread,
6271            int pid) {
6272
6273        // Find the application record that is being attached...  either via
6274        // the pid if we are running in multiple processes, or just pull the
6275        // next app record if we are emulating process with anonymous threads.
6276        ProcessRecord app;
6277        if (pid != MY_PID && pid >= 0) {
6278            synchronized (mPidsSelfLocked) {
6279                app = mPidsSelfLocked.get(pid);
6280            }
6281        } else {
6282            app = null;
6283        }
6284
6285        if (app == null) {
6286            Slog.w(TAG, "No pending application record for pid " + pid
6287                    + " (IApplicationThread " + thread + "); dropping process");
6288            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6289            if (pid > 0 && pid != MY_PID) {
6290                Process.killProcessQuiet(pid);
6291                //TODO: killProcessGroup(app.info.uid, pid);
6292            } else {
6293                try {
6294                    thread.scheduleExit();
6295                } catch (Exception e) {
6296                    // Ignore exceptions.
6297                }
6298            }
6299            return false;
6300        }
6301
6302        // If this application record is still attached to a previous
6303        // process, clean it up now.
6304        if (app.thread != null) {
6305            handleAppDiedLocked(app, true, true);
6306        }
6307
6308        // Tell the process all about itself.
6309
6310        if (DEBUG_ALL) Slog.v(
6311                TAG, "Binding process pid " + pid + " to record " + app);
6312
6313        final String processName = app.processName;
6314        try {
6315            AppDeathRecipient adr = new AppDeathRecipient(
6316                    app, pid, thread);
6317            thread.asBinder().linkToDeath(adr, 0);
6318            app.deathRecipient = adr;
6319        } catch (RemoteException e) {
6320            app.resetPackageList(mProcessStats);
6321            startProcessLocked(app, "link fail", processName);
6322            return false;
6323        }
6324
6325        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6326
6327        app.makeActive(thread, mProcessStats);
6328        app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6329        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6330        app.forcingToForeground = null;
6331        updateProcessForegroundLocked(app, false, false);
6332        app.hasShownUi = false;
6333        app.debugging = false;
6334        app.cached = false;
6335        app.killedByAm = false;
6336
6337        // We carefully use the same state that PackageManager uses for
6338        // filtering, since we use this flag to decide if we need to install
6339        // providers when user is unlocked later
6340        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6341
6342        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6343
6344        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6345        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6346
6347        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6348            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6349            msg.obj = app;
6350            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6351        }
6352
6353        if (!normalMode) {
6354            Slog.i(TAG, "Launching preboot mode app: " + app);
6355        }
6356
6357        if (DEBUG_ALL) Slog.v(
6358            TAG, "New app record " + app
6359            + " thread=" + thread.asBinder() + " pid=" + pid);
6360        try {
6361            int testMode = IApplicationThread.DEBUG_OFF;
6362            if (mDebugApp != null && mDebugApp.equals(processName)) {
6363                testMode = mWaitForDebugger
6364                    ? IApplicationThread.DEBUG_WAIT
6365                    : IApplicationThread.DEBUG_ON;
6366                app.debugging = true;
6367                if (mDebugTransient) {
6368                    mDebugApp = mOrigDebugApp;
6369                    mWaitForDebugger = mOrigWaitForDebugger;
6370                }
6371            }
6372            String profileFile = app.instrumentationProfileFile;
6373            ParcelFileDescriptor profileFd = null;
6374            int samplingInterval = 0;
6375            boolean profileAutoStop = false;
6376            if (mProfileApp != null && mProfileApp.equals(processName)) {
6377                mProfileProc = app;
6378                profileFile = mProfileFile;
6379                profileFd = mProfileFd;
6380                samplingInterval = mSamplingInterval;
6381                profileAutoStop = mAutoStopProfiler;
6382            }
6383            boolean enableTrackAllocation = false;
6384            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6385                enableTrackAllocation = true;
6386                mTrackAllocationApp = null;
6387            }
6388
6389            // If the app is being launched for restore or full backup, set it up specially
6390            boolean isRestrictedBackupMode = false;
6391            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6392                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6393                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6394                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6395                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6396            }
6397
6398            if (app.instrumentationClass != null) {
6399                notifyPackageUse(app.instrumentationClass.getPackageName(),
6400                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6401            }
6402            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6403                    + processName + " with config " + mConfiguration);
6404            ApplicationInfo appInfo = app.instrumentationInfo != null
6405                    ? app.instrumentationInfo : app.info;
6406            app.compat = compatibilityInfoForPackageLocked(appInfo);
6407            if (profileFd != null) {
6408                profileFd = profileFd.dup();
6409            }
6410            ProfilerInfo profilerInfo = profileFile == null ? null
6411                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6412            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6413                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6414                    app.instrumentationUiAutomationConnection, testMode,
6415                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6416                    isRestrictedBackupMode || !normalMode, app.persistent,
6417                    new Configuration(mConfiguration), app.compat,
6418                    getCommonServicesLocked(app.isolated),
6419                    mCoreSettingsObserver.getCoreSettingsLocked());
6420            updateLruProcessLocked(app, false, null);
6421            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6422        } catch (Exception e) {
6423            // todo: Yikes!  What should we do?  For now we will try to
6424            // start another process, but that could easily get us in
6425            // an infinite loop of restarting processes...
6426            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6427
6428            app.resetPackageList(mProcessStats);
6429            app.unlinkDeathRecipient();
6430            startProcessLocked(app, "bind fail", processName);
6431            return false;
6432        }
6433
6434        // Remove this record from the list of starting applications.
6435        mPersistentStartingProcesses.remove(app);
6436        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6437                "Attach application locked removing on hold: " + app);
6438        mProcessesOnHold.remove(app);
6439
6440        boolean badApp = false;
6441        boolean didSomething = false;
6442
6443        // See if the top visible activity is waiting to run in this process...
6444        if (normalMode) {
6445            try {
6446                if (mStackSupervisor.attachApplicationLocked(app)) {
6447                    didSomething = true;
6448                }
6449            } catch (Exception e) {
6450                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6451                badApp = true;
6452            }
6453        }
6454
6455        // Find any services that should be running in this process...
6456        if (!badApp) {
6457            try {
6458                didSomething |= mServices.attachApplicationLocked(app, processName);
6459            } catch (Exception e) {
6460                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6461                badApp = true;
6462            }
6463        }
6464
6465        // Check if a next-broadcast receiver is in this process...
6466        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6467            try {
6468                didSomething |= sendPendingBroadcastsLocked(app);
6469            } catch (Exception e) {
6470                // If the app died trying to launch the receiver we declare it 'bad'
6471                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6472                badApp = true;
6473            }
6474        }
6475
6476        // Check whether the next backup agent is in this process...
6477        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6478            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6479                    "New app is backup target, launching agent for " + app);
6480            notifyPackageUse(mBackupTarget.appInfo.packageName,
6481                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6482            try {
6483                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6484                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6485                        mBackupTarget.backupMode);
6486            } catch (Exception e) {
6487                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6488                badApp = true;
6489            }
6490        }
6491
6492        if (badApp) {
6493            app.kill("error during init", true);
6494            handleAppDiedLocked(app, false, true);
6495            return false;
6496        }
6497
6498        if (!didSomething) {
6499            updateOomAdjLocked();
6500        }
6501
6502        return true;
6503    }
6504
6505    @Override
6506    public final void attachApplication(IApplicationThread thread) {
6507        synchronized (this) {
6508            int callingPid = Binder.getCallingPid();
6509            final long origId = Binder.clearCallingIdentity();
6510            attachApplicationLocked(thread, callingPid);
6511            Binder.restoreCallingIdentity(origId);
6512        }
6513    }
6514
6515    @Override
6516    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6517        final long origId = Binder.clearCallingIdentity();
6518        synchronized (this) {
6519            ActivityStack stack = ActivityRecord.getStackLocked(token);
6520            if (stack != null) {
6521                ActivityRecord r =
6522                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6523                if (stopProfiling) {
6524                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6525                        try {
6526                            mProfileFd.close();
6527                        } catch (IOException e) {
6528                        }
6529                        clearProfilerLocked();
6530                    }
6531                }
6532            }
6533        }
6534        Binder.restoreCallingIdentity(origId);
6535    }
6536
6537    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6538        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6539                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6540    }
6541
6542    void enableScreenAfterBoot() {
6543        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6544                SystemClock.uptimeMillis());
6545        mWindowManager.enableScreenAfterBoot();
6546
6547        synchronized (this) {
6548            updateEventDispatchingLocked();
6549        }
6550    }
6551
6552    @Override
6553    public void showBootMessage(final CharSequence msg, final boolean always) {
6554        if (Binder.getCallingUid() != Process.myUid()) {
6555            // These days only the core system can call this, so apps can't get in
6556            // the way of what we show about running them.
6557        }
6558        mWindowManager.showBootMessage(msg, always);
6559    }
6560
6561    @Override
6562    public void keyguardWaitingForActivityDrawn() {
6563        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6564        final long token = Binder.clearCallingIdentity();
6565        try {
6566            synchronized (this) {
6567                if (DEBUG_LOCKSCREEN) logLockScreen("");
6568                mWindowManager.keyguardWaitingForActivityDrawn();
6569                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6570                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6571                    updateSleepIfNeededLocked();
6572                }
6573            }
6574        } finally {
6575            Binder.restoreCallingIdentity(token);
6576        }
6577    }
6578
6579    @Override
6580    public void keyguardGoingAway(int flags) {
6581        enforceNotIsolatedCaller("keyguardGoingAway");
6582        final long token = Binder.clearCallingIdentity();
6583        try {
6584            synchronized (this) {
6585                if (DEBUG_LOCKSCREEN) logLockScreen("");
6586                mWindowManager.keyguardGoingAway(flags);
6587                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6588                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6589                    updateSleepIfNeededLocked();
6590
6591                    // Some stack visibility might change (e.g. docked stack)
6592                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6593                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6594                }
6595            }
6596        } finally {
6597            Binder.restoreCallingIdentity(token);
6598        }
6599    }
6600
6601    final void finishBooting() {
6602        synchronized (this) {
6603            if (!mBootAnimationComplete) {
6604                mCallFinishBooting = true;
6605                return;
6606            }
6607            mCallFinishBooting = false;
6608        }
6609
6610        ArraySet<String> completedIsas = new ArraySet<String>();
6611        for (String abi : Build.SUPPORTED_ABIS) {
6612            Process.establishZygoteConnectionForAbi(abi);
6613            final String instructionSet = VMRuntime.getInstructionSet(abi);
6614            if (!completedIsas.contains(instructionSet)) {
6615                try {
6616                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6617                } catch (InstallerException e) {
6618                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6619                            e.getMessage() +")");
6620                }
6621                completedIsas.add(instructionSet);
6622            }
6623        }
6624
6625        IntentFilter pkgFilter = new IntentFilter();
6626        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6627        pkgFilter.addDataScheme("package");
6628        mContext.registerReceiver(new BroadcastReceiver() {
6629            @Override
6630            public void onReceive(Context context, Intent intent) {
6631                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6632                if (pkgs != null) {
6633                    for (String pkg : pkgs) {
6634                        synchronized (ActivityManagerService.this) {
6635                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6636                                    0, "query restart")) {
6637                                setResultCode(Activity.RESULT_OK);
6638                                return;
6639                            }
6640                        }
6641                    }
6642                }
6643            }
6644        }, pkgFilter);
6645
6646        IntentFilter dumpheapFilter = new IntentFilter();
6647        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6648        mContext.registerReceiver(new BroadcastReceiver() {
6649            @Override
6650            public void onReceive(Context context, Intent intent) {
6651                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6652                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6653                } else {
6654                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6655                }
6656            }
6657        }, dumpheapFilter);
6658
6659        // Let system services know.
6660        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6661
6662        synchronized (this) {
6663            // Ensure that any processes we had put on hold are now started
6664            // up.
6665            final int NP = mProcessesOnHold.size();
6666            if (NP > 0) {
6667                ArrayList<ProcessRecord> procs =
6668                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6669                for (int ip=0; ip<NP; ip++) {
6670                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6671                            + procs.get(ip));
6672                    startProcessLocked(procs.get(ip), "on-hold", null);
6673                }
6674            }
6675
6676            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6677                // Start looking for apps that are abusing wake locks.
6678                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6679                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6680                // Tell anyone interested that we are done booting!
6681                SystemProperties.set("sys.boot_completed", "1");
6682
6683                // And trigger dev.bootcomplete if we are not showing encryption progress
6684                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6685                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6686                    SystemProperties.set("dev.bootcomplete", "1");
6687                }
6688                mUserController.sendBootCompletedLocked(
6689                        new IIntentReceiver.Stub() {
6690                            @Override
6691                            public void performReceive(Intent intent, int resultCode,
6692                                    String data, Bundle extras, boolean ordered,
6693                                    boolean sticky, int sendingUser) {
6694                                synchronized (ActivityManagerService.this) {
6695                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6696                                            true, false);
6697                                }
6698                            }
6699                        });
6700                scheduleStartProfilesLocked();
6701            }
6702        }
6703    }
6704
6705    @Override
6706    public void bootAnimationComplete() {
6707        final boolean callFinishBooting;
6708        synchronized (this) {
6709            callFinishBooting = mCallFinishBooting;
6710            mBootAnimationComplete = true;
6711        }
6712        if (callFinishBooting) {
6713            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6714            finishBooting();
6715            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6716        }
6717    }
6718
6719    final void ensureBootCompleted() {
6720        boolean booting;
6721        boolean enableScreen;
6722        synchronized (this) {
6723            booting = mBooting;
6724            mBooting = false;
6725            enableScreen = !mBooted;
6726            mBooted = true;
6727        }
6728
6729        if (booting) {
6730            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6731            finishBooting();
6732            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6733        }
6734
6735        if (enableScreen) {
6736            enableScreenAfterBoot();
6737        }
6738    }
6739
6740    @Override
6741    public final void activityResumed(IBinder token) {
6742        final long origId = Binder.clearCallingIdentity();
6743        synchronized(this) {
6744            ActivityStack stack = ActivityRecord.getStackLocked(token);
6745            if (stack != null) {
6746                stack.activityResumedLocked(token);
6747            }
6748        }
6749        Binder.restoreCallingIdentity(origId);
6750    }
6751
6752    @Override
6753    public final void activityPaused(IBinder token) {
6754        final long origId = Binder.clearCallingIdentity();
6755        synchronized(this) {
6756            ActivityStack stack = ActivityRecord.getStackLocked(token);
6757            if (stack != null) {
6758                stack.activityPausedLocked(token, false);
6759            }
6760        }
6761        Binder.restoreCallingIdentity(origId);
6762    }
6763
6764    @Override
6765    public final void activityStopped(IBinder token, Bundle icicle,
6766            PersistableBundle persistentState, CharSequence description) {
6767        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6768
6769        // Refuse possible leaked file descriptors
6770        if (icicle != null && icicle.hasFileDescriptors()) {
6771            throw new IllegalArgumentException("File descriptors passed in Bundle");
6772        }
6773
6774        final long origId = Binder.clearCallingIdentity();
6775
6776        synchronized (this) {
6777            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6778            if (r != null) {
6779                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6780            }
6781        }
6782
6783        trimApplications();
6784
6785        Binder.restoreCallingIdentity(origId);
6786    }
6787
6788    @Override
6789    public final void activityDestroyed(IBinder token) {
6790        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6791        synchronized (this) {
6792            ActivityStack stack = ActivityRecord.getStackLocked(token);
6793            if (stack != null) {
6794                stack.activityDestroyedLocked(token, "activityDestroyed");
6795            }
6796        }
6797    }
6798
6799    @Override
6800    public final void activityRelaunched(IBinder token) {
6801        final long origId = Binder.clearCallingIdentity();
6802        synchronized (this) {
6803            mStackSupervisor.activityRelaunchedLocked(token);
6804        }
6805        Binder.restoreCallingIdentity(origId);
6806    }
6807
6808    @Override
6809    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6810            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6811        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6812                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6813        synchronized (this) {
6814            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6815            if (record == null) {
6816                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6817                        + "found for: " + token);
6818            }
6819            record.setSizeConfigurations(horizontalSizeConfiguration,
6820                    verticalSizeConfigurations, smallestSizeConfigurations);
6821        }
6822    }
6823
6824    @Override
6825    public final void backgroundResourcesReleased(IBinder token) {
6826        final long origId = Binder.clearCallingIdentity();
6827        try {
6828            synchronized (this) {
6829                ActivityStack stack = ActivityRecord.getStackLocked(token);
6830                if (stack != null) {
6831                    stack.backgroundResourcesReleased();
6832                }
6833            }
6834        } finally {
6835            Binder.restoreCallingIdentity(origId);
6836        }
6837    }
6838
6839    @Override
6840    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6841        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6842    }
6843
6844    @Override
6845    public final void notifyEnterAnimationComplete(IBinder token) {
6846        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6847    }
6848
6849    @Override
6850    public String getCallingPackage(IBinder token) {
6851        synchronized (this) {
6852            ActivityRecord r = getCallingRecordLocked(token);
6853            return r != null ? r.info.packageName : null;
6854        }
6855    }
6856
6857    @Override
6858    public ComponentName getCallingActivity(IBinder token) {
6859        synchronized (this) {
6860            ActivityRecord r = getCallingRecordLocked(token);
6861            return r != null ? r.intent.getComponent() : null;
6862        }
6863    }
6864
6865    private ActivityRecord getCallingRecordLocked(IBinder token) {
6866        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6867        if (r == null) {
6868            return null;
6869        }
6870        return r.resultTo;
6871    }
6872
6873    @Override
6874    public ComponentName getActivityClassForToken(IBinder token) {
6875        synchronized(this) {
6876            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6877            if (r == null) {
6878                return null;
6879            }
6880            return r.intent.getComponent();
6881        }
6882    }
6883
6884    @Override
6885    public String getPackageForToken(IBinder token) {
6886        synchronized(this) {
6887            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6888            if (r == null) {
6889                return null;
6890            }
6891            return r.packageName;
6892        }
6893    }
6894
6895    @Override
6896    public boolean isRootVoiceInteraction(IBinder token) {
6897        synchronized(this) {
6898            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6899            if (r == null) {
6900                return false;
6901            }
6902            return r.rootVoiceInteraction;
6903        }
6904    }
6905
6906    @Override
6907    public IIntentSender getIntentSender(int type,
6908            String packageName, IBinder token, String resultWho,
6909            int requestCode, Intent[] intents, String[] resolvedTypes,
6910            int flags, Bundle bOptions, int userId) {
6911        enforceNotIsolatedCaller("getIntentSender");
6912        // Refuse possible leaked file descriptors
6913        if (intents != null) {
6914            if (intents.length < 1) {
6915                throw new IllegalArgumentException("Intents array length must be >= 1");
6916            }
6917            for (int i=0; i<intents.length; i++) {
6918                Intent intent = intents[i];
6919                if (intent != null) {
6920                    if (intent.hasFileDescriptors()) {
6921                        throw new IllegalArgumentException("File descriptors passed in Intent");
6922                    }
6923                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6924                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6925                        throw new IllegalArgumentException(
6926                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6927                    }
6928                    intents[i] = new Intent(intent);
6929                }
6930            }
6931            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6932                throw new IllegalArgumentException(
6933                        "Intent array length does not match resolvedTypes length");
6934            }
6935        }
6936        if (bOptions != null) {
6937            if (bOptions.hasFileDescriptors()) {
6938                throw new IllegalArgumentException("File descriptors passed in options");
6939            }
6940        }
6941
6942        synchronized(this) {
6943            int callingUid = Binder.getCallingUid();
6944            int origUserId = userId;
6945            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6946                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6947                    ALLOW_NON_FULL, "getIntentSender", null);
6948            if (origUserId == UserHandle.USER_CURRENT) {
6949                // We don't want to evaluate this until the pending intent is
6950                // actually executed.  However, we do want to always do the
6951                // security checking for it above.
6952                userId = UserHandle.USER_CURRENT;
6953            }
6954            try {
6955                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6956                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6957                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6958                    if (!UserHandle.isSameApp(callingUid, uid)) {
6959                        String msg = "Permission Denial: getIntentSender() from pid="
6960                            + Binder.getCallingPid()
6961                            + ", uid=" + Binder.getCallingUid()
6962                            + ", (need uid=" + uid + ")"
6963                            + " is not allowed to send as package " + packageName;
6964                        Slog.w(TAG, msg);
6965                        throw new SecurityException(msg);
6966                    }
6967                }
6968
6969                return getIntentSenderLocked(type, packageName, callingUid, userId,
6970                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6971
6972            } catch (RemoteException e) {
6973                throw new SecurityException(e);
6974            }
6975        }
6976    }
6977
6978    IIntentSender getIntentSenderLocked(int type, String packageName,
6979            int callingUid, int userId, IBinder token, String resultWho,
6980            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6981            Bundle bOptions) {
6982        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6983        ActivityRecord activity = null;
6984        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6985            activity = ActivityRecord.isInStackLocked(token);
6986            if (activity == null) {
6987                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6988                return null;
6989            }
6990            if (activity.finishing) {
6991                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6992                return null;
6993            }
6994        }
6995
6996        // We're going to be splicing together extras before sending, so we're
6997        // okay poking into any contained extras.
6998        if (intents != null) {
6999            for (int i = 0; i < intents.length; i++) {
7000                intents[i].setDefusable(true);
7001            }
7002        }
7003        Bundle.setDefusable(bOptions, true);
7004
7005        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7006        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7007        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7008        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7009                |PendingIntent.FLAG_UPDATE_CURRENT);
7010
7011        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7012                type, packageName, activity, resultWho,
7013                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7014        WeakReference<PendingIntentRecord> ref;
7015        ref = mIntentSenderRecords.get(key);
7016        PendingIntentRecord rec = ref != null ? ref.get() : null;
7017        if (rec != null) {
7018            if (!cancelCurrent) {
7019                if (updateCurrent) {
7020                    if (rec.key.requestIntent != null) {
7021                        rec.key.requestIntent.replaceExtras(intents != null ?
7022                                intents[intents.length - 1] : null);
7023                    }
7024                    if (intents != null) {
7025                        intents[intents.length-1] = rec.key.requestIntent;
7026                        rec.key.allIntents = intents;
7027                        rec.key.allResolvedTypes = resolvedTypes;
7028                    } else {
7029                        rec.key.allIntents = null;
7030                        rec.key.allResolvedTypes = null;
7031                    }
7032                }
7033                return rec;
7034            }
7035            rec.canceled = true;
7036            mIntentSenderRecords.remove(key);
7037        }
7038        if (noCreate) {
7039            return rec;
7040        }
7041        rec = new PendingIntentRecord(this, key, callingUid);
7042        mIntentSenderRecords.put(key, rec.ref);
7043        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7044            if (activity.pendingResults == null) {
7045                activity.pendingResults
7046                        = new HashSet<WeakReference<PendingIntentRecord>>();
7047            }
7048            activity.pendingResults.add(rec.ref);
7049        }
7050        return rec;
7051    }
7052
7053    @Override
7054    public void cancelIntentSender(IIntentSender sender) {
7055        if (!(sender instanceof PendingIntentRecord)) {
7056            return;
7057        }
7058        synchronized(this) {
7059            PendingIntentRecord rec = (PendingIntentRecord)sender;
7060            try {
7061                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7062                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7063                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7064                    String msg = "Permission Denial: cancelIntentSender() from pid="
7065                        + Binder.getCallingPid()
7066                        + ", uid=" + Binder.getCallingUid()
7067                        + " is not allowed to cancel packges "
7068                        + rec.key.packageName;
7069                    Slog.w(TAG, msg);
7070                    throw new SecurityException(msg);
7071                }
7072            } catch (RemoteException e) {
7073                throw new SecurityException(e);
7074            }
7075            cancelIntentSenderLocked(rec, true);
7076        }
7077    }
7078
7079    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7080        rec.canceled = true;
7081        mIntentSenderRecords.remove(rec.key);
7082        if (cleanActivity && rec.key.activity != null) {
7083            rec.key.activity.pendingResults.remove(rec.ref);
7084        }
7085    }
7086
7087    @Override
7088    public String getPackageForIntentSender(IIntentSender pendingResult) {
7089        if (!(pendingResult instanceof PendingIntentRecord)) {
7090            return null;
7091        }
7092        try {
7093            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7094            return res.key.packageName;
7095        } catch (ClassCastException e) {
7096        }
7097        return null;
7098    }
7099
7100    @Override
7101    public int getUidForIntentSender(IIntentSender sender) {
7102        if (sender instanceof PendingIntentRecord) {
7103            try {
7104                PendingIntentRecord res = (PendingIntentRecord)sender;
7105                return res.uid;
7106            } catch (ClassCastException e) {
7107            }
7108        }
7109        return -1;
7110    }
7111
7112    @Override
7113    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7114        if (!(pendingResult instanceof PendingIntentRecord)) {
7115            return false;
7116        }
7117        try {
7118            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7119            if (res.key.allIntents == null) {
7120                return false;
7121            }
7122            for (int i=0; i<res.key.allIntents.length; i++) {
7123                Intent intent = res.key.allIntents[i];
7124                if (intent.getPackage() != null && intent.getComponent() != null) {
7125                    return false;
7126                }
7127            }
7128            return true;
7129        } catch (ClassCastException e) {
7130        }
7131        return false;
7132    }
7133
7134    @Override
7135    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7136        if (!(pendingResult instanceof PendingIntentRecord)) {
7137            return false;
7138        }
7139        try {
7140            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7141            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7142                return true;
7143            }
7144            return false;
7145        } catch (ClassCastException e) {
7146        }
7147        return false;
7148    }
7149
7150    @Override
7151    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7152        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7153                "getIntentForIntentSender()");
7154        if (!(pendingResult instanceof PendingIntentRecord)) {
7155            return null;
7156        }
7157        try {
7158            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7159            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7160        } catch (ClassCastException e) {
7161        }
7162        return null;
7163    }
7164
7165    @Override
7166    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7167        if (!(pendingResult instanceof PendingIntentRecord)) {
7168            return null;
7169        }
7170        try {
7171            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7172            synchronized (this) {
7173                return getTagForIntentSenderLocked(res, prefix);
7174            }
7175        } catch (ClassCastException e) {
7176        }
7177        return null;
7178    }
7179
7180    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7181        final Intent intent = res.key.requestIntent;
7182        if (intent != null) {
7183            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7184                    || res.lastTagPrefix.equals(prefix))) {
7185                return res.lastTag;
7186            }
7187            res.lastTagPrefix = prefix;
7188            final StringBuilder sb = new StringBuilder(128);
7189            if (prefix != null) {
7190                sb.append(prefix);
7191            }
7192            if (intent.getAction() != null) {
7193                sb.append(intent.getAction());
7194            } else if (intent.getComponent() != null) {
7195                intent.getComponent().appendShortString(sb);
7196            } else {
7197                sb.append("?");
7198            }
7199            return res.lastTag = sb.toString();
7200        }
7201        return null;
7202    }
7203
7204    @Override
7205    public void setProcessLimit(int max) {
7206        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7207                "setProcessLimit()");
7208        synchronized (this) {
7209            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7210            mProcessLimitOverride = max;
7211        }
7212        trimApplications();
7213    }
7214
7215    @Override
7216    public int getProcessLimit() {
7217        synchronized (this) {
7218            return mProcessLimitOverride;
7219        }
7220    }
7221
7222    void foregroundTokenDied(ForegroundToken token) {
7223        synchronized (ActivityManagerService.this) {
7224            synchronized (mPidsSelfLocked) {
7225                ForegroundToken cur
7226                    = mForegroundProcesses.get(token.pid);
7227                if (cur != token) {
7228                    return;
7229                }
7230                mForegroundProcesses.remove(token.pid);
7231                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7232                if (pr == null) {
7233                    return;
7234                }
7235                pr.forcingToForeground = null;
7236                updateProcessForegroundLocked(pr, false, false);
7237            }
7238            updateOomAdjLocked();
7239        }
7240    }
7241
7242    @Override
7243    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7244        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7245                "setProcessForeground()");
7246        synchronized(this) {
7247            boolean changed = false;
7248
7249            synchronized (mPidsSelfLocked) {
7250                ProcessRecord pr = mPidsSelfLocked.get(pid);
7251                if (pr == null && isForeground) {
7252                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7253                    return;
7254                }
7255                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7256                if (oldToken != null) {
7257                    oldToken.token.unlinkToDeath(oldToken, 0);
7258                    mForegroundProcesses.remove(pid);
7259                    if (pr != null) {
7260                        pr.forcingToForeground = null;
7261                    }
7262                    changed = true;
7263                }
7264                if (isForeground && token != null) {
7265                    ForegroundToken newToken = new ForegroundToken() {
7266                        @Override
7267                        public void binderDied() {
7268                            foregroundTokenDied(this);
7269                        }
7270                    };
7271                    newToken.pid = pid;
7272                    newToken.token = token;
7273                    try {
7274                        token.linkToDeath(newToken, 0);
7275                        mForegroundProcesses.put(pid, newToken);
7276                        pr.forcingToForeground = token;
7277                        changed = true;
7278                    } catch (RemoteException e) {
7279                        // If the process died while doing this, we will later
7280                        // do the cleanup with the process death link.
7281                    }
7282                }
7283            }
7284
7285            if (changed) {
7286                updateOomAdjLocked();
7287            }
7288        }
7289    }
7290
7291    @Override
7292    public boolean isAppForeground(int uid) throws RemoteException {
7293        synchronized (this) {
7294            UidRecord uidRec = mActiveUids.get(uid);
7295            if (uidRec == null || uidRec.idle) {
7296                return false;
7297            }
7298            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7299        }
7300    }
7301
7302    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7303    // be guarded by permission checking.
7304    int getUidState(int uid) {
7305        synchronized (this) {
7306            UidRecord uidRec = mActiveUids.get(uid);
7307            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7308        }
7309    }
7310
7311    @Override
7312    public boolean isInMultiWindowMode(IBinder token) {
7313        final long origId = Binder.clearCallingIdentity();
7314        try {
7315            synchronized(this) {
7316                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7317                if (r == null) {
7318                    return false;
7319                }
7320                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7321                return !r.task.mFullscreen;
7322            }
7323        } finally {
7324            Binder.restoreCallingIdentity(origId);
7325        }
7326    }
7327
7328    @Override
7329    public boolean isInPictureInPictureMode(IBinder token) {
7330        final long origId = Binder.clearCallingIdentity();
7331        try {
7332            synchronized(this) {
7333                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7334                if (stack == null) {
7335                    return false;
7336                }
7337                return stack.mStackId == PINNED_STACK_ID;
7338            }
7339        } finally {
7340            Binder.restoreCallingIdentity(origId);
7341        }
7342    }
7343
7344    @Override
7345    public void enterPictureInPictureMode(IBinder token) {
7346        final long origId = Binder.clearCallingIdentity();
7347        try {
7348            synchronized(this) {
7349                if (!mSupportsPictureInPicture) {
7350                    throw new IllegalStateException("enterPictureInPictureMode: "
7351                            + "Device doesn't support picture-in-picture mode.");
7352                }
7353
7354                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7355
7356                if (r == null) {
7357                    throw new IllegalStateException("enterPictureInPictureMode: "
7358                            + "Can't find activity for token=" + token);
7359                }
7360
7361                if (!r.supportsPictureInPicture()) {
7362                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7363                            + "Picture-In-Picture not supported for r=" + r);
7364                }
7365
7366                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7367                // current bounds.
7368                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7369                final Rect bounds = (pinnedStack != null)
7370                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7371
7372                mStackSupervisor.moveActivityToPinnedStackLocked(
7373                        r, "enterPictureInPictureMode", bounds);
7374            }
7375        } finally {
7376            Binder.restoreCallingIdentity(origId);
7377        }
7378    }
7379
7380    // =========================================================
7381    // PROCESS INFO
7382    // =========================================================
7383
7384    static class ProcessInfoService extends IProcessInfoService.Stub {
7385        final ActivityManagerService mActivityManagerService;
7386        ProcessInfoService(ActivityManagerService activityManagerService) {
7387            mActivityManagerService = activityManagerService;
7388        }
7389
7390        @Override
7391        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7392            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7393                    /*in*/ pids, /*out*/ states, null);
7394        }
7395
7396        @Override
7397        public void getProcessStatesAndOomScoresFromPids(
7398                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7399            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7400                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7401        }
7402    }
7403
7404    /**
7405     * For each PID in the given input array, write the current process state
7406     * for that process into the states array, or -1 to indicate that no
7407     * process with the given PID exists. If scores array is provided, write
7408     * the oom score for the process into the scores array, with INVALID_ADJ
7409     * indicating the PID doesn't exist.
7410     */
7411    public void getProcessStatesAndOomScoresForPIDs(
7412            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7413        if (scores != null) {
7414            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7415                    "getProcessStatesAndOomScoresForPIDs()");
7416        }
7417
7418        if (pids == null) {
7419            throw new NullPointerException("pids");
7420        } else if (states == null) {
7421            throw new NullPointerException("states");
7422        } else if (pids.length != states.length) {
7423            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7424        } else if (scores != null && pids.length != scores.length) {
7425            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7426        }
7427
7428        synchronized (mPidsSelfLocked) {
7429            for (int i = 0; i < pids.length; i++) {
7430                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7431                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7432                        pr.curProcState;
7433                if (scores != null) {
7434                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7435                }
7436            }
7437        }
7438    }
7439
7440    // =========================================================
7441    // PERMISSIONS
7442    // =========================================================
7443
7444    static class PermissionController extends IPermissionController.Stub {
7445        ActivityManagerService mActivityManagerService;
7446        PermissionController(ActivityManagerService activityManagerService) {
7447            mActivityManagerService = activityManagerService;
7448        }
7449
7450        @Override
7451        public boolean checkPermission(String permission, int pid, int uid) {
7452            return mActivityManagerService.checkPermission(permission, pid,
7453                    uid) == PackageManager.PERMISSION_GRANTED;
7454        }
7455
7456        @Override
7457        public String[] getPackagesForUid(int uid) {
7458            return mActivityManagerService.mContext.getPackageManager()
7459                    .getPackagesForUid(uid);
7460        }
7461
7462        @Override
7463        public boolean isRuntimePermission(String permission) {
7464            try {
7465                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7466                        .getPermissionInfo(permission, 0);
7467                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7468            } catch (NameNotFoundException nnfe) {
7469                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7470            }
7471            return false;
7472        }
7473    }
7474
7475    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7476        @Override
7477        public int checkComponentPermission(String permission, int pid, int uid,
7478                int owningUid, boolean exported) {
7479            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7480                    owningUid, exported);
7481        }
7482
7483        @Override
7484        public Object getAMSLock() {
7485            return ActivityManagerService.this;
7486        }
7487    }
7488
7489    /**
7490     * This can be called with or without the global lock held.
7491     */
7492    int checkComponentPermission(String permission, int pid, int uid,
7493            int owningUid, boolean exported) {
7494        if (pid == MY_PID) {
7495            return PackageManager.PERMISSION_GRANTED;
7496        }
7497        return ActivityManager.checkComponentPermission(permission, uid,
7498                owningUid, exported);
7499    }
7500
7501    /**
7502     * As the only public entry point for permissions checking, this method
7503     * can enforce the semantic that requesting a check on a null global
7504     * permission is automatically denied.  (Internally a null permission
7505     * string is used when calling {@link #checkComponentPermission} in cases
7506     * when only uid-based security is needed.)
7507     *
7508     * This can be called with or without the global lock held.
7509     */
7510    @Override
7511    public int checkPermission(String permission, int pid, int uid) {
7512        if (permission == null) {
7513            return PackageManager.PERMISSION_DENIED;
7514        }
7515        return checkComponentPermission(permission, pid, uid, -1, true);
7516    }
7517
7518    @Override
7519    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7520        if (permission == null) {
7521            return PackageManager.PERMISSION_DENIED;
7522        }
7523
7524        // We might be performing an operation on behalf of an indirect binder
7525        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7526        // client identity accordingly before proceeding.
7527        Identity tlsIdentity = sCallerIdentity.get();
7528        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7529            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7530                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7531            uid = tlsIdentity.uid;
7532            pid = tlsIdentity.pid;
7533        }
7534
7535        return checkComponentPermission(permission, pid, uid, -1, true);
7536    }
7537
7538    /**
7539     * Binder IPC calls go through the public entry point.
7540     * This can be called with or without the global lock held.
7541     */
7542    int checkCallingPermission(String permission) {
7543        return checkPermission(permission,
7544                Binder.getCallingPid(),
7545                UserHandle.getAppId(Binder.getCallingUid()));
7546    }
7547
7548    /**
7549     * This can be called with or without the global lock held.
7550     */
7551    void enforceCallingPermission(String permission, String func) {
7552        if (checkCallingPermission(permission)
7553                == PackageManager.PERMISSION_GRANTED) {
7554            return;
7555        }
7556
7557        String msg = "Permission Denial: " + func + " from pid="
7558                + Binder.getCallingPid()
7559                + ", uid=" + Binder.getCallingUid()
7560                + " requires " + permission;
7561        Slog.w(TAG, msg);
7562        throw new SecurityException(msg);
7563    }
7564
7565    /**
7566     * Determine if UID is holding permissions required to access {@link Uri} in
7567     * the given {@link ProviderInfo}. Final permission checking is always done
7568     * in {@link ContentProvider}.
7569     */
7570    private final boolean checkHoldingPermissionsLocked(
7571            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7572        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7573                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7574        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7575            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7576                    != PERMISSION_GRANTED) {
7577                return false;
7578            }
7579        }
7580        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7581    }
7582
7583    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7584            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7585        if (pi.applicationInfo.uid == uid) {
7586            return true;
7587        } else if (!pi.exported) {
7588            return false;
7589        }
7590
7591        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7592        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7593        try {
7594            // check if target holds top-level <provider> permissions
7595            if (!readMet && pi.readPermission != null && considerUidPermissions
7596                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7597                readMet = true;
7598            }
7599            if (!writeMet && pi.writePermission != null && considerUidPermissions
7600                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7601                writeMet = true;
7602            }
7603
7604            // track if unprotected read/write is allowed; any denied
7605            // <path-permission> below removes this ability
7606            boolean allowDefaultRead = pi.readPermission == null;
7607            boolean allowDefaultWrite = pi.writePermission == null;
7608
7609            // check if target holds any <path-permission> that match uri
7610            final PathPermission[] pps = pi.pathPermissions;
7611            if (pps != null) {
7612                final String path = grantUri.uri.getPath();
7613                int i = pps.length;
7614                while (i > 0 && (!readMet || !writeMet)) {
7615                    i--;
7616                    PathPermission pp = pps[i];
7617                    if (pp.match(path)) {
7618                        if (!readMet) {
7619                            final String pprperm = pp.getReadPermission();
7620                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7621                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7622                                    + ": match=" + pp.match(path)
7623                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7624                            if (pprperm != null) {
7625                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7626                                        == PERMISSION_GRANTED) {
7627                                    readMet = true;
7628                                } else {
7629                                    allowDefaultRead = false;
7630                                }
7631                            }
7632                        }
7633                        if (!writeMet) {
7634                            final String ppwperm = pp.getWritePermission();
7635                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7636                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7637                                    + ": match=" + pp.match(path)
7638                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7639                            if (ppwperm != null) {
7640                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7641                                        == PERMISSION_GRANTED) {
7642                                    writeMet = true;
7643                                } else {
7644                                    allowDefaultWrite = false;
7645                                }
7646                            }
7647                        }
7648                    }
7649                }
7650            }
7651
7652            // grant unprotected <provider> read/write, if not blocked by
7653            // <path-permission> above
7654            if (allowDefaultRead) readMet = true;
7655            if (allowDefaultWrite) writeMet = true;
7656
7657        } catch (RemoteException e) {
7658            return false;
7659        }
7660
7661        return readMet && writeMet;
7662    }
7663
7664    public int getAppStartMode(int uid, String packageName) {
7665        synchronized (this) {
7666            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7667        }
7668    }
7669
7670    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7671            boolean allowWhenForeground) {
7672        UidRecord uidRec = mActiveUids.get(uid);
7673        if (!mLenientBackgroundCheck) {
7674            if (!allowWhenForeground || uidRec == null
7675                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7676                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7677                        packageName) != AppOpsManager.MODE_ALLOWED) {
7678                    return ActivityManager.APP_START_MODE_DELAYED;
7679                }
7680            }
7681
7682        } else if (uidRec == null || uidRec.idle) {
7683            if (callingPid >= 0) {
7684                ProcessRecord proc;
7685                synchronized (mPidsSelfLocked) {
7686                    proc = mPidsSelfLocked.get(callingPid);
7687                }
7688                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7689                    // Whoever is instigating this is in the foreground, so we will allow it
7690                    // to go through.
7691                    return ActivityManager.APP_START_MODE_NORMAL;
7692                }
7693            }
7694            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7695                    != AppOpsManager.MODE_ALLOWED) {
7696                return ActivityManager.APP_START_MODE_DELAYED;
7697            }
7698        }
7699        return ActivityManager.APP_START_MODE_NORMAL;
7700    }
7701
7702    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7703        ProviderInfo pi = null;
7704        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7705        if (cpr != null) {
7706            pi = cpr.info;
7707        } else {
7708            try {
7709                pi = AppGlobals.getPackageManager().resolveContentProvider(
7710                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7711            } catch (RemoteException ex) {
7712            }
7713        }
7714        return pi;
7715    }
7716
7717    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7718        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7719        if (targetUris != null) {
7720            return targetUris.get(grantUri);
7721        }
7722        return null;
7723    }
7724
7725    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7726            String targetPkg, int targetUid, GrantUri grantUri) {
7727        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7728        if (targetUris == null) {
7729            targetUris = Maps.newArrayMap();
7730            mGrantedUriPermissions.put(targetUid, targetUris);
7731        }
7732
7733        UriPermission perm = targetUris.get(grantUri);
7734        if (perm == null) {
7735            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7736            targetUris.put(grantUri, perm);
7737        }
7738
7739        return perm;
7740    }
7741
7742    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7743            final int modeFlags) {
7744        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7745        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7746                : UriPermission.STRENGTH_OWNED;
7747
7748        // Root gets to do everything.
7749        if (uid == 0) {
7750            return true;
7751        }
7752
7753        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7754        if (perms == null) return false;
7755
7756        // First look for exact match
7757        final UriPermission exactPerm = perms.get(grantUri);
7758        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7759            return true;
7760        }
7761
7762        // No exact match, look for prefixes
7763        final int N = perms.size();
7764        for (int i = 0; i < N; i++) {
7765            final UriPermission perm = perms.valueAt(i);
7766            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7767                    && perm.getStrength(modeFlags) >= minStrength) {
7768                return true;
7769            }
7770        }
7771
7772        return false;
7773    }
7774
7775    /**
7776     * @param uri This uri must NOT contain an embedded userId.
7777     * @param userId The userId in which the uri is to be resolved.
7778     */
7779    @Override
7780    public int checkUriPermission(Uri uri, int pid, int uid,
7781            final int modeFlags, int userId, IBinder callerToken) {
7782        enforceNotIsolatedCaller("checkUriPermission");
7783
7784        // Another redirected-binder-call permissions check as in
7785        // {@link checkPermissionWithToken}.
7786        Identity tlsIdentity = sCallerIdentity.get();
7787        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7788            uid = tlsIdentity.uid;
7789            pid = tlsIdentity.pid;
7790        }
7791
7792        // Our own process gets to do everything.
7793        if (pid == MY_PID) {
7794            return PackageManager.PERMISSION_GRANTED;
7795        }
7796        synchronized (this) {
7797            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7798                    ? PackageManager.PERMISSION_GRANTED
7799                    : PackageManager.PERMISSION_DENIED;
7800        }
7801    }
7802
7803    /**
7804     * Check if the targetPkg can be granted permission to access uri by
7805     * the callingUid using the given modeFlags.  Throws a security exception
7806     * if callingUid is not allowed to do this.  Returns the uid of the target
7807     * if the URI permission grant should be performed; returns -1 if it is not
7808     * needed (for example targetPkg already has permission to access the URI).
7809     * If you already know the uid of the target, you can supply it in
7810     * lastTargetUid else set that to -1.
7811     */
7812    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7813            final int modeFlags, int lastTargetUid) {
7814        if (!Intent.isAccessUriMode(modeFlags)) {
7815            return -1;
7816        }
7817
7818        if (targetPkg != null) {
7819            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7820                    "Checking grant " + targetPkg + " permission to " + grantUri);
7821        }
7822
7823        final IPackageManager pm = AppGlobals.getPackageManager();
7824
7825        // If this is not a content: uri, we can't do anything with it.
7826        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7827            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7828                    "Can't grant URI permission for non-content URI: " + grantUri);
7829            return -1;
7830        }
7831
7832        final String authority = grantUri.uri.getAuthority();
7833        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7834        if (pi == null) {
7835            Slog.w(TAG, "No content provider found for permission check: " +
7836                    grantUri.uri.toSafeString());
7837            return -1;
7838        }
7839
7840        int targetUid = lastTargetUid;
7841        if (targetUid < 0 && targetPkg != null) {
7842            try {
7843                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7844                        UserHandle.getUserId(callingUid));
7845                if (targetUid < 0) {
7846                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7847                            "Can't grant URI permission no uid for: " + targetPkg);
7848                    return -1;
7849                }
7850            } catch (RemoteException ex) {
7851                return -1;
7852            }
7853        }
7854
7855        if (targetUid >= 0) {
7856            // First...  does the target actually need this permission?
7857            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7858                // No need to grant the target this permission.
7859                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7860                        "Target " + targetPkg + " already has full permission to " + grantUri);
7861                return -1;
7862            }
7863        } else {
7864            // First...  there is no target package, so can anyone access it?
7865            boolean allowed = pi.exported;
7866            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7867                if (pi.readPermission != null) {
7868                    allowed = false;
7869                }
7870            }
7871            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7872                if (pi.writePermission != null) {
7873                    allowed = false;
7874                }
7875            }
7876            if (allowed) {
7877                return -1;
7878            }
7879        }
7880
7881        /* There is a special cross user grant if:
7882         * - The target is on another user.
7883         * - Apps on the current user can access the uri without any uid permissions.
7884         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7885         * grant uri permissions.
7886         */
7887        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7888                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7889                modeFlags, false /*without considering the uid permissions*/);
7890
7891        // Second...  is the provider allowing granting of URI permissions?
7892        if (!specialCrossUserGrant) {
7893            if (!pi.grantUriPermissions) {
7894                throw new SecurityException("Provider " + pi.packageName
7895                        + "/" + pi.name
7896                        + " does not allow granting of Uri permissions (uri "
7897                        + grantUri + ")");
7898            }
7899            if (pi.uriPermissionPatterns != null) {
7900                final int N = pi.uriPermissionPatterns.length;
7901                boolean allowed = false;
7902                for (int i=0; i<N; i++) {
7903                    if (pi.uriPermissionPatterns[i] != null
7904                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7905                        allowed = true;
7906                        break;
7907                    }
7908                }
7909                if (!allowed) {
7910                    throw new SecurityException("Provider " + pi.packageName
7911                            + "/" + pi.name
7912                            + " does not allow granting of permission to path of Uri "
7913                            + grantUri);
7914                }
7915            }
7916        }
7917
7918        // Third...  does the caller itself have permission to access
7919        // this uri?
7920        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7921            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7922                // Require they hold a strong enough Uri permission
7923                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7924                    throw new SecurityException("Uid " + callingUid
7925                            + " does not have permission to uri " + grantUri);
7926                }
7927            }
7928        }
7929        return targetUid;
7930    }
7931
7932    /**
7933     * @param uri This uri must NOT contain an embedded userId.
7934     * @param userId The userId in which the uri is to be resolved.
7935     */
7936    @Override
7937    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7938            final int modeFlags, int userId) {
7939        enforceNotIsolatedCaller("checkGrantUriPermission");
7940        synchronized(this) {
7941            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7942                    new GrantUri(userId, uri, false), modeFlags, -1);
7943        }
7944    }
7945
7946    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7947            final int modeFlags, UriPermissionOwner owner) {
7948        if (!Intent.isAccessUriMode(modeFlags)) {
7949            return;
7950        }
7951
7952        // So here we are: the caller has the assumed permission
7953        // to the uri, and the target doesn't.  Let's now give this to
7954        // the target.
7955
7956        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7957                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7958
7959        final String authority = grantUri.uri.getAuthority();
7960        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7961        if (pi == null) {
7962            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7963            return;
7964        }
7965
7966        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7967            grantUri.prefix = true;
7968        }
7969        final UriPermission perm = findOrCreateUriPermissionLocked(
7970                pi.packageName, targetPkg, targetUid, grantUri);
7971        perm.grantModes(modeFlags, owner);
7972    }
7973
7974    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7975            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7976        if (targetPkg == null) {
7977            throw new NullPointerException("targetPkg");
7978        }
7979        int targetUid;
7980        final IPackageManager pm = AppGlobals.getPackageManager();
7981        try {
7982            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7983        } catch (RemoteException ex) {
7984            return;
7985        }
7986
7987        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7988                targetUid);
7989        if (targetUid < 0) {
7990            return;
7991        }
7992
7993        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7994                owner);
7995    }
7996
7997    static class NeededUriGrants extends ArrayList<GrantUri> {
7998        final String targetPkg;
7999        final int targetUid;
8000        final int flags;
8001
8002        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8003            this.targetPkg = targetPkg;
8004            this.targetUid = targetUid;
8005            this.flags = flags;
8006        }
8007    }
8008
8009    /**
8010     * Like checkGrantUriPermissionLocked, but takes an Intent.
8011     */
8012    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8013            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8014        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8015                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8016                + " clip=" + (intent != null ? intent.getClipData() : null)
8017                + " from " + intent + "; flags=0x"
8018                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8019
8020        if (targetPkg == null) {
8021            throw new NullPointerException("targetPkg");
8022        }
8023
8024        if (intent == null) {
8025            return null;
8026        }
8027        Uri data = intent.getData();
8028        ClipData clip = intent.getClipData();
8029        if (data == null && clip == null) {
8030            return null;
8031        }
8032        // Default userId for uris in the intent (if they don't specify it themselves)
8033        int contentUserHint = intent.getContentUserHint();
8034        if (contentUserHint == UserHandle.USER_CURRENT) {
8035            contentUserHint = UserHandle.getUserId(callingUid);
8036        }
8037        final IPackageManager pm = AppGlobals.getPackageManager();
8038        int targetUid;
8039        if (needed != null) {
8040            targetUid = needed.targetUid;
8041        } else {
8042            try {
8043                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8044                        targetUserId);
8045            } catch (RemoteException ex) {
8046                return null;
8047            }
8048            if (targetUid < 0) {
8049                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8050                        "Can't grant URI permission no uid for: " + targetPkg
8051                        + " on user " + targetUserId);
8052                return null;
8053            }
8054        }
8055        if (data != null) {
8056            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8057            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8058                    targetUid);
8059            if (targetUid > 0) {
8060                if (needed == null) {
8061                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8062                }
8063                needed.add(grantUri);
8064            }
8065        }
8066        if (clip != null) {
8067            for (int i=0; i<clip.getItemCount(); i++) {
8068                Uri uri = clip.getItemAt(i).getUri();
8069                if (uri != null) {
8070                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8071                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8072                            targetUid);
8073                    if (targetUid > 0) {
8074                        if (needed == null) {
8075                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8076                        }
8077                        needed.add(grantUri);
8078                    }
8079                } else {
8080                    Intent clipIntent = clip.getItemAt(i).getIntent();
8081                    if (clipIntent != null) {
8082                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8083                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8084                        if (newNeeded != null) {
8085                            needed = newNeeded;
8086                        }
8087                    }
8088                }
8089            }
8090        }
8091
8092        return needed;
8093    }
8094
8095    /**
8096     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8097     */
8098    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8099            UriPermissionOwner owner) {
8100        if (needed != null) {
8101            for (int i=0; i<needed.size(); i++) {
8102                GrantUri grantUri = needed.get(i);
8103                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8104                        grantUri, needed.flags, owner);
8105            }
8106        }
8107    }
8108
8109    void grantUriPermissionFromIntentLocked(int callingUid,
8110            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8111        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8112                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8113        if (needed == null) {
8114            return;
8115        }
8116
8117        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8118    }
8119
8120    /**
8121     * @param uri This uri must NOT contain an embedded userId.
8122     * @param userId The userId in which the uri is to be resolved.
8123     */
8124    @Override
8125    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8126            final int modeFlags, int userId) {
8127        enforceNotIsolatedCaller("grantUriPermission");
8128        GrantUri grantUri = new GrantUri(userId, uri, false);
8129        synchronized(this) {
8130            final ProcessRecord r = getRecordForAppLocked(caller);
8131            if (r == null) {
8132                throw new SecurityException("Unable to find app for caller "
8133                        + caller
8134                        + " when granting permission to uri " + grantUri);
8135            }
8136            if (targetPkg == null) {
8137                throw new IllegalArgumentException("null target");
8138            }
8139            if (grantUri == null) {
8140                throw new IllegalArgumentException("null uri");
8141            }
8142
8143            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8144                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8145                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8146                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8147
8148            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8149                    UserHandle.getUserId(r.uid));
8150        }
8151    }
8152
8153    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8154        if (perm.modeFlags == 0) {
8155            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8156                    perm.targetUid);
8157            if (perms != null) {
8158                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8159                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8160
8161                perms.remove(perm.uri);
8162                if (perms.isEmpty()) {
8163                    mGrantedUriPermissions.remove(perm.targetUid);
8164                }
8165            }
8166        }
8167    }
8168
8169    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8170        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8171                "Revoking all granted permissions to " + grantUri);
8172
8173        final IPackageManager pm = AppGlobals.getPackageManager();
8174        final String authority = grantUri.uri.getAuthority();
8175        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8176        if (pi == null) {
8177            Slog.w(TAG, "No content provider found for permission revoke: "
8178                    + grantUri.toSafeString());
8179            return;
8180        }
8181
8182        // Does the caller have this permission on the URI?
8183        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8184            // If they don't have direct access to the URI, then revoke any
8185            // ownerless URI permissions that have been granted to them.
8186            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8187            if (perms != null) {
8188                boolean persistChanged = false;
8189                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8190                    final UriPermission perm = it.next();
8191                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8192                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8193                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8194                                "Revoking non-owned " + perm.targetUid
8195                                + " permission to " + perm.uri);
8196                        persistChanged |= perm.revokeModes(
8197                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8198                        if (perm.modeFlags == 0) {
8199                            it.remove();
8200                        }
8201                    }
8202                }
8203                if (perms.isEmpty()) {
8204                    mGrantedUriPermissions.remove(callingUid);
8205                }
8206                if (persistChanged) {
8207                    schedulePersistUriGrants();
8208                }
8209            }
8210            return;
8211        }
8212
8213        boolean persistChanged = false;
8214
8215        // Go through all of the permissions and remove any that match.
8216        int N = mGrantedUriPermissions.size();
8217        for (int i = 0; i < N; i++) {
8218            final int targetUid = mGrantedUriPermissions.keyAt(i);
8219            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8220
8221            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8222                final UriPermission perm = it.next();
8223                if (perm.uri.sourceUserId == grantUri.sourceUserId
8224                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8225                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8226                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8227                    persistChanged |= perm.revokeModes(
8228                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8229                    if (perm.modeFlags == 0) {
8230                        it.remove();
8231                    }
8232                }
8233            }
8234
8235            if (perms.isEmpty()) {
8236                mGrantedUriPermissions.remove(targetUid);
8237                N--;
8238                i--;
8239            }
8240        }
8241
8242        if (persistChanged) {
8243            schedulePersistUriGrants();
8244        }
8245    }
8246
8247    /**
8248     * @param uri This uri must NOT contain an embedded userId.
8249     * @param userId The userId in which the uri is to be resolved.
8250     */
8251    @Override
8252    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8253            int userId) {
8254        enforceNotIsolatedCaller("revokeUriPermission");
8255        synchronized(this) {
8256            final ProcessRecord r = getRecordForAppLocked(caller);
8257            if (r == null) {
8258                throw new SecurityException("Unable to find app for caller "
8259                        + caller
8260                        + " when revoking permission to uri " + uri);
8261            }
8262            if (uri == null) {
8263                Slog.w(TAG, "revokeUriPermission: null uri");
8264                return;
8265            }
8266
8267            if (!Intent.isAccessUriMode(modeFlags)) {
8268                return;
8269            }
8270
8271            final String authority = uri.getAuthority();
8272            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8273            if (pi == null) {
8274                Slog.w(TAG, "No content provider found for permission revoke: "
8275                        + uri.toSafeString());
8276                return;
8277            }
8278
8279            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8280        }
8281    }
8282
8283    /**
8284     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8285     * given package.
8286     *
8287     * @param packageName Package name to match, or {@code null} to apply to all
8288     *            packages.
8289     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8290     *            to all users.
8291     * @param persistable If persistable grants should be removed.
8292     */
8293    private void removeUriPermissionsForPackageLocked(
8294            String packageName, int userHandle, boolean persistable) {
8295        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8296            throw new IllegalArgumentException("Must narrow by either package or user");
8297        }
8298
8299        boolean persistChanged = false;
8300
8301        int N = mGrantedUriPermissions.size();
8302        for (int i = 0; i < N; i++) {
8303            final int targetUid = mGrantedUriPermissions.keyAt(i);
8304            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8305
8306            // Only inspect grants matching user
8307            if (userHandle == UserHandle.USER_ALL
8308                    || userHandle == UserHandle.getUserId(targetUid)) {
8309                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8310                    final UriPermission perm = it.next();
8311
8312                    // Only inspect grants matching package
8313                    if (packageName == null || perm.sourcePkg.equals(packageName)
8314                            || perm.targetPkg.equals(packageName)) {
8315                        persistChanged |= perm.revokeModes(persistable
8316                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8317
8318                        // Only remove when no modes remain; any persisted grants
8319                        // will keep this alive.
8320                        if (perm.modeFlags == 0) {
8321                            it.remove();
8322                        }
8323                    }
8324                }
8325
8326                if (perms.isEmpty()) {
8327                    mGrantedUriPermissions.remove(targetUid);
8328                    N--;
8329                    i--;
8330                }
8331            }
8332        }
8333
8334        if (persistChanged) {
8335            schedulePersistUriGrants();
8336        }
8337    }
8338
8339    @Override
8340    public IBinder newUriPermissionOwner(String name) {
8341        enforceNotIsolatedCaller("newUriPermissionOwner");
8342        synchronized(this) {
8343            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8344            return owner.getExternalTokenLocked();
8345        }
8346    }
8347
8348    @Override
8349    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8350        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8351        synchronized(this) {
8352            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8353            if (r == null) {
8354                throw new IllegalArgumentException("Activity does not exist; token="
8355                        + activityToken);
8356            }
8357            return r.getUriPermissionsLocked().getExternalTokenLocked();
8358        }
8359    }
8360    /**
8361     * @param uri This uri must NOT contain an embedded userId.
8362     * @param sourceUserId The userId in which the uri is to be resolved.
8363     * @param targetUserId The userId of the app that receives the grant.
8364     */
8365    @Override
8366    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8367            final int modeFlags, int sourceUserId, int targetUserId) {
8368        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8369                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8370                "grantUriPermissionFromOwner", null);
8371        synchronized(this) {
8372            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8373            if (owner == null) {
8374                throw new IllegalArgumentException("Unknown owner: " + token);
8375            }
8376            if (fromUid != Binder.getCallingUid()) {
8377                if (Binder.getCallingUid() != Process.myUid()) {
8378                    // Only system code can grant URI permissions on behalf
8379                    // of other users.
8380                    throw new SecurityException("nice try");
8381                }
8382            }
8383            if (targetPkg == null) {
8384                throw new IllegalArgumentException("null target");
8385            }
8386            if (uri == null) {
8387                throw new IllegalArgumentException("null uri");
8388            }
8389
8390            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8391                    modeFlags, owner, targetUserId);
8392        }
8393    }
8394
8395    /**
8396     * @param uri This uri must NOT contain an embedded userId.
8397     * @param userId The userId in which the uri is to be resolved.
8398     */
8399    @Override
8400    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8401        synchronized(this) {
8402            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8403            if (owner == null) {
8404                throw new IllegalArgumentException("Unknown owner: " + token);
8405            }
8406
8407            if (uri == null) {
8408                owner.removeUriPermissionsLocked(mode);
8409            } else {
8410                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8411            }
8412        }
8413    }
8414
8415    private void schedulePersistUriGrants() {
8416        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8417            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8418                    10 * DateUtils.SECOND_IN_MILLIS);
8419        }
8420    }
8421
8422    private void writeGrantedUriPermissions() {
8423        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8424
8425        // Snapshot permissions so we can persist without lock
8426        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8427        synchronized (this) {
8428            final int size = mGrantedUriPermissions.size();
8429            for (int i = 0; i < size; i++) {
8430                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8431                for (UriPermission perm : perms.values()) {
8432                    if (perm.persistedModeFlags != 0) {
8433                        persist.add(perm.snapshot());
8434                    }
8435                }
8436            }
8437        }
8438
8439        FileOutputStream fos = null;
8440        try {
8441            fos = mGrantFile.startWrite();
8442
8443            XmlSerializer out = new FastXmlSerializer();
8444            out.setOutput(fos, StandardCharsets.UTF_8.name());
8445            out.startDocument(null, true);
8446            out.startTag(null, TAG_URI_GRANTS);
8447            for (UriPermission.Snapshot perm : persist) {
8448                out.startTag(null, TAG_URI_GRANT);
8449                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8450                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8451                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8452                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8453                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8454                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8455                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8456                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8457                out.endTag(null, TAG_URI_GRANT);
8458            }
8459            out.endTag(null, TAG_URI_GRANTS);
8460            out.endDocument();
8461
8462            mGrantFile.finishWrite(fos);
8463        } catch (IOException e) {
8464            if (fos != null) {
8465                mGrantFile.failWrite(fos);
8466            }
8467        }
8468    }
8469
8470    private void readGrantedUriPermissionsLocked() {
8471        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8472
8473        final long now = System.currentTimeMillis();
8474
8475        FileInputStream fis = null;
8476        try {
8477            fis = mGrantFile.openRead();
8478            final XmlPullParser in = Xml.newPullParser();
8479            in.setInput(fis, StandardCharsets.UTF_8.name());
8480
8481            int type;
8482            while ((type = in.next()) != END_DOCUMENT) {
8483                final String tag = in.getName();
8484                if (type == START_TAG) {
8485                    if (TAG_URI_GRANT.equals(tag)) {
8486                        final int sourceUserId;
8487                        final int targetUserId;
8488                        final int userHandle = readIntAttribute(in,
8489                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8490                        if (userHandle != UserHandle.USER_NULL) {
8491                            // For backwards compatibility.
8492                            sourceUserId = userHandle;
8493                            targetUserId = userHandle;
8494                        } else {
8495                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8496                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8497                        }
8498                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8499                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8500                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8501                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8502                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8503                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8504
8505                        // Sanity check that provider still belongs to source package
8506                        final ProviderInfo pi = getProviderInfoLocked(
8507                                uri.getAuthority(), sourceUserId);
8508                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8509                            int targetUid = -1;
8510                            try {
8511                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8512                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8513                            } catch (RemoteException e) {
8514                            }
8515                            if (targetUid != -1) {
8516                                final UriPermission perm = findOrCreateUriPermissionLocked(
8517                                        sourcePkg, targetPkg, targetUid,
8518                                        new GrantUri(sourceUserId, uri, prefix));
8519                                perm.initPersistedModes(modeFlags, createdTime);
8520                            }
8521                        } else {
8522                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8523                                    + " but instead found " + pi);
8524                        }
8525                    }
8526                }
8527            }
8528        } catch (FileNotFoundException e) {
8529            // Missing grants is okay
8530        } catch (IOException e) {
8531            Slog.wtf(TAG, "Failed reading Uri grants", e);
8532        } catch (XmlPullParserException e) {
8533            Slog.wtf(TAG, "Failed reading Uri grants", e);
8534        } finally {
8535            IoUtils.closeQuietly(fis);
8536        }
8537    }
8538
8539    /**
8540     * @param uri This uri must NOT contain an embedded userId.
8541     * @param userId The userId in which the uri is to be resolved.
8542     */
8543    @Override
8544    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8545        enforceNotIsolatedCaller("takePersistableUriPermission");
8546
8547        Preconditions.checkFlagsArgument(modeFlags,
8548                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8549
8550        synchronized (this) {
8551            final int callingUid = Binder.getCallingUid();
8552            boolean persistChanged = false;
8553            GrantUri grantUri = new GrantUri(userId, uri, false);
8554
8555            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8556                    new GrantUri(userId, uri, false));
8557            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8558                    new GrantUri(userId, uri, true));
8559
8560            final boolean exactValid = (exactPerm != null)
8561                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8562            final boolean prefixValid = (prefixPerm != null)
8563                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8564
8565            if (!(exactValid || prefixValid)) {
8566                throw new SecurityException("No persistable permission grants found for UID "
8567                        + callingUid + " and Uri " + grantUri.toSafeString());
8568            }
8569
8570            if (exactValid) {
8571                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8572            }
8573            if (prefixValid) {
8574                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8575            }
8576
8577            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8578
8579            if (persistChanged) {
8580                schedulePersistUriGrants();
8581            }
8582        }
8583    }
8584
8585    /**
8586     * @param uri This uri must NOT contain an embedded userId.
8587     * @param userId The userId in which the uri is to be resolved.
8588     */
8589    @Override
8590    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8591        enforceNotIsolatedCaller("releasePersistableUriPermission");
8592
8593        Preconditions.checkFlagsArgument(modeFlags,
8594                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8595
8596        synchronized (this) {
8597            final int callingUid = Binder.getCallingUid();
8598            boolean persistChanged = false;
8599
8600            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8601                    new GrantUri(userId, uri, false));
8602            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8603                    new GrantUri(userId, uri, true));
8604            if (exactPerm == null && prefixPerm == null) {
8605                throw new SecurityException("No permission grants found for UID " + callingUid
8606                        + " and Uri " + uri.toSafeString());
8607            }
8608
8609            if (exactPerm != null) {
8610                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8611                removeUriPermissionIfNeededLocked(exactPerm);
8612            }
8613            if (prefixPerm != null) {
8614                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8615                removeUriPermissionIfNeededLocked(prefixPerm);
8616            }
8617
8618            if (persistChanged) {
8619                schedulePersistUriGrants();
8620            }
8621        }
8622    }
8623
8624    /**
8625     * Prune any older {@link UriPermission} for the given UID until outstanding
8626     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8627     *
8628     * @return if any mutations occured that require persisting.
8629     */
8630    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8631        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8632        if (perms == null) return false;
8633        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8634
8635        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8636        for (UriPermission perm : perms.values()) {
8637            if (perm.persistedModeFlags != 0) {
8638                persisted.add(perm);
8639            }
8640        }
8641
8642        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8643        if (trimCount <= 0) return false;
8644
8645        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8646        for (int i = 0; i < trimCount; i++) {
8647            final UriPermission perm = persisted.get(i);
8648
8649            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8650                    "Trimming grant created at " + perm.persistedCreateTime);
8651
8652            perm.releasePersistableModes(~0);
8653            removeUriPermissionIfNeededLocked(perm);
8654        }
8655
8656        return true;
8657    }
8658
8659    @Override
8660    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8661            String packageName, boolean incoming) {
8662        enforceNotIsolatedCaller("getPersistedUriPermissions");
8663        Preconditions.checkNotNull(packageName, "packageName");
8664
8665        final int callingUid = Binder.getCallingUid();
8666        final IPackageManager pm = AppGlobals.getPackageManager();
8667        try {
8668            final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8669                    UserHandle.getUserId(callingUid));
8670            if (packageUid != callingUid) {
8671                throw new SecurityException(
8672                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8673            }
8674        } catch (RemoteException e) {
8675            throw new SecurityException("Failed to verify package name ownership");
8676        }
8677
8678        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8679        synchronized (this) {
8680            if (incoming) {
8681                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8682                        callingUid);
8683                if (perms == null) {
8684                    Slog.w(TAG, "No permission grants found for " + packageName);
8685                } else {
8686                    for (UriPermission perm : perms.values()) {
8687                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8688                            result.add(perm.buildPersistedPublicApiObject());
8689                        }
8690                    }
8691                }
8692            } else {
8693                final int size = mGrantedUriPermissions.size();
8694                for (int i = 0; i < size; i++) {
8695                    final ArrayMap<GrantUri, UriPermission> perms =
8696                            mGrantedUriPermissions.valueAt(i);
8697                    for (UriPermission perm : perms.values()) {
8698                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8699                            result.add(perm.buildPersistedPublicApiObject());
8700                        }
8701                    }
8702                }
8703            }
8704        }
8705        return new ParceledListSlice<android.content.UriPermission>(result);
8706    }
8707
8708    @Override
8709    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8710            String packageName, int userId) {
8711        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8712                "getGrantedUriPermissions");
8713
8714        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8715        synchronized (this) {
8716            final int size = mGrantedUriPermissions.size();
8717            for (int i = 0; i < size; i++) {
8718                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8719                for (UriPermission perm : perms.values()) {
8720                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8721                            && perm.persistedModeFlags != 0) {
8722                        result.add(perm.buildPersistedPublicApiObject());
8723                    }
8724                }
8725            }
8726        }
8727        return new ParceledListSlice<android.content.UriPermission>(result);
8728    }
8729
8730    @Override
8731    public void clearGrantedUriPermissions(String packageName, int userId) {
8732        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8733                "clearGrantedUriPermissions");
8734        removeUriPermissionsForPackageLocked(packageName, userId, true);
8735    }
8736
8737    @Override
8738    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8739        synchronized (this) {
8740            ProcessRecord app =
8741                who != null ? getRecordForAppLocked(who) : null;
8742            if (app == null) return;
8743
8744            Message msg = Message.obtain();
8745            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8746            msg.obj = app;
8747            msg.arg1 = waiting ? 1 : 0;
8748            mUiHandler.sendMessage(msg);
8749        }
8750    }
8751
8752    @Override
8753    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8754        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8755        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8756        outInfo.availMem = Process.getFreeMemory();
8757        outInfo.totalMem = Process.getTotalMemory();
8758        outInfo.threshold = homeAppMem;
8759        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8760        outInfo.hiddenAppThreshold = cachedAppMem;
8761        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8762                ProcessList.SERVICE_ADJ);
8763        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8764                ProcessList.VISIBLE_APP_ADJ);
8765        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8766                ProcessList.FOREGROUND_APP_ADJ);
8767    }
8768
8769    // =========================================================
8770    // TASK MANAGEMENT
8771    // =========================================================
8772
8773    @Override
8774    public List<IAppTask> getAppTasks(String callingPackage) {
8775        int callingUid = Binder.getCallingUid();
8776        long ident = Binder.clearCallingIdentity();
8777
8778        synchronized(this) {
8779            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8780            try {
8781                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8782
8783                final int N = mRecentTasks.size();
8784                for (int i = 0; i < N; i++) {
8785                    TaskRecord tr = mRecentTasks.get(i);
8786                    // Skip tasks that do not match the caller.  We don't need to verify
8787                    // callingPackage, because we are also limiting to callingUid and know
8788                    // that will limit to the correct security sandbox.
8789                    if (tr.effectiveUid != callingUid) {
8790                        continue;
8791                    }
8792                    Intent intent = tr.getBaseIntent();
8793                    if (intent == null ||
8794                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8795                        continue;
8796                    }
8797                    ActivityManager.RecentTaskInfo taskInfo =
8798                            createRecentTaskInfoFromTaskRecord(tr);
8799                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8800                    list.add(taskImpl);
8801                }
8802            } finally {
8803                Binder.restoreCallingIdentity(ident);
8804            }
8805            return list;
8806        }
8807    }
8808
8809    @Override
8810    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8811        final int callingUid = Binder.getCallingUid();
8812        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8813
8814        synchronized(this) {
8815            if (DEBUG_ALL) Slog.v(
8816                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8817
8818            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8819                    callingUid);
8820
8821            // TODO: Improve with MRU list from all ActivityStacks.
8822            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8823        }
8824
8825        return list;
8826    }
8827
8828    /**
8829     * Creates a new RecentTaskInfo from a TaskRecord.
8830     */
8831    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8832        // Update the task description to reflect any changes in the task stack
8833        tr.updateTaskDescription();
8834
8835        // Compose the recent task info
8836        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8837        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8838        rti.persistentId = tr.taskId;
8839        rti.baseIntent = new Intent(tr.getBaseIntent());
8840        rti.origActivity = tr.origActivity;
8841        rti.realActivity = tr.realActivity;
8842        rti.description = tr.lastDescription;
8843        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8844        rti.userId = tr.userId;
8845        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8846        rti.firstActiveTime = tr.firstActiveTime;
8847        rti.lastActiveTime = tr.lastActiveTime;
8848        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8849        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8850        rti.numActivities = 0;
8851        if (tr.mBounds != null) {
8852            rti.bounds = new Rect(tr.mBounds);
8853        }
8854        rti.isDockable = tr.canGoInDockedStack();
8855        rti.resizeMode = tr.mResizeMode;
8856
8857        ActivityRecord base = null;
8858        ActivityRecord top = null;
8859        ActivityRecord tmp;
8860
8861        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8862            tmp = tr.mActivities.get(i);
8863            if (tmp.finishing) {
8864                continue;
8865            }
8866            base = tmp;
8867            if (top == null || (top.state == ActivityState.INITIALIZING)) {
8868                top = base;
8869            }
8870            rti.numActivities++;
8871        }
8872
8873        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8874        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8875
8876        return rti;
8877    }
8878
8879    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8880        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8881                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8882        if (!allowed) {
8883            if (checkPermission(android.Manifest.permission.GET_TASKS,
8884                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8885                // Temporary compatibility: some existing apps on the system image may
8886                // still be requesting the old permission and not switched to the new
8887                // one; if so, we'll still allow them full access.  This means we need
8888                // to see if they are holding the old permission and are a system app.
8889                try {
8890                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8891                        allowed = true;
8892                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8893                                + " is using old GET_TASKS but privileged; allowing");
8894                    }
8895                } catch (RemoteException e) {
8896                }
8897            }
8898        }
8899        if (!allowed) {
8900            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8901                    + " does not hold REAL_GET_TASKS; limiting output");
8902        }
8903        return allowed;
8904    }
8905
8906    @Override
8907    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8908        final int callingUid = Binder.getCallingUid();
8909        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8910                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8911
8912        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8913        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8914        synchronized (this) {
8915            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8916                    callingUid);
8917            final boolean detailed = checkCallingPermission(
8918                    android.Manifest.permission.GET_DETAILED_TASKS)
8919                    == PackageManager.PERMISSION_GRANTED;
8920
8921            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8922                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8923                return Collections.emptyList();
8924            }
8925            mRecentTasks.loadUserRecentsLocked(userId);
8926
8927            final int recentsCount = mRecentTasks.size();
8928            ArrayList<ActivityManager.RecentTaskInfo> res =
8929                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8930
8931            final Set<Integer> includedUsers;
8932            if (includeProfiles) {
8933                includedUsers = mUserController.getProfileIds(userId);
8934            } else {
8935                includedUsers = new HashSet<>();
8936            }
8937            includedUsers.add(Integer.valueOf(userId));
8938
8939            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8940                TaskRecord tr = mRecentTasks.get(i);
8941                // Only add calling user or related users recent tasks
8942                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8943                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8944                    continue;
8945                }
8946
8947                if (tr.realActivitySuspended) {
8948                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8949                    continue;
8950                }
8951
8952                // Return the entry if desired by the caller.  We always return
8953                // the first entry, because callers always expect this to be the
8954                // foreground app.  We may filter others if the caller has
8955                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8956                // we should exclude the entry.
8957
8958                if (i == 0
8959                        || withExcluded
8960                        || (tr.intent == null)
8961                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8962                                == 0)) {
8963                    if (!allowed) {
8964                        // If the caller doesn't have the GET_TASKS permission, then only
8965                        // allow them to see a small subset of tasks -- their own and home.
8966                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8967                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8968                            continue;
8969                        }
8970                    }
8971                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8972                        if (tr.stack != null && tr.stack.isHomeStack()) {
8973                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8974                                    "Skipping, home stack task: " + tr);
8975                            continue;
8976                        }
8977                    }
8978                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
8979                        final ActivityStack stack = tr.stack;
8980                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
8981                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8982                                    "Skipping, top task in docked stack: " + tr);
8983                            continue;
8984                        }
8985                    }
8986                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8987                        if (tr.stack != null && tr.stack.isPinnedStack()) {
8988                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8989                                    "Skipping, pinned stack task: " + tr);
8990                            continue;
8991                        }
8992                    }
8993                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8994                        // Don't include auto remove tasks that are finished or finishing.
8995                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8996                                "Skipping, auto-remove without activity: " + tr);
8997                        continue;
8998                    }
8999                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9000                            && !tr.isAvailable) {
9001                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9002                                "Skipping, unavail real act: " + tr);
9003                        continue;
9004                    }
9005
9006                    if (!tr.mUserSetupComplete) {
9007                        // Don't include task launched while user is not done setting-up.
9008                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9009                                "Skipping, user setup not complete: " + tr);
9010                        continue;
9011                    }
9012
9013                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9014                    if (!detailed) {
9015                        rti.baseIntent.replaceExtras((Bundle)null);
9016                    }
9017
9018                    res.add(rti);
9019                    maxNum--;
9020                }
9021            }
9022            return res;
9023        }
9024    }
9025
9026    @Override
9027    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9028        synchronized (this) {
9029            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9030                    "getTaskThumbnail()");
9031            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9032                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9033            if (tr != null) {
9034                return tr.getTaskThumbnailLocked();
9035            }
9036        }
9037        return null;
9038    }
9039
9040    @Override
9041    public int addAppTask(IBinder activityToken, Intent intent,
9042            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9043        final int callingUid = Binder.getCallingUid();
9044        final long callingIdent = Binder.clearCallingIdentity();
9045
9046        try {
9047            synchronized (this) {
9048                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9049                if (r == null) {
9050                    throw new IllegalArgumentException("Activity does not exist; token="
9051                            + activityToken);
9052                }
9053                ComponentName comp = intent.getComponent();
9054                if (comp == null) {
9055                    throw new IllegalArgumentException("Intent " + intent
9056                            + " must specify explicit component");
9057                }
9058                if (thumbnail.getWidth() != mThumbnailWidth
9059                        || thumbnail.getHeight() != mThumbnailHeight) {
9060                    throw new IllegalArgumentException("Bad thumbnail size: got "
9061                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9062                            + mThumbnailWidth + "x" + mThumbnailHeight);
9063                }
9064                if (intent.getSelector() != null) {
9065                    intent.setSelector(null);
9066                }
9067                if (intent.getSourceBounds() != null) {
9068                    intent.setSourceBounds(null);
9069                }
9070                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9071                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9072                        // The caller has added this as an auto-remove task...  that makes no
9073                        // sense, so turn off auto-remove.
9074                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9075                    }
9076                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9077                    // Must be a new task.
9078                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9079                }
9080                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9081                    mLastAddedTaskActivity = null;
9082                }
9083                ActivityInfo ainfo = mLastAddedTaskActivity;
9084                if (ainfo == null) {
9085                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9086                            comp, 0, UserHandle.getUserId(callingUid));
9087                    if (ainfo.applicationInfo.uid != callingUid) {
9088                        throw new SecurityException(
9089                                "Can't add task for another application: target uid="
9090                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9091                    }
9092                }
9093
9094                // Use the full screen as the context for the task thumbnail
9095                final Point displaySize = new Point();
9096                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9097                r.task.stack.getDisplaySize(displaySize);
9098                thumbnailInfo.taskWidth = displaySize.x;
9099                thumbnailInfo.taskHeight = displaySize.y;
9100                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9101
9102                TaskRecord task = new TaskRecord(this,
9103                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9104                        ainfo, intent, description, thumbnailInfo);
9105
9106                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9107                if (trimIdx >= 0) {
9108                    // If this would have caused a trim, then we'll abort because that
9109                    // means it would be added at the end of the list but then just removed.
9110                    return INVALID_TASK_ID;
9111                }
9112
9113                final int N = mRecentTasks.size();
9114                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9115                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9116                    tr.removedFromRecents();
9117                }
9118
9119                task.inRecents = true;
9120                mRecentTasks.add(task);
9121                r.task.stack.addTask(task, false, "addAppTask");
9122
9123                task.setLastThumbnailLocked(thumbnail);
9124                task.freeLastThumbnail();
9125
9126                return task.taskId;
9127            }
9128        } finally {
9129            Binder.restoreCallingIdentity(callingIdent);
9130        }
9131    }
9132
9133    @Override
9134    public Point getAppTaskThumbnailSize() {
9135        synchronized (this) {
9136            return new Point(mThumbnailWidth,  mThumbnailHeight);
9137        }
9138    }
9139
9140    @Override
9141    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9142        synchronized (this) {
9143            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9144            if (r != null) {
9145                r.setTaskDescription(td);
9146                r.task.updateTaskDescription();
9147            }
9148        }
9149    }
9150
9151    @Override
9152    public void setTaskResizeable(int taskId, int resizeableMode) {
9153        synchronized (this) {
9154            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9155                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9156            if (task == null) {
9157                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9158                return;
9159            }
9160            if (task.mResizeMode != resizeableMode) {
9161                task.mResizeMode = resizeableMode;
9162                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9163                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9164                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9165            }
9166        }
9167    }
9168
9169    @Override
9170    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9171        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9172        long ident = Binder.clearCallingIdentity();
9173        try {
9174            synchronized (this) {
9175                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9176                if (task == null) {
9177                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9178                    return;
9179                }
9180                int stackId = task.stack.mStackId;
9181                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9182                // in crop windows resize mode or if the task size is affected by the docked stack
9183                // changing size. No need to update configuration.
9184                if (bounds != null && task.inCropWindowsResizeMode()
9185                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9186                    mWindowManager.scrollTask(task.taskId, bounds);
9187                    return;
9188                }
9189
9190                // Place the task in the right stack if it isn't there already based on
9191                // the requested bounds.
9192                // The stack transition logic is:
9193                // - a null bounds on a freeform task moves that task to fullscreen
9194                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9195                //   that task to freeform
9196                // - otherwise the task is not moved
9197                if (!StackId.isTaskResizeAllowed(stackId)) {
9198                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9199                }
9200                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9201                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9202                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9203                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9204                }
9205                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9206                if (stackId != task.stack.mStackId) {
9207                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9208                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9209                    preserveWindow = false;
9210                }
9211
9212                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9213                        false /* deferResume */);
9214            }
9215        } finally {
9216            Binder.restoreCallingIdentity(ident);
9217        }
9218    }
9219
9220    @Override
9221    public Rect getTaskBounds(int taskId) {
9222        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9223        long ident = Binder.clearCallingIdentity();
9224        Rect rect = new Rect();
9225        try {
9226            synchronized (this) {
9227                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9228                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9229                if (task == null) {
9230                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9231                    return rect;
9232                }
9233                if (task.stack != null) {
9234                    // Return the bounds from window manager since it will be adjusted for various
9235                    // things like the presense of a docked stack for tasks that aren't resizeable.
9236                    mWindowManager.getTaskBounds(task.taskId, rect);
9237                } else {
9238                    // Task isn't in window manager yet since it isn't associated with a stack.
9239                    // Return the persist value from activity manager
9240                    if (task.mBounds != null) {
9241                        rect.set(task.mBounds);
9242                    } else if (task.mLastNonFullscreenBounds != null) {
9243                        rect.set(task.mLastNonFullscreenBounds);
9244                    }
9245                }
9246            }
9247        } finally {
9248            Binder.restoreCallingIdentity(ident);
9249        }
9250        return rect;
9251    }
9252
9253    @Override
9254    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9255        if (userId != UserHandle.getCallingUserId()) {
9256            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9257                    "getTaskDescriptionIcon");
9258        }
9259        final File passedIconFile = new File(filePath);
9260        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9261                passedIconFile.getName());
9262        if (!legitIconFile.getPath().equals(filePath)
9263                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9264            throw new IllegalArgumentException("Bad file path: " + filePath
9265                    + " passed for userId " + userId);
9266        }
9267        return mRecentTasks.getTaskDescriptionIcon(filePath);
9268    }
9269
9270    @Override
9271    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9272            throws RemoteException {
9273        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9274                opts.getCustomInPlaceResId() == 0) {
9275            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9276                    "with valid animation");
9277        }
9278        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9279        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9280                opts.getCustomInPlaceResId());
9281        mWindowManager.executeAppTransition();
9282    }
9283
9284    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9285            boolean removeFromRecents) {
9286        if (removeFromRecents) {
9287            mRecentTasks.remove(tr);
9288            tr.removedFromRecents();
9289        }
9290        ComponentName component = tr.getBaseIntent().getComponent();
9291        if (component == null) {
9292            Slog.w(TAG, "No component for base intent of task: " + tr);
9293            return;
9294        }
9295
9296        // Find any running services associated with this app and stop if needed.
9297        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9298
9299        if (!killProcess) {
9300            return;
9301        }
9302
9303        // Determine if the process(es) for this task should be killed.
9304        final String pkg = component.getPackageName();
9305        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9306        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9307        for (int i = 0; i < pmap.size(); i++) {
9308
9309            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9310            for (int j = 0; j < uids.size(); j++) {
9311                ProcessRecord proc = uids.valueAt(j);
9312                if (proc.userId != tr.userId) {
9313                    // Don't kill process for a different user.
9314                    continue;
9315                }
9316                if (proc == mHomeProcess) {
9317                    // Don't kill the home process along with tasks from the same package.
9318                    continue;
9319                }
9320                if (!proc.pkgList.containsKey(pkg)) {
9321                    // Don't kill process that is not associated with this task.
9322                    continue;
9323                }
9324
9325                for (int k = 0; k < proc.activities.size(); k++) {
9326                    TaskRecord otherTask = proc.activities.get(k).task;
9327                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9328                        // Don't kill process(es) that has an activity in a different task that is
9329                        // also in recents.
9330                        return;
9331                    }
9332                }
9333
9334                if (proc.foregroundServices) {
9335                    // Don't kill process(es) with foreground service.
9336                    return;
9337                }
9338
9339                // Add process to kill list.
9340                procsToKill.add(proc);
9341            }
9342        }
9343
9344        // Kill the running processes.
9345        for (int i = 0; i < procsToKill.size(); i++) {
9346            ProcessRecord pr = procsToKill.get(i);
9347            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9348                    && pr.curReceiver == null) {
9349                pr.kill("remove task", true);
9350            } else {
9351                // We delay killing processes that are not in the background or running a receiver.
9352                pr.waitingToKill = "remove task";
9353            }
9354        }
9355    }
9356
9357    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9358        // Remove all tasks with activities in the specified package from the list of recent tasks
9359        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9360            TaskRecord tr = mRecentTasks.get(i);
9361            if (tr.userId != userId) continue;
9362
9363            ComponentName cn = tr.intent.getComponent();
9364            if (cn != null && cn.getPackageName().equals(packageName)) {
9365                // If the package name matches, remove the task.
9366                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9367            }
9368        }
9369    }
9370
9371    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9372            int userId) {
9373
9374        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9375            TaskRecord tr = mRecentTasks.get(i);
9376            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9377                continue;
9378            }
9379
9380            ComponentName cn = tr.intent.getComponent();
9381            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9382                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9383            if (sameComponent) {
9384                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9385            }
9386        }
9387    }
9388
9389    /**
9390     * Removes the task with the specified task id.
9391     *
9392     * @param taskId Identifier of the task to be removed.
9393     * @param killProcess Kill any process associated with the task if possible.
9394     * @param removeFromRecents Whether to also remove the task from recents.
9395     * @return Returns true if the given task was found and removed.
9396     */
9397    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9398            boolean removeFromRecents) {
9399        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9400                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9401        if (tr != null) {
9402            tr.removeTaskActivitiesLocked();
9403            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9404            if (tr.isPersistable) {
9405                notifyTaskPersisterLocked(null, true);
9406            }
9407            return true;
9408        }
9409        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9410        return false;
9411    }
9412
9413    @Override
9414    public void removeStack(int stackId) {
9415        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9416        if (stackId == HOME_STACK_ID) {
9417            throw new IllegalArgumentException("Removing home stack is not allowed.");
9418        }
9419
9420        synchronized (this) {
9421            final long ident = Binder.clearCallingIdentity();
9422            try {
9423                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9424                if (stack == null) {
9425                    return;
9426                }
9427                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9428                for (int i = tasks.size() - 1; i >= 0; i--) {
9429                    removeTaskByIdLocked(
9430                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9431                }
9432            } finally {
9433                Binder.restoreCallingIdentity(ident);
9434            }
9435        }
9436    }
9437
9438    @Override
9439    public boolean removeTask(int taskId) {
9440        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9441        synchronized (this) {
9442            final long ident = Binder.clearCallingIdentity();
9443            try {
9444                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9445            } finally {
9446                Binder.restoreCallingIdentity(ident);
9447            }
9448        }
9449    }
9450
9451    /**
9452     * TODO: Add mController hook
9453     */
9454    @Override
9455    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9456        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9457
9458        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9459        synchronized(this) {
9460            moveTaskToFrontLocked(taskId, flags, bOptions);
9461        }
9462    }
9463
9464    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9465        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9466
9467        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9468                Binder.getCallingUid(), -1, -1, "Task to front")) {
9469            ActivityOptions.abort(options);
9470            return;
9471        }
9472        final long origId = Binder.clearCallingIdentity();
9473        try {
9474            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9475            if (task == null) {
9476                Slog.d(TAG, "Could not find task for id: "+ taskId);
9477                return;
9478            }
9479            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9480                mStackSupervisor.showLockTaskToast();
9481                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9482                return;
9483            }
9484            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9485            if (prev != null && prev.isRecentsActivity()) {
9486                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9487            }
9488            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9489                    false /* forceNonResizable */);
9490        } finally {
9491            Binder.restoreCallingIdentity(origId);
9492        }
9493        ActivityOptions.abort(options);
9494    }
9495
9496    /**
9497     * Moves an activity, and all of the other activities within the same task, to the bottom
9498     * of the history stack.  The activity's order within the task is unchanged.
9499     *
9500     * @param token A reference to the activity we wish to move
9501     * @param nonRoot If false then this only works if the activity is the root
9502     *                of a task; if true it will work for any activity in a task.
9503     * @return Returns true if the move completed, false if not.
9504     */
9505    @Override
9506    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9507        enforceNotIsolatedCaller("moveActivityTaskToBack");
9508        synchronized(this) {
9509            final long origId = Binder.clearCallingIdentity();
9510            try {
9511                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9512                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9513                if (task != null) {
9514                    if (mStackSupervisor.isLockedTask(task)) {
9515                        mStackSupervisor.showLockTaskToast();
9516                        return false;
9517                    }
9518                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9519                }
9520            } finally {
9521                Binder.restoreCallingIdentity(origId);
9522            }
9523        }
9524        return false;
9525    }
9526
9527    @Override
9528    public void moveTaskBackwards(int task) {
9529        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9530                "moveTaskBackwards()");
9531
9532        synchronized(this) {
9533            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9534                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9535                return;
9536            }
9537            final long origId = Binder.clearCallingIdentity();
9538            moveTaskBackwardsLocked(task);
9539            Binder.restoreCallingIdentity(origId);
9540        }
9541    }
9542
9543    private final void moveTaskBackwardsLocked(int task) {
9544        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9545    }
9546
9547    @Override
9548    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9549            IActivityContainerCallback callback) throws RemoteException {
9550        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9551        synchronized (this) {
9552            if (parentActivityToken == null) {
9553                throw new IllegalArgumentException("parent token must not be null");
9554            }
9555            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9556            if (r == null) {
9557                return null;
9558            }
9559            if (callback == null) {
9560                throw new IllegalArgumentException("callback must not be null");
9561            }
9562            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9563        }
9564    }
9565
9566    @Override
9567    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9568        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9569        synchronized (this) {
9570            mStackSupervisor.deleteActivityContainer(container);
9571        }
9572    }
9573
9574    @Override
9575    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9576        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9577        synchronized (this) {
9578            final int stackId = mStackSupervisor.getNextStackId();
9579            final ActivityStack stack =
9580                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9581            if (stack == null) {
9582                return null;
9583            }
9584            return stack.mActivityContainer;
9585        }
9586    }
9587
9588    @Override
9589    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9590        synchronized (this) {
9591            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9592            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9593                return stack.mActivityContainer.getDisplayId();
9594            }
9595            return Display.DEFAULT_DISPLAY;
9596        }
9597    }
9598
9599    @Override
9600    public int getActivityStackId(IBinder token) throws RemoteException {
9601        synchronized (this) {
9602            ActivityStack stack = ActivityRecord.getStackLocked(token);
9603            if (stack == null) {
9604                return INVALID_STACK_ID;
9605            }
9606            return stack.mStackId;
9607        }
9608    }
9609
9610    @Override
9611    public void exitFreeformMode(IBinder token) throws RemoteException {
9612        synchronized (this) {
9613            long ident = Binder.clearCallingIdentity();
9614            try {
9615                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9616                if (r == null) {
9617                    throw new IllegalArgumentException(
9618                            "exitFreeformMode: No activity record matching token=" + token);
9619                }
9620                final ActivityStack stack = r.getStackLocked(token);
9621                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9622                    throw new IllegalStateException(
9623                            "exitFreeformMode: You can only go fullscreen from freeform.");
9624                }
9625                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9626                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9627                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9628            } finally {
9629                Binder.restoreCallingIdentity(ident);
9630            }
9631        }
9632    }
9633
9634    @Override
9635    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9636        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9637        if (stackId == HOME_STACK_ID) {
9638            throw new IllegalArgumentException(
9639                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9640        }
9641        synchronized (this) {
9642            long ident = Binder.clearCallingIdentity();
9643            try {
9644                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9645                        + " to stackId=" + stackId + " toTop=" + toTop);
9646                if (stackId == DOCKED_STACK_ID) {
9647                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9648                            null /* initialBounds */);
9649                }
9650                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9651                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9652                if (result && stackId == DOCKED_STACK_ID) {
9653                    // If task moved to docked stack - show recents if needed.
9654                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9655                            "moveTaskToDockedStack");
9656                }
9657            } finally {
9658                Binder.restoreCallingIdentity(ident);
9659            }
9660        }
9661    }
9662
9663    @Override
9664    public void swapDockedAndFullscreenStack() throws RemoteException {
9665        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9666        synchronized (this) {
9667            long ident = Binder.clearCallingIdentity();
9668            try {
9669                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9670                        FULLSCREEN_WORKSPACE_STACK_ID);
9671                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9672                        : null;
9673                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9674                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9675                        : null;
9676                if (topTask == null || tasks == null || tasks.size() == 0) {
9677                    Slog.w(TAG,
9678                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9679                    return;
9680                }
9681
9682                // TODO: App transition
9683                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9684
9685                // Defer the resume so resume/pausing while moving stacks is dangerous.
9686                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9687                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9688                        ANIMATE, true /* deferResume */);
9689                final int size = tasks.size();
9690                for (int i = 0; i < size; i++) {
9691                    final int id = tasks.get(i).taskId;
9692                    if (id == topTask.taskId) {
9693                        continue;
9694                    }
9695                    mStackSupervisor.moveTaskToStackLocked(id,
9696                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9697                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9698                }
9699
9700                // Because we deferred the resume, to avoid conflicts with stack switches while
9701                // resuming, we need to do it after all the tasks are moved.
9702                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9703                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9704
9705                mWindowManager.executeAppTransition();
9706            } finally {
9707                Binder.restoreCallingIdentity(ident);
9708            }
9709        }
9710    }
9711
9712    /**
9713     * Moves the input task to the docked stack.
9714     *
9715     * @param taskId Id of task to move.
9716     * @param createMode The mode the docked stack should be created in if it doesn't exist
9717     *                   already. See
9718     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9719     *                   and
9720     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9721     * @param toTop If the task and stack should be moved to the top.
9722     * @param animate Whether we should play an animation for the moving the task
9723     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9724     *                      docked stack. Pass {@code null} to use default bounds.
9725     */
9726    @Override
9727    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9728            Rect initialBounds, boolean moveHomeStackFront) {
9729        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9730        synchronized (this) {
9731            long ident = Binder.clearCallingIdentity();
9732            try {
9733                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9734                        + " to createMode=" + createMode + " toTop=" + toTop);
9735                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9736                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9737                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9738                        animate, DEFER_RESUME);
9739                if (moved) {
9740                    if (moveHomeStackFront) {
9741                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9742                    }
9743                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9744                }
9745                return moved;
9746            } finally {
9747                Binder.restoreCallingIdentity(ident);
9748            }
9749        }
9750    }
9751
9752    /**
9753     * Moves the top activity in the input stackId to the pinned stack.
9754     *
9755     * @param stackId Id of stack to move the top activity to pinned stack.
9756     * @param bounds Bounds to use for pinned stack.
9757     *
9758     * @return True if the top activity of the input stack was successfully moved to the pinned
9759     *          stack.
9760     */
9761    @Override
9762    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9763        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9764        synchronized (this) {
9765            if (!mSupportsPictureInPicture) {
9766                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9767                        + "Device doesn't support picture-in-pciture mode");
9768            }
9769
9770            long ident = Binder.clearCallingIdentity();
9771            try {
9772                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9773            } finally {
9774                Binder.restoreCallingIdentity(ident);
9775            }
9776        }
9777    }
9778
9779    @Override
9780    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9781            boolean preserveWindows, boolean animate, int animationDuration) {
9782        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9783        long ident = Binder.clearCallingIdentity();
9784        try {
9785            synchronized (this) {
9786                if (animate) {
9787                    if (stackId == PINNED_STACK_ID) {
9788                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9789                    } else {
9790                        throw new IllegalArgumentException("Stack: " + stackId
9791                                + " doesn't support animated resize.");
9792                    }
9793                } else {
9794                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9795                            null /* tempTaskInsetBounds */, preserveWindows,
9796                            allowResizeInDockedMode, !DEFER_RESUME);
9797                }
9798            }
9799        } finally {
9800            Binder.restoreCallingIdentity(ident);
9801        }
9802    }
9803
9804    @Override
9805    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9806            Rect tempDockedTaskInsetBounds,
9807            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9808        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9809                "resizeDockedStack()");
9810        long ident = Binder.clearCallingIdentity();
9811        try {
9812            synchronized (this) {
9813                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9814                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9815                        PRESERVE_WINDOWS);
9816            }
9817        } finally {
9818            Binder.restoreCallingIdentity(ident);
9819        }
9820    }
9821
9822    @Override
9823    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9824        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9825                "resizePinnedStack()");
9826        final long ident = Binder.clearCallingIdentity();
9827        try {
9828            synchronized (this) {
9829                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9830            }
9831        } finally {
9832            Binder.restoreCallingIdentity(ident);
9833        }
9834    }
9835
9836    @Override
9837    public void positionTaskInStack(int taskId, int stackId, int position) {
9838        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9839        if (stackId == HOME_STACK_ID) {
9840            throw new IllegalArgumentException(
9841                    "positionTaskInStack: Attempt to change the position of task "
9842                    + taskId + " in/to home stack");
9843        }
9844        synchronized (this) {
9845            long ident = Binder.clearCallingIdentity();
9846            try {
9847                if (DEBUG_STACK) Slog.d(TAG_STACK,
9848                        "positionTaskInStack: positioning task=" + taskId
9849                        + " in stackId=" + stackId + " at position=" + position);
9850                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9851            } finally {
9852                Binder.restoreCallingIdentity(ident);
9853            }
9854        }
9855    }
9856
9857    @Override
9858    public List<StackInfo> getAllStackInfos() {
9859        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9860        long ident = Binder.clearCallingIdentity();
9861        try {
9862            synchronized (this) {
9863                return mStackSupervisor.getAllStackInfosLocked();
9864            }
9865        } finally {
9866            Binder.restoreCallingIdentity(ident);
9867        }
9868    }
9869
9870    @Override
9871    public StackInfo getStackInfo(int stackId) {
9872        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9873        long ident = Binder.clearCallingIdentity();
9874        try {
9875            synchronized (this) {
9876                return mStackSupervisor.getStackInfoLocked(stackId);
9877            }
9878        } finally {
9879            Binder.restoreCallingIdentity(ident);
9880        }
9881    }
9882
9883    @Override
9884    public boolean isInHomeStack(int taskId) {
9885        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9886        long ident = Binder.clearCallingIdentity();
9887        try {
9888            synchronized (this) {
9889                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9890                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9891                return tr != null && tr.stack != null && tr.stack.isHomeStack();
9892            }
9893        } finally {
9894            Binder.restoreCallingIdentity(ident);
9895        }
9896    }
9897
9898    @Override
9899    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9900        synchronized(this) {
9901            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9902        }
9903    }
9904
9905    @Override
9906    public void updateDeviceOwner(String packageName) {
9907        final int callingUid = Binder.getCallingUid();
9908        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9909            throw new SecurityException("updateDeviceOwner called from non-system process");
9910        }
9911        synchronized (this) {
9912            mDeviceOwnerName = packageName;
9913        }
9914    }
9915
9916    @Override
9917    public void updateLockTaskPackages(int userId, String[] packages) {
9918        final int callingUid = Binder.getCallingUid();
9919        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9920            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
9921                    "updateLockTaskPackages()");
9922        }
9923        synchronized (this) {
9924            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9925                    Arrays.toString(packages));
9926            mLockTaskPackages.put(userId, packages);
9927            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9928        }
9929    }
9930
9931
9932    void startLockTaskModeLocked(TaskRecord task) {
9933        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9934        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9935            return;
9936        }
9937
9938        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9939        // is initiated by system after the pinning request was shown and locked mode is initiated
9940        // by an authorized app directly
9941        final int callingUid = Binder.getCallingUid();
9942        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9943        long ident = Binder.clearCallingIdentity();
9944        try {
9945            if (!isSystemInitiated) {
9946                task.mLockTaskUid = callingUid;
9947                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9948                    // startLockTask() called by app and task mode is lockTaskModeDefault.
9949                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9950                    StatusBarManagerInternal statusBarManager =
9951                            LocalServices.getService(StatusBarManagerInternal.class);
9952                    if (statusBarManager != null) {
9953                        statusBarManager.showScreenPinningRequest(task.taskId);
9954                    }
9955                    return;
9956                }
9957
9958                final ActivityStack stack = mStackSupervisor.getFocusedStack();
9959                if (stack == null || task != stack.topTask()) {
9960                    throw new IllegalArgumentException("Invalid task, not in foreground");
9961                }
9962            }
9963            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9964                    "Locking fully");
9965            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9966                    ActivityManager.LOCK_TASK_MODE_PINNED :
9967                    ActivityManager.LOCK_TASK_MODE_LOCKED,
9968                    "startLockTask", true);
9969        } finally {
9970            Binder.restoreCallingIdentity(ident);
9971        }
9972    }
9973
9974    @Override
9975    public void startLockTaskMode(int taskId) {
9976        synchronized (this) {
9977            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9978            if (task != null) {
9979                startLockTaskModeLocked(task);
9980            }
9981        }
9982    }
9983
9984    @Override
9985    public void startLockTaskMode(IBinder token) {
9986        synchronized (this) {
9987            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9988            if (r == null) {
9989                return;
9990            }
9991            final TaskRecord task = r.task;
9992            if (task != null) {
9993                startLockTaskModeLocked(task);
9994            }
9995        }
9996    }
9997
9998    @Override
9999    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10000        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10001        // This makes inner call to look as if it was initiated by system.
10002        long ident = Binder.clearCallingIdentity();
10003        try {
10004            synchronized (this) {
10005                startLockTaskMode(taskId);
10006            }
10007        } finally {
10008            Binder.restoreCallingIdentity(ident);
10009        }
10010    }
10011
10012    @Override
10013    public void stopLockTaskMode() {
10014        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10015        if (lockTask == null) {
10016            // Our work here is done.
10017            return;
10018        }
10019
10020        final int callingUid = Binder.getCallingUid();
10021        final int lockTaskUid = lockTask.mLockTaskUid;
10022        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10023        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10024            // Done.
10025            return;
10026        } else {
10027            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10028            // It is possible lockTaskMode was started by the system process because
10029            // android:lockTaskMode is set to a locking value in the application manifest
10030            // instead of the app calling startLockTaskMode. In this case
10031            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10032            // {@link TaskRecord.effectiveUid} instead. Also caller with
10033            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10034            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10035                    && callingUid != lockTaskUid
10036                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10037                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10038                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10039            }
10040        }
10041        long ident = Binder.clearCallingIdentity();
10042        try {
10043            Log.d(TAG, "stopLockTaskMode");
10044            // Stop lock task
10045            synchronized (this) {
10046                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10047                        "stopLockTask", true);
10048            }
10049        } finally {
10050            Binder.restoreCallingIdentity(ident);
10051        }
10052    }
10053
10054    /**
10055     * This API should be called by SystemUI only when user perform certain action to dismiss
10056     * lock task mode. We should only dismiss pinned lock task mode in this case.
10057     */
10058    @Override
10059    public void stopSystemLockTaskMode() throws RemoteException {
10060        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10061            stopLockTaskMode();
10062        } else {
10063            mStackSupervisor.showLockTaskToast();
10064        }
10065    }
10066
10067    @Override
10068    public boolean isInLockTaskMode() {
10069        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10070    }
10071
10072    @Override
10073    public int getLockTaskModeState() {
10074        synchronized (this) {
10075            return mStackSupervisor.getLockTaskModeState();
10076        }
10077    }
10078
10079    @Override
10080    public void showLockTaskEscapeMessage(IBinder token) {
10081        synchronized (this) {
10082            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10083            if (r == null) {
10084                return;
10085            }
10086            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10087        }
10088    }
10089
10090    // =========================================================
10091    // CONTENT PROVIDERS
10092    // =========================================================
10093
10094    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10095        List<ProviderInfo> providers = null;
10096        try {
10097            providers = AppGlobals.getPackageManager()
10098                    .queryContentProviders(app.processName, app.uid,
10099                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10100                                    | MATCH_DEBUG_TRIAGED_MISSING)
10101                    .getList();
10102        } catch (RemoteException ex) {
10103        }
10104        if (DEBUG_MU) Slog.v(TAG_MU,
10105                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10106        int userId = app.userId;
10107        if (providers != null) {
10108            int N = providers.size();
10109            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10110            for (int i=0; i<N; i++) {
10111                ProviderInfo cpi =
10112                    (ProviderInfo)providers.get(i);
10113                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10114                        cpi.name, cpi.flags);
10115                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10116                    // This is a singleton provider, but a user besides the
10117                    // default user is asking to initialize a process it runs
10118                    // in...  well, no, it doesn't actually run in this process,
10119                    // it runs in the process of the default user.  Get rid of it.
10120                    providers.remove(i);
10121                    N--;
10122                    i--;
10123                    continue;
10124                }
10125
10126                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10127                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10128                if (cpr == null) {
10129                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10130                    mProviderMap.putProviderByClass(comp, cpr);
10131                }
10132                if (DEBUG_MU) Slog.v(TAG_MU,
10133                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10134                app.pubProviders.put(cpi.name, cpr);
10135                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10136                    // Don't add this if it is a platform component that is marked
10137                    // to run in multiple processes, because this is actually
10138                    // part of the framework so doesn't make sense to track as a
10139                    // separate apk in the process.
10140                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10141                            mProcessStats);
10142                }
10143                notifyPackageUse(cpi.applicationInfo.packageName,
10144                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10145            }
10146        }
10147        return providers;
10148    }
10149
10150    /**
10151     * Check if {@link ProcessRecord} has a possible chance at accessing the
10152     * given {@link ProviderInfo}. Final permission checking is always done
10153     * in {@link ContentProvider}.
10154     */
10155    private final String checkContentProviderPermissionLocked(
10156            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10157        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10158        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10159        boolean checkedGrants = false;
10160        if (checkUser) {
10161            // Looking for cross-user grants before enforcing the typical cross-users permissions
10162            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10163            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10164                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10165                    return null;
10166                }
10167                checkedGrants = true;
10168            }
10169            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10170                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10171            if (userId != tmpTargetUserId) {
10172                // When we actually went to determine the final targer user ID, this ended
10173                // up different than our initial check for the authority.  This is because
10174                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10175                // SELF.  So we need to re-check the grants again.
10176                checkedGrants = false;
10177            }
10178        }
10179        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10180                cpi.applicationInfo.uid, cpi.exported)
10181                == PackageManager.PERMISSION_GRANTED) {
10182            return null;
10183        }
10184        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10185                cpi.applicationInfo.uid, cpi.exported)
10186                == PackageManager.PERMISSION_GRANTED) {
10187            return null;
10188        }
10189
10190        PathPermission[] pps = cpi.pathPermissions;
10191        if (pps != null) {
10192            int i = pps.length;
10193            while (i > 0) {
10194                i--;
10195                PathPermission pp = pps[i];
10196                String pprperm = pp.getReadPermission();
10197                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10198                        cpi.applicationInfo.uid, cpi.exported)
10199                        == PackageManager.PERMISSION_GRANTED) {
10200                    return null;
10201                }
10202                String ppwperm = pp.getWritePermission();
10203                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10204                        cpi.applicationInfo.uid, cpi.exported)
10205                        == PackageManager.PERMISSION_GRANTED) {
10206                    return null;
10207                }
10208            }
10209        }
10210        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10211            return null;
10212        }
10213
10214        String msg;
10215        if (!cpi.exported) {
10216            msg = "Permission Denial: opening provider " + cpi.name
10217                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10218                    + ", uid=" + callingUid + ") that is not exported from uid "
10219                    + cpi.applicationInfo.uid;
10220        } else {
10221            msg = "Permission Denial: opening provider " + cpi.name
10222                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10223                    + ", uid=" + callingUid + ") requires "
10224                    + cpi.readPermission + " or " + cpi.writePermission;
10225        }
10226        Slog.w(TAG, msg);
10227        return msg;
10228    }
10229
10230    /**
10231     * Returns if the ContentProvider has granted a uri to callingUid
10232     */
10233    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10234        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10235        if (perms != null) {
10236            for (int i=perms.size()-1; i>=0; i--) {
10237                GrantUri grantUri = perms.keyAt(i);
10238                if (grantUri.sourceUserId == userId || !checkUser) {
10239                    if (matchesProvider(grantUri.uri, cpi)) {
10240                        return true;
10241                    }
10242                }
10243            }
10244        }
10245        return false;
10246    }
10247
10248    /**
10249     * Returns true if the uri authority is one of the authorities specified in the provider.
10250     */
10251    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10252        String uriAuth = uri.getAuthority();
10253        String cpiAuth = cpi.authority;
10254        if (cpiAuth.indexOf(';') == -1) {
10255            return cpiAuth.equals(uriAuth);
10256        }
10257        String[] cpiAuths = cpiAuth.split(";");
10258        int length = cpiAuths.length;
10259        for (int i = 0; i < length; i++) {
10260            if (cpiAuths[i].equals(uriAuth)) return true;
10261        }
10262        return false;
10263    }
10264
10265    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10266            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10267        if (r != null) {
10268            for (int i=0; i<r.conProviders.size(); i++) {
10269                ContentProviderConnection conn = r.conProviders.get(i);
10270                if (conn.provider == cpr) {
10271                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10272                            "Adding provider requested by "
10273                            + r.processName + " from process "
10274                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10275                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10276                    if (stable) {
10277                        conn.stableCount++;
10278                        conn.numStableIncs++;
10279                    } else {
10280                        conn.unstableCount++;
10281                        conn.numUnstableIncs++;
10282                    }
10283                    return conn;
10284                }
10285            }
10286            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10287            if (stable) {
10288                conn.stableCount = 1;
10289                conn.numStableIncs = 1;
10290            } else {
10291                conn.unstableCount = 1;
10292                conn.numUnstableIncs = 1;
10293            }
10294            cpr.connections.add(conn);
10295            r.conProviders.add(conn);
10296            startAssociationLocked(r.uid, r.processName, r.curProcState,
10297                    cpr.uid, cpr.name, cpr.info.processName);
10298            return conn;
10299        }
10300        cpr.addExternalProcessHandleLocked(externalProcessToken);
10301        return null;
10302    }
10303
10304    boolean decProviderCountLocked(ContentProviderConnection conn,
10305            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10306        if (conn != null) {
10307            cpr = conn.provider;
10308            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10309                    "Removing provider requested by "
10310                    + conn.client.processName + " from process "
10311                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10312                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10313            if (stable) {
10314                conn.stableCount--;
10315            } else {
10316                conn.unstableCount--;
10317            }
10318            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10319                cpr.connections.remove(conn);
10320                conn.client.conProviders.remove(conn);
10321                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10322                    // The client is more important than last activity -- note the time this
10323                    // is happening, so we keep the old provider process around a bit as last
10324                    // activity to avoid thrashing it.
10325                    if (cpr.proc != null) {
10326                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10327                    }
10328                }
10329                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10330                return true;
10331            }
10332            return false;
10333        }
10334        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10335        return false;
10336    }
10337
10338    private void checkTime(long startTime, String where) {
10339        long now = SystemClock.uptimeMillis();
10340        if ((now-startTime) > 50) {
10341            // If we are taking more than 50ms, log about it.
10342            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10343        }
10344    }
10345
10346    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10347            String name, IBinder token, boolean stable, int userId) {
10348        ContentProviderRecord cpr;
10349        ContentProviderConnection conn = null;
10350        ProviderInfo cpi = null;
10351
10352        synchronized(this) {
10353            long startTime = SystemClock.uptimeMillis();
10354
10355            ProcessRecord r = null;
10356            if (caller != null) {
10357                r = getRecordForAppLocked(caller);
10358                if (r == null) {
10359                    throw new SecurityException(
10360                            "Unable to find app for caller " + caller
10361                          + " (pid=" + Binder.getCallingPid()
10362                          + ") when getting content provider " + name);
10363                }
10364            }
10365
10366            boolean checkCrossUser = true;
10367
10368            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10369
10370            // First check if this content provider has been published...
10371            cpr = mProviderMap.getProviderByName(name, userId);
10372            // If that didn't work, check if it exists for user 0 and then
10373            // verify that it's a singleton provider before using it.
10374            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10375                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10376                if (cpr != null) {
10377                    cpi = cpr.info;
10378                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10379                            cpi.name, cpi.flags)
10380                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10381                        userId = UserHandle.USER_SYSTEM;
10382                        checkCrossUser = false;
10383                    } else {
10384                        cpr = null;
10385                        cpi = null;
10386                    }
10387                }
10388            }
10389
10390            boolean providerRunning = cpr != null;
10391            if (providerRunning) {
10392                cpi = cpr.info;
10393                String msg;
10394                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10395                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10396                        != null) {
10397                    throw new SecurityException(msg);
10398                }
10399                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10400
10401                if (r != null && cpr.canRunHere(r)) {
10402                    // This provider has been published or is in the process
10403                    // of being published...  but it is also allowed to run
10404                    // in the caller's process, so don't make a connection
10405                    // and just let the caller instantiate its own instance.
10406                    ContentProviderHolder holder = cpr.newHolder(null);
10407                    // don't give caller the provider object, it needs
10408                    // to make its own.
10409                    holder.provider = null;
10410                    return holder;
10411                }
10412
10413                final long origId = Binder.clearCallingIdentity();
10414
10415                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10416
10417                // In this case the provider instance already exists, so we can
10418                // return it right away.
10419                conn = incProviderCountLocked(r, cpr, token, stable);
10420                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10421                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10422                        // If this is a perceptible app accessing the provider,
10423                        // make sure to count it as being accessed and thus
10424                        // back up on the LRU list.  This is good because
10425                        // content providers are often expensive to start.
10426                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10427                        updateLruProcessLocked(cpr.proc, false, null);
10428                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10429                    }
10430                }
10431
10432                if (cpr.proc != null) {
10433                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10434                    boolean success = updateOomAdjLocked(cpr.proc);
10435                    maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10436                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10437                    if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10438                    // NOTE: there is still a race here where a signal could be
10439                    // pending on the process even though we managed to update its
10440                    // adj level.  Not sure what to do about this, but at least
10441                    // the race is now smaller.
10442                    if (!success) {
10443                        // Uh oh...  it looks like the provider's process
10444                        // has been killed on us.  We need to wait for a new
10445                        // process to be started, and make sure its death
10446                        // doesn't kill our process.
10447                        Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10448                                + " is crashing; detaching " + r);
10449                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10450                        checkTime(startTime, "getContentProviderImpl: before appDied");
10451                        appDiedLocked(cpr.proc);
10452                        checkTime(startTime, "getContentProviderImpl: after appDied");
10453                        if (!lastRef) {
10454                            // This wasn't the last ref our process had on
10455                            // the provider...  we have now been killed, bail.
10456                            return null;
10457                        }
10458                        providerRunning = false;
10459                        conn = null;
10460                    }
10461                }
10462
10463                Binder.restoreCallingIdentity(origId);
10464            }
10465
10466            if (!providerRunning) {
10467                try {
10468                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10469                    cpi = AppGlobals.getPackageManager().
10470                        resolveContentProvider(name,
10471                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10472                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10473                } catch (RemoteException ex) {
10474                }
10475                if (cpi == null) {
10476                    return null;
10477                }
10478                // If the provider is a singleton AND
10479                // (it's a call within the same user || the provider is a
10480                // privileged app)
10481                // Then allow connecting to the singleton provider
10482                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10483                        cpi.name, cpi.flags)
10484                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10485                if (singleton) {
10486                    userId = UserHandle.USER_SYSTEM;
10487                }
10488                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10489                checkTime(startTime, "getContentProviderImpl: got app info for user");
10490
10491                String msg;
10492                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10493                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10494                        != null) {
10495                    throw new SecurityException(msg);
10496                }
10497                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10498
10499                if (!mProcessesReady
10500                        && !cpi.processName.equals("system")) {
10501                    // If this content provider does not run in the system
10502                    // process, and the system is not yet ready to run other
10503                    // processes, then fail fast instead of hanging.
10504                    throw new IllegalArgumentException(
10505                            "Attempt to launch content provider before system ready");
10506                }
10507
10508                // Make sure that the user who owns this provider is running.  If not,
10509                // we don't want to allow it to run.
10510                if (!mUserController.isUserRunningLocked(userId, 0)) {
10511                    Slog.w(TAG, "Unable to launch app "
10512                            + cpi.applicationInfo.packageName + "/"
10513                            + cpi.applicationInfo.uid + " for provider "
10514                            + name + ": user " + userId + " is stopped");
10515                    return null;
10516                }
10517
10518                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10519                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10520                cpr = mProviderMap.getProviderByClass(comp, userId);
10521                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10522                final boolean firstClass = cpr == null;
10523                if (firstClass) {
10524                    final long ident = Binder.clearCallingIdentity();
10525
10526                    // If permissions need a review before any of the app components can run,
10527                    // we return no provider and launch a review activity if the calling app
10528                    // is in the foreground.
10529                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10530                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10531                            return null;
10532                        }
10533                    }
10534
10535                    try {
10536                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10537                        ApplicationInfo ai =
10538                            AppGlobals.getPackageManager().
10539                                getApplicationInfo(
10540                                        cpi.applicationInfo.packageName,
10541                                        STOCK_PM_FLAGS, userId);
10542                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10543                        if (ai == null) {
10544                            Slog.w(TAG, "No package info for content provider "
10545                                    + cpi.name);
10546                            return null;
10547                        }
10548                        ai = getAppInfoForUser(ai, userId);
10549                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10550                    } catch (RemoteException ex) {
10551                        // pm is in same process, this will never happen.
10552                    } finally {
10553                        Binder.restoreCallingIdentity(ident);
10554                    }
10555                }
10556
10557                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10558
10559                if (r != null && cpr.canRunHere(r)) {
10560                    // If this is a multiprocess provider, then just return its
10561                    // info and allow the caller to instantiate it.  Only do
10562                    // this if the provider is the same user as the caller's
10563                    // process, or can run as root (so can be in any process).
10564                    return cpr.newHolder(null);
10565                }
10566
10567                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10568                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10569                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10570
10571                // This is single process, and our app is now connecting to it.
10572                // See if we are already in the process of launching this
10573                // provider.
10574                final int N = mLaunchingProviders.size();
10575                int i;
10576                for (i = 0; i < N; i++) {
10577                    if (mLaunchingProviders.get(i) == cpr) {
10578                        break;
10579                    }
10580                }
10581
10582                // If the provider is not already being launched, then get it
10583                // started.
10584                if (i >= N) {
10585                    final long origId = Binder.clearCallingIdentity();
10586
10587                    try {
10588                        // Content provider is now in use, its package can't be stopped.
10589                        try {
10590                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10591                            AppGlobals.getPackageManager().setPackageStoppedState(
10592                                    cpr.appInfo.packageName, false, userId);
10593                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10594                        } catch (RemoteException e) {
10595                        } catch (IllegalArgumentException e) {
10596                            Slog.w(TAG, "Failed trying to unstop package "
10597                                    + cpr.appInfo.packageName + ": " + e);
10598                        }
10599
10600                        // Use existing process if already started
10601                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10602                        ProcessRecord proc = getProcessRecordLocked(
10603                                cpi.processName, cpr.appInfo.uid, false);
10604                        if (proc != null && proc.thread != null) {
10605                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10606                                    "Installing in existing process " + proc);
10607                            if (!proc.pubProviders.containsKey(cpi.name)) {
10608                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10609                                proc.pubProviders.put(cpi.name, cpr);
10610                                try {
10611                                    proc.thread.scheduleInstallProvider(cpi);
10612                                } catch (RemoteException e) {
10613                                }
10614                            }
10615                        } else {
10616                            checkTime(startTime, "getContentProviderImpl: before start process");
10617                            proc = startProcessLocked(cpi.processName,
10618                                    cpr.appInfo, false, 0, "content provider",
10619                                    new ComponentName(cpi.applicationInfo.packageName,
10620                                            cpi.name), false, false, false);
10621                            checkTime(startTime, "getContentProviderImpl: after start process");
10622                            if (proc == null) {
10623                                Slog.w(TAG, "Unable to launch app "
10624                                        + cpi.applicationInfo.packageName + "/"
10625                                        + cpi.applicationInfo.uid + " for provider "
10626                                        + name + ": process is bad");
10627                                return null;
10628                            }
10629                        }
10630                        cpr.launchingApp = proc;
10631                        mLaunchingProviders.add(cpr);
10632                    } finally {
10633                        Binder.restoreCallingIdentity(origId);
10634                    }
10635                }
10636
10637                checkTime(startTime, "getContentProviderImpl: updating data structures");
10638
10639                // Make sure the provider is published (the same provider class
10640                // may be published under multiple names).
10641                if (firstClass) {
10642                    mProviderMap.putProviderByClass(comp, cpr);
10643                }
10644
10645                mProviderMap.putProviderByName(name, cpr);
10646                conn = incProviderCountLocked(r, cpr, token, stable);
10647                if (conn != null) {
10648                    conn.waiting = true;
10649                }
10650            }
10651            checkTime(startTime, "getContentProviderImpl: done!");
10652        }
10653
10654        // Wait for the provider to be published...
10655        synchronized (cpr) {
10656            while (cpr.provider == null) {
10657                if (cpr.launchingApp == null) {
10658                    Slog.w(TAG, "Unable to launch app "
10659                            + cpi.applicationInfo.packageName + "/"
10660                            + cpi.applicationInfo.uid + " for provider "
10661                            + name + ": launching app became null");
10662                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10663                            UserHandle.getUserId(cpi.applicationInfo.uid),
10664                            cpi.applicationInfo.packageName,
10665                            cpi.applicationInfo.uid, name);
10666                    return null;
10667                }
10668                try {
10669                    if (DEBUG_MU) Slog.v(TAG_MU,
10670                            "Waiting to start provider " + cpr
10671                            + " launchingApp=" + cpr.launchingApp);
10672                    if (conn != null) {
10673                        conn.waiting = true;
10674                    }
10675                    cpr.wait();
10676                } catch (InterruptedException ex) {
10677                } finally {
10678                    if (conn != null) {
10679                        conn.waiting = false;
10680                    }
10681                }
10682            }
10683        }
10684        return cpr != null ? cpr.newHolder(conn) : null;
10685    }
10686
10687    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10688            ProcessRecord r, final int userId) {
10689        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10690                cpi.packageName, userId)) {
10691
10692            final boolean callerForeground = r == null || r.setSchedGroup
10693                    != ProcessList.SCHED_GROUP_BACKGROUND;
10694
10695            // Show a permission review UI only for starting from a foreground app
10696            if (!callerForeground) {
10697                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10698                        + cpi.packageName + " requires a permissions review");
10699                return false;
10700            }
10701
10702            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10703            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10704                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10705            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10706
10707            if (DEBUG_PERMISSIONS_REVIEW) {
10708                Slog.i(TAG, "u" + userId + " Launching permission review "
10709                        + "for package " + cpi.packageName);
10710            }
10711
10712            final UserHandle userHandle = new UserHandle(userId);
10713            mHandler.post(new Runnable() {
10714                @Override
10715                public void run() {
10716                    mContext.startActivityAsUser(intent, userHandle);
10717                }
10718            });
10719
10720            return false;
10721        }
10722
10723        return true;
10724    }
10725
10726    PackageManagerInternal getPackageManagerInternalLocked() {
10727        if (mPackageManagerInt == null) {
10728            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10729        }
10730        return mPackageManagerInt;
10731    }
10732
10733    @Override
10734    public final ContentProviderHolder getContentProvider(
10735            IApplicationThread caller, String name, int userId, boolean stable) {
10736        enforceNotIsolatedCaller("getContentProvider");
10737        if (caller == null) {
10738            String msg = "null IApplicationThread when getting content provider "
10739                    + name;
10740            Slog.w(TAG, msg);
10741            throw new SecurityException(msg);
10742        }
10743        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10744        // with cross-user grant.
10745        return getContentProviderImpl(caller, name, null, stable, userId);
10746    }
10747
10748    public ContentProviderHolder getContentProviderExternal(
10749            String name, int userId, IBinder token) {
10750        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10751            "Do not have permission in call getContentProviderExternal()");
10752        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10753                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10754        return getContentProviderExternalUnchecked(name, token, userId);
10755    }
10756
10757    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10758            IBinder token, int userId) {
10759        return getContentProviderImpl(null, name, token, true, userId);
10760    }
10761
10762    /**
10763     * Drop a content provider from a ProcessRecord's bookkeeping
10764     */
10765    public void removeContentProvider(IBinder connection, boolean stable) {
10766        enforceNotIsolatedCaller("removeContentProvider");
10767        long ident = Binder.clearCallingIdentity();
10768        try {
10769            synchronized (this) {
10770                ContentProviderConnection conn;
10771                try {
10772                    conn = (ContentProviderConnection)connection;
10773                } catch (ClassCastException e) {
10774                    String msg ="removeContentProvider: " + connection
10775                            + " not a ContentProviderConnection";
10776                    Slog.w(TAG, msg);
10777                    throw new IllegalArgumentException(msg);
10778                }
10779                if (conn == null) {
10780                    throw new NullPointerException("connection is null");
10781                }
10782                if (decProviderCountLocked(conn, null, null, stable)) {
10783                    updateOomAdjLocked();
10784                }
10785            }
10786        } finally {
10787            Binder.restoreCallingIdentity(ident);
10788        }
10789    }
10790
10791    public void removeContentProviderExternal(String name, IBinder token) {
10792        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10793            "Do not have permission in call removeContentProviderExternal()");
10794        int userId = UserHandle.getCallingUserId();
10795        long ident = Binder.clearCallingIdentity();
10796        try {
10797            removeContentProviderExternalUnchecked(name, token, userId);
10798        } finally {
10799            Binder.restoreCallingIdentity(ident);
10800        }
10801    }
10802
10803    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10804        synchronized (this) {
10805            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10806            if(cpr == null) {
10807                //remove from mProvidersByClass
10808                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10809                return;
10810            }
10811
10812            //update content provider record entry info
10813            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10814            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10815            if (localCpr.hasExternalProcessHandles()) {
10816                if (localCpr.removeExternalProcessHandleLocked(token)) {
10817                    updateOomAdjLocked();
10818                } else {
10819                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10820                            + " with no external reference for token: "
10821                            + token + ".");
10822                }
10823            } else {
10824                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10825                        + " with no external references.");
10826            }
10827        }
10828    }
10829
10830    public final void publishContentProviders(IApplicationThread caller,
10831            List<ContentProviderHolder> providers) {
10832        if (providers == null) {
10833            return;
10834        }
10835
10836        enforceNotIsolatedCaller("publishContentProviders");
10837        synchronized (this) {
10838            final ProcessRecord r = getRecordForAppLocked(caller);
10839            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10840            if (r == null) {
10841                throw new SecurityException(
10842                        "Unable to find app for caller " + caller
10843                      + " (pid=" + Binder.getCallingPid()
10844                      + ") when publishing content providers");
10845            }
10846
10847            final long origId = Binder.clearCallingIdentity();
10848
10849            final int N = providers.size();
10850            for (int i = 0; i < N; i++) {
10851                ContentProviderHolder src = providers.get(i);
10852                if (src == null || src.info == null || src.provider == null) {
10853                    continue;
10854                }
10855                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10856                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10857                if (dst != null) {
10858                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10859                    mProviderMap.putProviderByClass(comp, dst);
10860                    String names[] = dst.info.authority.split(";");
10861                    for (int j = 0; j < names.length; j++) {
10862                        mProviderMap.putProviderByName(names[j], dst);
10863                    }
10864
10865                    int launchingCount = mLaunchingProviders.size();
10866                    int j;
10867                    boolean wasInLaunchingProviders = false;
10868                    for (j = 0; j < launchingCount; j++) {
10869                        if (mLaunchingProviders.get(j) == dst) {
10870                            mLaunchingProviders.remove(j);
10871                            wasInLaunchingProviders = true;
10872                            j--;
10873                            launchingCount--;
10874                        }
10875                    }
10876                    if (wasInLaunchingProviders) {
10877                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10878                    }
10879                    synchronized (dst) {
10880                        dst.provider = src.provider;
10881                        dst.proc = r;
10882                        dst.notifyAll();
10883                    }
10884                    updateOomAdjLocked(r);
10885                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10886                            src.info.authority);
10887                }
10888            }
10889
10890            Binder.restoreCallingIdentity(origId);
10891        }
10892    }
10893
10894    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10895        ContentProviderConnection conn;
10896        try {
10897            conn = (ContentProviderConnection)connection;
10898        } catch (ClassCastException e) {
10899            String msg ="refContentProvider: " + connection
10900                    + " not a ContentProviderConnection";
10901            Slog.w(TAG, msg);
10902            throw new IllegalArgumentException(msg);
10903        }
10904        if (conn == null) {
10905            throw new NullPointerException("connection is null");
10906        }
10907
10908        synchronized (this) {
10909            if (stable > 0) {
10910                conn.numStableIncs += stable;
10911            }
10912            stable = conn.stableCount + stable;
10913            if (stable < 0) {
10914                throw new IllegalStateException("stableCount < 0: " + stable);
10915            }
10916
10917            if (unstable > 0) {
10918                conn.numUnstableIncs += unstable;
10919            }
10920            unstable = conn.unstableCount + unstable;
10921            if (unstable < 0) {
10922                throw new IllegalStateException("unstableCount < 0: " + unstable);
10923            }
10924
10925            if ((stable+unstable) <= 0) {
10926                throw new IllegalStateException("ref counts can't go to zero here: stable="
10927                        + stable + " unstable=" + unstable);
10928            }
10929            conn.stableCount = stable;
10930            conn.unstableCount = unstable;
10931            return !conn.dead;
10932        }
10933    }
10934
10935    public void unstableProviderDied(IBinder connection) {
10936        ContentProviderConnection conn;
10937        try {
10938            conn = (ContentProviderConnection)connection;
10939        } catch (ClassCastException e) {
10940            String msg ="refContentProvider: " + connection
10941                    + " not a ContentProviderConnection";
10942            Slog.w(TAG, msg);
10943            throw new IllegalArgumentException(msg);
10944        }
10945        if (conn == null) {
10946            throw new NullPointerException("connection is null");
10947        }
10948
10949        // Safely retrieve the content provider associated with the connection.
10950        IContentProvider provider;
10951        synchronized (this) {
10952            provider = conn.provider.provider;
10953        }
10954
10955        if (provider == null) {
10956            // Um, yeah, we're way ahead of you.
10957            return;
10958        }
10959
10960        // Make sure the caller is being honest with us.
10961        if (provider.asBinder().pingBinder()) {
10962            // Er, no, still looks good to us.
10963            synchronized (this) {
10964                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10965                        + " says " + conn + " died, but we don't agree");
10966                return;
10967            }
10968        }
10969
10970        // Well look at that!  It's dead!
10971        synchronized (this) {
10972            if (conn.provider.provider != provider) {
10973                // But something changed...  good enough.
10974                return;
10975            }
10976
10977            ProcessRecord proc = conn.provider.proc;
10978            if (proc == null || proc.thread == null) {
10979                // Seems like the process is already cleaned up.
10980                return;
10981            }
10982
10983            // As far as we're concerned, this is just like receiving a
10984            // death notification...  just a bit prematurely.
10985            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10986                    + ") early provider death");
10987            final long ident = Binder.clearCallingIdentity();
10988            try {
10989                appDiedLocked(proc);
10990            } finally {
10991                Binder.restoreCallingIdentity(ident);
10992            }
10993        }
10994    }
10995
10996    @Override
10997    public void appNotRespondingViaProvider(IBinder connection) {
10998        enforceCallingPermission(
10999                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11000
11001        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11002        if (conn == null) {
11003            Slog.w(TAG, "ContentProviderConnection is null");
11004            return;
11005        }
11006
11007        final ProcessRecord host = conn.provider.proc;
11008        if (host == null) {
11009            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11010            return;
11011        }
11012
11013        mHandler.post(new Runnable() {
11014            @Override
11015            public void run() {
11016                mAppErrors.appNotResponding(host, null, null, false,
11017                        "ContentProvider not responding");
11018            }
11019        });
11020    }
11021
11022    public final void installSystemProviders() {
11023        List<ProviderInfo> providers;
11024        synchronized (this) {
11025            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11026            providers = generateApplicationProvidersLocked(app);
11027            if (providers != null) {
11028                for (int i=providers.size()-1; i>=0; i--) {
11029                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11030                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11031                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11032                                + ": not system .apk");
11033                        providers.remove(i);
11034                    }
11035                }
11036            }
11037        }
11038        if (providers != null) {
11039            mSystemThread.installSystemProviders(providers);
11040        }
11041
11042        mCoreSettingsObserver = new CoreSettingsObserver(this);
11043        mFontScaleSettingObserver = new FontScaleSettingObserver();
11044
11045        //mUsageStatsService.monitorPackages();
11046    }
11047
11048    private void startPersistentApps(int matchFlags) {
11049        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11050
11051        synchronized (this) {
11052            try {
11053                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11054                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11055                for (ApplicationInfo app : apps) {
11056                    if (!"android".equals(app.packageName)) {
11057                        addAppLocked(app, false, null /* ABI override */);
11058                    }
11059                }
11060            } catch (RemoteException ex) {
11061            }
11062        }
11063    }
11064
11065    /**
11066     * When a user is unlocked, we need to install encryption-unaware providers
11067     * belonging to any running apps.
11068     */
11069    private void installEncryptionUnawareProviders(int userId) {
11070        // We're only interested in providers that are encryption unaware, and
11071        // we don't care about uninstalled apps, since there's no way they're
11072        // running at this point.
11073        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11074
11075        synchronized (this) {
11076            final int NP = mProcessNames.getMap().size();
11077            for (int ip = 0; ip < NP; ip++) {
11078                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11079                final int NA = apps.size();
11080                for (int ia = 0; ia < NA; ia++) {
11081                    final ProcessRecord app = apps.valueAt(ia);
11082                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11083
11084                    final int NG = app.pkgList.size();
11085                    for (int ig = 0; ig < NG; ig++) {
11086                        try {
11087                            final String pkgName = app.pkgList.keyAt(ig);
11088                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11089                                    .getPackageInfo(pkgName, matchFlags, userId);
11090                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11091                                for (ProviderInfo provInfo : pkgInfo.providers) {
11092                                    if (Objects.equals(provInfo.processName, app.processName)) {
11093                                        Log.v(TAG, "Installing " + provInfo);
11094                                        app.thread.scheduleInstallProvider(provInfo);
11095                                    } else {
11096                                        Log.v(TAG, "Skipping " + provInfo);
11097                                    }
11098                                }
11099                            }
11100                        } catch (RemoteException ignored) {
11101                        }
11102                    }
11103                }
11104            }
11105        }
11106    }
11107
11108    /**
11109     * Allows apps to retrieve the MIME type of a URI.
11110     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11111     * users, then it does not need permission to access the ContentProvider.
11112     * Either, it needs cross-user uri grants.
11113     *
11114     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11115     *
11116     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11117     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11118     */
11119    public String getProviderMimeType(Uri uri, int userId) {
11120        enforceNotIsolatedCaller("getProviderMimeType");
11121        final String name = uri.getAuthority();
11122        int callingUid = Binder.getCallingUid();
11123        int callingPid = Binder.getCallingPid();
11124        long ident = 0;
11125        boolean clearedIdentity = false;
11126        synchronized (this) {
11127            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11128        }
11129        if (canClearIdentity(callingPid, callingUid, userId)) {
11130            clearedIdentity = true;
11131            ident = Binder.clearCallingIdentity();
11132        }
11133        ContentProviderHolder holder = null;
11134        try {
11135            holder = getContentProviderExternalUnchecked(name, null, userId);
11136            if (holder != null) {
11137                return holder.provider.getType(uri);
11138            }
11139        } catch (RemoteException e) {
11140            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11141            return null;
11142        } finally {
11143            // We need to clear the identity to call removeContentProviderExternalUnchecked
11144            if (!clearedIdentity) {
11145                ident = Binder.clearCallingIdentity();
11146            }
11147            try {
11148                if (holder != null) {
11149                    removeContentProviderExternalUnchecked(name, null, userId);
11150                }
11151            } finally {
11152                Binder.restoreCallingIdentity(ident);
11153            }
11154        }
11155
11156        return null;
11157    }
11158
11159    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11160        if (UserHandle.getUserId(callingUid) == userId) {
11161            return true;
11162        }
11163        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11164                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11165                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11166                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11167                return true;
11168        }
11169        return false;
11170    }
11171
11172    // =========================================================
11173    // GLOBAL MANAGEMENT
11174    // =========================================================
11175
11176    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11177            boolean isolated, int isolatedUid) {
11178        String proc = customProcess != null ? customProcess : info.processName;
11179        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11180        final int userId = UserHandle.getUserId(info.uid);
11181        int uid = info.uid;
11182        if (isolated) {
11183            if (isolatedUid == 0) {
11184                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11185                while (true) {
11186                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11187                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11188                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11189                    }
11190                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11191                    mNextIsolatedProcessUid++;
11192                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11193                        // No process for this uid, use it.
11194                        break;
11195                    }
11196                    stepsLeft--;
11197                    if (stepsLeft <= 0) {
11198                        return null;
11199                    }
11200                }
11201            } else {
11202                // Special case for startIsolatedProcess (internal only), where
11203                // the uid of the isolated process is specified by the caller.
11204                uid = isolatedUid;
11205            }
11206        }
11207        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11208        if (!mBooted && !mBooting
11209                && userId == UserHandle.USER_SYSTEM
11210                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11211            r.persistent = true;
11212        }
11213        addProcessNameLocked(r);
11214        return r;
11215    }
11216
11217    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11218            String abiOverride) {
11219        ProcessRecord app;
11220        if (!isolated) {
11221            app = getProcessRecordLocked(info.processName, info.uid, true);
11222        } else {
11223            app = null;
11224        }
11225
11226        if (app == null) {
11227            app = newProcessRecordLocked(info, null, isolated, 0);
11228            updateLruProcessLocked(app, false, null);
11229            updateOomAdjLocked();
11230        }
11231
11232        // This package really, really can not be stopped.
11233        try {
11234            AppGlobals.getPackageManager().setPackageStoppedState(
11235                    info.packageName, false, UserHandle.getUserId(app.uid));
11236        } catch (RemoteException e) {
11237        } catch (IllegalArgumentException e) {
11238            Slog.w(TAG, "Failed trying to unstop package "
11239                    + info.packageName + ": " + e);
11240        }
11241
11242        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11243            app.persistent = true;
11244            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11245        }
11246        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11247            mPersistentStartingProcesses.add(app);
11248            startProcessLocked(app, "added application", app.processName, abiOverride,
11249                    null /* entryPoint */, null /* entryPointArgs */);
11250        }
11251
11252        return app;
11253    }
11254
11255    public void unhandledBack() {
11256        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11257                "unhandledBack()");
11258
11259        synchronized(this) {
11260            final long origId = Binder.clearCallingIdentity();
11261            try {
11262                getFocusedStack().unhandledBackLocked();
11263            } finally {
11264                Binder.restoreCallingIdentity(origId);
11265            }
11266        }
11267    }
11268
11269    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11270        enforceNotIsolatedCaller("openContentUri");
11271        final int userId = UserHandle.getCallingUserId();
11272        String name = uri.getAuthority();
11273        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11274        ParcelFileDescriptor pfd = null;
11275        if (cph != null) {
11276            // We record the binder invoker's uid in thread-local storage before
11277            // going to the content provider to open the file.  Later, in the code
11278            // that handles all permissions checks, we look for this uid and use
11279            // that rather than the Activity Manager's own uid.  The effect is that
11280            // we do the check against the caller's permissions even though it looks
11281            // to the content provider like the Activity Manager itself is making
11282            // the request.
11283            Binder token = new Binder();
11284            sCallerIdentity.set(new Identity(
11285                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11286            try {
11287                pfd = cph.provider.openFile(null, uri, "r", null, token);
11288            } catch (FileNotFoundException e) {
11289                // do nothing; pfd will be returned null
11290            } finally {
11291                // Ensure that whatever happens, we clean up the identity state
11292                sCallerIdentity.remove();
11293                // Ensure we're done with the provider.
11294                removeContentProviderExternalUnchecked(name, null, userId);
11295            }
11296        } else {
11297            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11298        }
11299        return pfd;
11300    }
11301
11302    // Actually is sleeping or shutting down or whatever else in the future
11303    // is an inactive state.
11304    public boolean isSleepingOrShuttingDown() {
11305        return isSleeping() || mShuttingDown;
11306    }
11307
11308    public boolean isSleeping() {
11309        return mSleeping;
11310    }
11311
11312    void onWakefulnessChanged(int wakefulness) {
11313        synchronized(this) {
11314            mWakefulness = wakefulness;
11315            updateSleepIfNeededLocked();
11316        }
11317    }
11318
11319    void finishRunningVoiceLocked() {
11320        if (mRunningVoice != null) {
11321            mRunningVoice = null;
11322            mVoiceWakeLock.release();
11323            updateSleepIfNeededLocked();
11324        }
11325    }
11326
11327    void startTimeTrackingFocusedActivityLocked() {
11328        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11329            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11330        }
11331    }
11332
11333    void updateSleepIfNeededLocked() {
11334        if (mSleeping && !shouldSleepLocked()) {
11335            mSleeping = false;
11336            startTimeTrackingFocusedActivityLocked();
11337            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11338            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11339            updateOomAdjLocked();
11340        } else if (!mSleeping && shouldSleepLocked()) {
11341            mSleeping = true;
11342            if (mCurAppTimeTracker != null) {
11343                mCurAppTimeTracker.stop();
11344            }
11345            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11346            mStackSupervisor.goingToSleepLocked();
11347            updateOomAdjLocked();
11348
11349            // Initialize the wake times of all processes.
11350            checkExcessivePowerUsageLocked(false);
11351            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11352            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11353            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11354        }
11355    }
11356
11357    private boolean shouldSleepLocked() {
11358        // Resume applications while running a voice interactor.
11359        if (mRunningVoice != null) {
11360            return false;
11361        }
11362
11363        // TODO: Transform the lock screen state into a sleep token instead.
11364        switch (mWakefulness) {
11365            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11366            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11367            case PowerManagerInternal.WAKEFULNESS_DOZING:
11368                // Pause applications whenever the lock screen is shown or any sleep
11369                // tokens have been acquired.
11370                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11371            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11372            default:
11373                // If we're asleep then pause applications unconditionally.
11374                return true;
11375        }
11376    }
11377
11378    /** Pokes the task persister. */
11379    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11380        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11381    }
11382
11383    /** Notifies all listeners when the task stack has changed. */
11384    void notifyTaskStackChangedLocked() {
11385        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11386        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11387        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11388        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11389    }
11390
11391    /** Notifies all listeners when an Activity is pinned. */
11392    void notifyActivityPinnedLocked() {
11393        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11394        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11395    }
11396
11397    /**
11398     * Notifies all listeners when an attempt was made to start an an activity that is already
11399     * running in the pinned stack and the activity was not actually started, but the task is
11400     * either brought to the front or a new Intent is delivered to it.
11401     */
11402    void notifyPinnedActivityRestartAttemptLocked() {
11403        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11404        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11405    }
11406
11407    /** Notifies all listeners when the pinned stack animation ends. */
11408    @Override
11409    public void notifyPinnedStackAnimationEnded() {
11410        synchronized (this) {
11411            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11412            mHandler.obtainMessage(
11413                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11414        }
11415    }
11416
11417    @Override
11418    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11419        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11420    }
11421
11422    @Override
11423    public boolean shutdown(int timeout) {
11424        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11425                != PackageManager.PERMISSION_GRANTED) {
11426            throw new SecurityException("Requires permission "
11427                    + android.Manifest.permission.SHUTDOWN);
11428        }
11429
11430        boolean timedout = false;
11431
11432        synchronized(this) {
11433            mShuttingDown = true;
11434            updateEventDispatchingLocked();
11435            timedout = mStackSupervisor.shutdownLocked(timeout);
11436        }
11437
11438        mAppOpsService.shutdown();
11439        if (mUsageStatsService != null) {
11440            mUsageStatsService.prepareShutdown();
11441        }
11442        mBatteryStatsService.shutdown();
11443        synchronized (this) {
11444            mProcessStats.shutdownLocked();
11445            notifyTaskPersisterLocked(null, true);
11446        }
11447
11448        return timedout;
11449    }
11450
11451    public final void activitySlept(IBinder token) {
11452        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11453
11454        final long origId = Binder.clearCallingIdentity();
11455
11456        synchronized (this) {
11457            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11458            if (r != null) {
11459                mStackSupervisor.activitySleptLocked(r);
11460            }
11461        }
11462
11463        Binder.restoreCallingIdentity(origId);
11464    }
11465
11466    private String lockScreenShownToString() {
11467        switch (mLockScreenShown) {
11468            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11469            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11470            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11471            default: return "Unknown=" + mLockScreenShown;
11472        }
11473    }
11474
11475    void logLockScreen(String msg) {
11476        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11477                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11478                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11479                + " mSleeping=" + mSleeping);
11480    }
11481
11482    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11483        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11484        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11485        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11486            boolean wasRunningVoice = mRunningVoice != null;
11487            mRunningVoice = session;
11488            if (!wasRunningVoice) {
11489                mVoiceWakeLock.acquire();
11490                updateSleepIfNeededLocked();
11491            }
11492        }
11493    }
11494
11495    private void updateEventDispatchingLocked() {
11496        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11497    }
11498
11499    public void setLockScreenShown(boolean showing, boolean occluded) {
11500        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11501                != PackageManager.PERMISSION_GRANTED) {
11502            throw new SecurityException("Requires permission "
11503                    + android.Manifest.permission.DEVICE_POWER);
11504        }
11505
11506        synchronized(this) {
11507            long ident = Binder.clearCallingIdentity();
11508            try {
11509                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11510                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11511                if (showing && occluded) {
11512                    // The lock screen is currently showing, but is occluded by a window that can
11513                    // show on top of the lock screen. In this can we want to dismiss the docked
11514                    // stack since it will be complicated/risky to try to put the activity on top
11515                    // of the lock screen in the right fullscreen configuration.
11516                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11517                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11518                }
11519
11520                updateSleepIfNeededLocked();
11521            } finally {
11522                Binder.restoreCallingIdentity(ident);
11523            }
11524        }
11525    }
11526
11527    @Override
11528    public void notifyLockedProfile(@UserIdInt int userId) {
11529        try {
11530            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11531                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11532            }
11533        } catch (RemoteException ex) {
11534            throw new SecurityException("Fail to check is caller a privileged app", ex);
11535        }
11536
11537        synchronized (this) {
11538            if (mStackSupervisor.isUserLockedProfile(userId)) {
11539                final long ident = Binder.clearCallingIdentity();
11540                try {
11541                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11542                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11543                        // If there is no device lock, we will show the profile's credential page.
11544                        mActivityStarter.showConfirmDeviceCredential(userId);
11545                    } else {
11546                        // Showing launcher to avoid user entering credential twice.
11547                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11548                    }
11549                } finally {
11550                    Binder.restoreCallingIdentity(ident);
11551                }
11552            }
11553        }
11554    }
11555
11556    @Override
11557    public void startConfirmDeviceCredentialIntent(Intent intent) {
11558        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11559        synchronized (this) {
11560            final long ident = Binder.clearCallingIdentity();
11561            try {
11562                mActivityStarter.startConfirmCredentialIntent(intent);
11563            } finally {
11564                Binder.restoreCallingIdentity(ident);
11565            }
11566        }
11567    }
11568
11569    @Override
11570    public void stopAppSwitches() {
11571        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11572                != PackageManager.PERMISSION_GRANTED) {
11573            throw new SecurityException("viewquires permission "
11574                    + android.Manifest.permission.STOP_APP_SWITCHES);
11575        }
11576
11577        synchronized(this) {
11578            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11579                    + APP_SWITCH_DELAY_TIME;
11580            mDidAppSwitch = false;
11581            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11582            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11583            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11584        }
11585    }
11586
11587    public void resumeAppSwitches() {
11588        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11589                != PackageManager.PERMISSION_GRANTED) {
11590            throw new SecurityException("Requires permission "
11591                    + android.Manifest.permission.STOP_APP_SWITCHES);
11592        }
11593
11594        synchronized(this) {
11595            // Note that we don't execute any pending app switches... we will
11596            // let those wait until either the timeout, or the next start
11597            // activity request.
11598            mAppSwitchesAllowedTime = 0;
11599        }
11600    }
11601
11602    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11603            int callingPid, int callingUid, String name) {
11604        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11605            return true;
11606        }
11607
11608        int perm = checkComponentPermission(
11609                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11610                sourceUid, -1, true);
11611        if (perm == PackageManager.PERMISSION_GRANTED) {
11612            return true;
11613        }
11614
11615        // If the actual IPC caller is different from the logical source, then
11616        // also see if they are allowed to control app switches.
11617        if (callingUid != -1 && callingUid != sourceUid) {
11618            perm = checkComponentPermission(
11619                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11620                    callingUid, -1, true);
11621            if (perm == PackageManager.PERMISSION_GRANTED) {
11622                return true;
11623            }
11624        }
11625
11626        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11627        return false;
11628    }
11629
11630    public void setDebugApp(String packageName, boolean waitForDebugger,
11631            boolean persistent) {
11632        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11633                "setDebugApp()");
11634
11635        long ident = Binder.clearCallingIdentity();
11636        try {
11637            // Note that this is not really thread safe if there are multiple
11638            // callers into it at the same time, but that's not a situation we
11639            // care about.
11640            if (persistent) {
11641                final ContentResolver resolver = mContext.getContentResolver();
11642                Settings.Global.putString(
11643                    resolver, Settings.Global.DEBUG_APP,
11644                    packageName);
11645                Settings.Global.putInt(
11646                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11647                    waitForDebugger ? 1 : 0);
11648            }
11649
11650            synchronized (this) {
11651                if (!persistent) {
11652                    mOrigDebugApp = mDebugApp;
11653                    mOrigWaitForDebugger = mWaitForDebugger;
11654                }
11655                mDebugApp = packageName;
11656                mWaitForDebugger = waitForDebugger;
11657                mDebugTransient = !persistent;
11658                if (packageName != null) {
11659                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11660                            false, UserHandle.USER_ALL, "set debug app");
11661                }
11662            }
11663        } finally {
11664            Binder.restoreCallingIdentity(ident);
11665        }
11666    }
11667
11668    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11669        synchronized (this) {
11670            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11671            if (!isDebuggable) {
11672                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11673                    throw new SecurityException("Process not debuggable: " + app.packageName);
11674                }
11675            }
11676
11677            mTrackAllocationApp = processName;
11678        }
11679    }
11680
11681    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11682        synchronized (this) {
11683            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11684            if (!isDebuggable) {
11685                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11686                    throw new SecurityException("Process not debuggable: " + app.packageName);
11687                }
11688            }
11689            mProfileApp = processName;
11690            mProfileFile = profilerInfo.profileFile;
11691            if (mProfileFd != null) {
11692                try {
11693                    mProfileFd.close();
11694                } catch (IOException e) {
11695                }
11696                mProfileFd = null;
11697            }
11698            mProfileFd = profilerInfo.profileFd;
11699            mSamplingInterval = profilerInfo.samplingInterval;
11700            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11701            mProfileType = 0;
11702        }
11703    }
11704
11705    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11706        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11707        if (!isDebuggable) {
11708            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11709                throw new SecurityException("Process not debuggable: " + app.packageName);
11710            }
11711        }
11712        mNativeDebuggingApp = processName;
11713    }
11714
11715    @Override
11716    public void setAlwaysFinish(boolean enabled) {
11717        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11718                "setAlwaysFinish()");
11719
11720        long ident = Binder.clearCallingIdentity();
11721        try {
11722            Settings.Global.putInt(
11723                    mContext.getContentResolver(),
11724                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11725
11726            synchronized (this) {
11727                mAlwaysFinishActivities = enabled;
11728            }
11729        } finally {
11730            Binder.restoreCallingIdentity(ident);
11731        }
11732    }
11733
11734    @Override
11735    public void setLenientBackgroundCheck(boolean enabled) {
11736        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11737                "setLenientBackgroundCheck()");
11738
11739        long ident = Binder.clearCallingIdentity();
11740        try {
11741            Settings.Global.putInt(
11742                    mContext.getContentResolver(),
11743                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11744
11745            synchronized (this) {
11746                mLenientBackgroundCheck = enabled;
11747            }
11748        } finally {
11749            Binder.restoreCallingIdentity(ident);
11750        }
11751    }
11752
11753    @Override
11754    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11755        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11756                "setActivityController()");
11757        synchronized (this) {
11758            mController = controller;
11759            mControllerIsAMonkey = imAMonkey;
11760            Watchdog.getInstance().setActivityController(controller);
11761        }
11762    }
11763
11764    @Override
11765    public void setUserIsMonkey(boolean userIsMonkey) {
11766        synchronized (this) {
11767            synchronized (mPidsSelfLocked) {
11768                final int callingPid = Binder.getCallingPid();
11769                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11770                if (precessRecord == null) {
11771                    throw new SecurityException("Unknown process: " + callingPid);
11772                }
11773                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11774                    throw new SecurityException("Only an instrumentation process "
11775                            + "with a UiAutomation can call setUserIsMonkey");
11776                }
11777            }
11778            mUserIsMonkey = userIsMonkey;
11779        }
11780    }
11781
11782    @Override
11783    public boolean isUserAMonkey() {
11784        synchronized (this) {
11785            // If there is a controller also implies the user is a monkey.
11786            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11787        }
11788    }
11789
11790    public void requestBugReport(int bugreportType) {
11791        String service = null;
11792        switch (bugreportType) {
11793            case ActivityManager.BUGREPORT_OPTION_FULL:
11794                service = "bugreport";
11795                break;
11796            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11797                service = "bugreportplus";
11798                break;
11799            case ActivityManager.BUGREPORT_OPTION_REMOTE:
11800                service = "bugreportremote";
11801                break;
11802        }
11803        if (service == null) {
11804            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11805                    + bugreportType);
11806        }
11807        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11808        SystemProperties.set("ctl.start", service);
11809    }
11810
11811    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11812        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11813    }
11814
11815    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11816        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11817            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11818        }
11819        return KEY_DISPATCHING_TIMEOUT;
11820    }
11821
11822    @Override
11823    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11824        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11825                != PackageManager.PERMISSION_GRANTED) {
11826            throw new SecurityException("Requires permission "
11827                    + android.Manifest.permission.FILTER_EVENTS);
11828        }
11829        ProcessRecord proc;
11830        long timeout;
11831        synchronized (this) {
11832            synchronized (mPidsSelfLocked) {
11833                proc = mPidsSelfLocked.get(pid);
11834            }
11835            timeout = getInputDispatchingTimeoutLocked(proc);
11836        }
11837
11838        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11839            return -1;
11840        }
11841
11842        return timeout;
11843    }
11844
11845    /**
11846     * Handle input dispatching timeouts.
11847     * Returns whether input dispatching should be aborted or not.
11848     */
11849    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11850            final ActivityRecord activity, final ActivityRecord parent,
11851            final boolean aboveSystem, String reason) {
11852        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11853                != PackageManager.PERMISSION_GRANTED) {
11854            throw new SecurityException("Requires permission "
11855                    + android.Manifest.permission.FILTER_EVENTS);
11856        }
11857
11858        final String annotation;
11859        if (reason == null) {
11860            annotation = "Input dispatching timed out";
11861        } else {
11862            annotation = "Input dispatching timed out (" + reason + ")";
11863        }
11864
11865        if (proc != null) {
11866            synchronized (this) {
11867                if (proc.debugging) {
11868                    return false;
11869                }
11870
11871                if (mDidDexOpt) {
11872                    // Give more time since we were dexopting.
11873                    mDidDexOpt = false;
11874                    return false;
11875                }
11876
11877                if (proc.instrumentationClass != null) {
11878                    Bundle info = new Bundle();
11879                    info.putString("shortMsg", "keyDispatchingTimedOut");
11880                    info.putString("longMsg", annotation);
11881                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11882                    return true;
11883                }
11884            }
11885            mHandler.post(new Runnable() {
11886                @Override
11887                public void run() {
11888                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11889                }
11890            });
11891        }
11892
11893        return true;
11894    }
11895
11896    @Override
11897    public Bundle getAssistContextExtras(int requestType) {
11898        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11899                null, null, true /* focused */, true /* newSessionId */,
11900                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11901        if (pae == null) {
11902            return null;
11903        }
11904        synchronized (pae) {
11905            while (!pae.haveResult) {
11906                try {
11907                    pae.wait();
11908                } catch (InterruptedException e) {
11909                }
11910            }
11911        }
11912        synchronized (this) {
11913            buildAssistBundleLocked(pae, pae.result);
11914            mPendingAssistExtras.remove(pae);
11915            mUiHandler.removeCallbacks(pae);
11916        }
11917        return pae.extras;
11918    }
11919
11920    @Override
11921    public boolean isAssistDataAllowedOnCurrentActivity() {
11922        int userId;
11923        synchronized (this) {
11924            userId = mUserController.getCurrentUserIdLocked();
11925            ActivityRecord activity = getFocusedStack().topActivity();
11926            if (activity == null) {
11927                return false;
11928            }
11929            userId = activity.userId;
11930        }
11931        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11932                Context.DEVICE_POLICY_SERVICE);
11933        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11934    }
11935
11936    @Override
11937    public boolean showAssistFromActivity(IBinder token, Bundle args) {
11938        long ident = Binder.clearCallingIdentity();
11939        try {
11940            synchronized (this) {
11941                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11942                ActivityRecord top = getFocusedStack().topActivity();
11943                if (top != caller) {
11944                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11945                            + " is not current top " + top);
11946                    return false;
11947                }
11948                if (!top.nowVisible) {
11949                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11950                            + " is not visible");
11951                    return false;
11952                }
11953            }
11954            AssistUtils utils = new AssistUtils(mContext);
11955            return utils.showSessionForActiveService(args,
11956                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11957        } finally {
11958            Binder.restoreCallingIdentity(ident);
11959        }
11960    }
11961
11962    @Override
11963    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11964            Bundle receiverExtras,
11965            IBinder activityToken, boolean focused, boolean newSessionId) {
11966        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
11967                activityToken, focused, newSessionId,
11968                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
11969                != null;
11970    }
11971
11972    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11973            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
11974            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
11975        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11976                "enqueueAssistContext()");
11977        synchronized (this) {
11978            ActivityRecord activity = getFocusedStack().topActivity();
11979            if (activity == null) {
11980                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11981                return null;
11982            }
11983            if (activity.app == null || activity.app.thread == null) {
11984                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11985                return null;
11986            }
11987            if (focused) {
11988                if (activityToken != null) {
11989                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11990                    if (activity != caller) {
11991                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11992                                + " is not current top " + activity);
11993                        return null;
11994                    }
11995                }
11996            } else {
11997                activity = ActivityRecord.forTokenLocked(activityToken);
11998                if (activity == null) {
11999                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12000                            + " couldn't be found");
12001                    return null;
12002                }
12003            }
12004
12005            PendingAssistExtras pae;
12006            Bundle extras = new Bundle();
12007            if (args != null) {
12008                extras.putAll(args);
12009            }
12010            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12011            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12012            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12013                    userHandle);
12014            // Increment the sessionId if necessary
12015            if (newSessionId) {
12016                mViSessionId++;
12017            }
12018            try {
12019                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12020                        requestType, mViSessionId);
12021                mPendingAssistExtras.add(pae);
12022                mUiHandler.postDelayed(pae, timeout);
12023            } catch (RemoteException e) {
12024                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12025                return null;
12026            }
12027            return pae;
12028        }
12029    }
12030
12031    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12032        IResultReceiver receiver;
12033        synchronized (this) {
12034            mPendingAssistExtras.remove(pae);
12035            receiver = pae.receiver;
12036        }
12037        if (receiver != null) {
12038            // Caller wants result sent back to them.
12039            Bundle sendBundle = new Bundle();
12040            // At least return the receiver extras
12041            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12042                    pae.receiverExtras);
12043            try {
12044                pae.receiver.send(0, sendBundle);
12045            } catch (RemoteException e) {
12046            }
12047        }
12048    }
12049
12050    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12051        if (result != null) {
12052            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12053        }
12054        if (pae.hint != null) {
12055            pae.extras.putBoolean(pae.hint, true);
12056        }
12057    }
12058
12059    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12060            AssistContent content, Uri referrer) {
12061        PendingAssistExtras pae = (PendingAssistExtras)token;
12062        synchronized (pae) {
12063            pae.result = extras;
12064            pae.structure = structure;
12065            pae.content = content;
12066            if (referrer != null) {
12067                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12068            }
12069            pae.haveResult = true;
12070            pae.notifyAll();
12071            if (pae.intent == null && pae.receiver == null) {
12072                // Caller is just waiting for the result.
12073                return;
12074            }
12075        }
12076
12077        // We are now ready to launch the assist activity.
12078        IResultReceiver sendReceiver = null;
12079        Bundle sendBundle = null;
12080        synchronized (this) {
12081            buildAssistBundleLocked(pae, extras);
12082            boolean exists = mPendingAssistExtras.remove(pae);
12083            mUiHandler.removeCallbacks(pae);
12084            if (!exists) {
12085                // Timed out.
12086                return;
12087            }
12088            if ((sendReceiver=pae.receiver) != null) {
12089                // Caller wants result sent back to them.
12090                sendBundle = new Bundle();
12091                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12092                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12093                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12094                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12095                        pae.receiverExtras);
12096            }
12097        }
12098        if (sendReceiver != null) {
12099            try {
12100                sendReceiver.send(0, sendBundle);
12101            } catch (RemoteException e) {
12102            }
12103            return;
12104        }
12105
12106        long ident = Binder.clearCallingIdentity();
12107        try {
12108            pae.intent.replaceExtras(pae.extras);
12109            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12110                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12111                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12112            closeSystemDialogs("assist");
12113            try {
12114                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12115            } catch (ActivityNotFoundException e) {
12116                Slog.w(TAG, "No activity to handle assist action.", e);
12117            }
12118        } finally {
12119            Binder.restoreCallingIdentity(ident);
12120        }
12121    }
12122
12123    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12124            Bundle args) {
12125        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12126                true /* focused */, true /* newSessionId */,
12127                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12128    }
12129
12130    public void registerProcessObserver(IProcessObserver observer) {
12131        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12132                "registerProcessObserver()");
12133        synchronized (this) {
12134            mProcessObservers.register(observer);
12135        }
12136    }
12137
12138    @Override
12139    public void unregisterProcessObserver(IProcessObserver observer) {
12140        synchronized (this) {
12141            mProcessObservers.unregister(observer);
12142        }
12143    }
12144
12145    @Override
12146    public void registerUidObserver(IUidObserver observer, int which) {
12147        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12148                "registerUidObserver()");
12149        synchronized (this) {
12150            mUidObservers.register(observer, which);
12151        }
12152    }
12153
12154    @Override
12155    public void unregisterUidObserver(IUidObserver observer) {
12156        synchronized (this) {
12157            mUidObservers.unregister(observer);
12158        }
12159    }
12160
12161    @Override
12162    public boolean convertFromTranslucent(IBinder token) {
12163        final long origId = Binder.clearCallingIdentity();
12164        try {
12165            synchronized (this) {
12166                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12167                if (r == null) {
12168                    return false;
12169                }
12170                final boolean translucentChanged = r.changeWindowTranslucency(true);
12171                if (translucentChanged) {
12172                    r.task.stack.releaseBackgroundResources(r);
12173                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12174                }
12175                mWindowManager.setAppFullscreen(token, true);
12176                return translucentChanged;
12177            }
12178        } finally {
12179            Binder.restoreCallingIdentity(origId);
12180        }
12181    }
12182
12183    @Override
12184    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12185        final long origId = Binder.clearCallingIdentity();
12186        try {
12187            synchronized (this) {
12188                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12189                if (r == null) {
12190                    return false;
12191                }
12192                int index = r.task.mActivities.lastIndexOf(r);
12193                if (index > 0) {
12194                    ActivityRecord under = r.task.mActivities.get(index - 1);
12195                    under.returningOptions = options;
12196                }
12197                final boolean translucentChanged = r.changeWindowTranslucency(false);
12198                if (translucentChanged) {
12199                    r.task.stack.convertActivityToTranslucent(r);
12200                }
12201                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12202                mWindowManager.setAppFullscreen(token, false);
12203                return translucentChanged;
12204            }
12205        } finally {
12206            Binder.restoreCallingIdentity(origId);
12207        }
12208    }
12209
12210    @Override
12211    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12212        final long origId = Binder.clearCallingIdentity();
12213        try {
12214            synchronized (this) {
12215                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12216                if (r != null) {
12217                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12218                }
12219            }
12220            return false;
12221        } finally {
12222            Binder.restoreCallingIdentity(origId);
12223        }
12224    }
12225
12226    @Override
12227    public boolean isBackgroundVisibleBehind(IBinder token) {
12228        final long origId = Binder.clearCallingIdentity();
12229        try {
12230            synchronized (this) {
12231                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12232                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12233                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12234                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12235                return visible;
12236            }
12237        } finally {
12238            Binder.restoreCallingIdentity(origId);
12239        }
12240    }
12241
12242    @Override
12243    public ActivityOptions getActivityOptions(IBinder token) {
12244        final long origId = Binder.clearCallingIdentity();
12245        try {
12246            synchronized (this) {
12247                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12248                if (r != null) {
12249                    final ActivityOptions activityOptions = r.pendingOptions;
12250                    r.pendingOptions = null;
12251                    return activityOptions;
12252                }
12253                return null;
12254            }
12255        } finally {
12256            Binder.restoreCallingIdentity(origId);
12257        }
12258    }
12259
12260    @Override
12261    public void setImmersive(IBinder token, boolean immersive) {
12262        synchronized(this) {
12263            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12264            if (r == null) {
12265                throw new IllegalArgumentException();
12266            }
12267            r.immersive = immersive;
12268
12269            // update associated state if we're frontmost
12270            if (r == mFocusedActivity) {
12271                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12272                applyUpdateLockStateLocked(r);
12273            }
12274        }
12275    }
12276
12277    @Override
12278    public boolean isImmersive(IBinder token) {
12279        synchronized (this) {
12280            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12281            if (r == null) {
12282                throw new IllegalArgumentException();
12283            }
12284            return r.immersive;
12285        }
12286    }
12287
12288    @Override
12289    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12290        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12291            throw new UnsupportedOperationException("VR mode not supported on this device!");
12292        }
12293
12294        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12295
12296        ActivityRecord r;
12297        synchronized (this) {
12298            r = ActivityRecord.isInStackLocked(token);
12299        }
12300
12301        if (r == null) {
12302            throw new IllegalArgumentException();
12303        }
12304
12305        int err;
12306        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12307                VrManagerInternal.NO_ERROR) {
12308            return err;
12309        }
12310
12311        synchronized(this) {
12312            r.requestedVrComponent = (enabled) ? packageName : null;
12313
12314            // Update associated state if this activity is currently focused
12315            if (r == mFocusedActivity) {
12316                applyUpdateVrModeLocked(r);
12317            }
12318            return 0;
12319        }
12320    }
12321
12322    @Override
12323    public boolean isVrModePackageEnabled(ComponentName packageName) {
12324        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12325            throw new UnsupportedOperationException("VR mode not supported on this device!");
12326        }
12327
12328        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12329
12330        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12331                VrManagerInternal.NO_ERROR;
12332    }
12333
12334    public boolean isTopActivityImmersive() {
12335        enforceNotIsolatedCaller("startActivity");
12336        synchronized (this) {
12337            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12338            return (r != null) ? r.immersive : false;
12339        }
12340    }
12341
12342    @Override
12343    public boolean isTopOfTask(IBinder token) {
12344        synchronized (this) {
12345            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12346            if (r == null) {
12347                throw new IllegalArgumentException();
12348            }
12349            return r.task.getTopActivity() == r;
12350        }
12351    }
12352
12353    public final void enterSafeMode() {
12354        synchronized(this) {
12355            // It only makes sense to do this before the system is ready
12356            // and started launching other packages.
12357            if (!mSystemReady) {
12358                try {
12359                    AppGlobals.getPackageManager().enterSafeMode();
12360                } catch (RemoteException e) {
12361                }
12362            }
12363
12364            mSafeMode = true;
12365        }
12366    }
12367
12368    public final void showSafeModeOverlay() {
12369        View v = LayoutInflater.from(mContext).inflate(
12370                com.android.internal.R.layout.safe_mode, null);
12371        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12372        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12373        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12374        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12375        lp.gravity = Gravity.BOTTOM | Gravity.START;
12376        lp.format = v.getBackground().getOpacity();
12377        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12378                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12379        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12380        ((WindowManager)mContext.getSystemService(
12381                Context.WINDOW_SERVICE)).addView(v, lp);
12382    }
12383
12384    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12385        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12386            return;
12387        }
12388        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12389        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12390        synchronized (stats) {
12391            if (mBatteryStatsService.isOnBattery()) {
12392                mBatteryStatsService.enforceCallingPermission();
12393                int MY_UID = Binder.getCallingUid();
12394                final int uid;
12395                if (sender == null) {
12396                    uid = sourceUid;
12397                } else {
12398                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12399                }
12400                BatteryStatsImpl.Uid.Pkg pkg =
12401                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12402                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12403                pkg.noteWakeupAlarmLocked(tag);
12404            }
12405        }
12406    }
12407
12408    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12409        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12410            return;
12411        }
12412        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12413        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12414        synchronized (stats) {
12415            mBatteryStatsService.enforceCallingPermission();
12416            int MY_UID = Binder.getCallingUid();
12417            final int uid;
12418            if (sender == null) {
12419                uid = sourceUid;
12420            } else {
12421                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12422            }
12423            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12424        }
12425    }
12426
12427    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12428        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12429            return;
12430        }
12431        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12432        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12433        synchronized (stats) {
12434            mBatteryStatsService.enforceCallingPermission();
12435            int MY_UID = Binder.getCallingUid();
12436            final int uid;
12437            if (sender == null) {
12438                uid = sourceUid;
12439            } else {
12440                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12441            }
12442            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12443        }
12444    }
12445
12446    public boolean killPids(int[] pids, String pReason, boolean secure) {
12447        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12448            throw new SecurityException("killPids only available to the system");
12449        }
12450        String reason = (pReason == null) ? "Unknown" : pReason;
12451        // XXX Note: don't acquire main activity lock here, because the window
12452        // manager calls in with its locks held.
12453
12454        boolean killed = false;
12455        synchronized (mPidsSelfLocked) {
12456            int worstType = 0;
12457            for (int i=0; i<pids.length; i++) {
12458                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12459                if (proc != null) {
12460                    int type = proc.setAdj;
12461                    if (type > worstType) {
12462                        worstType = type;
12463                    }
12464                }
12465            }
12466
12467            // If the worst oom_adj is somewhere in the cached proc LRU range,
12468            // then constrain it so we will kill all cached procs.
12469            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12470                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12471                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12472            }
12473
12474            // If this is not a secure call, don't let it kill processes that
12475            // are important.
12476            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12477                worstType = ProcessList.SERVICE_ADJ;
12478            }
12479
12480            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12481            for (int i=0; i<pids.length; i++) {
12482                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12483                if (proc == null) {
12484                    continue;
12485                }
12486                int adj = proc.setAdj;
12487                if (adj >= worstType && !proc.killedByAm) {
12488                    proc.kill(reason, true);
12489                    killed = true;
12490                }
12491            }
12492        }
12493        return killed;
12494    }
12495
12496    @Override
12497    public void killUid(int appId, int userId, String reason) {
12498        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12499        synchronized (this) {
12500            final long identity = Binder.clearCallingIdentity();
12501            try {
12502                killPackageProcessesLocked(null, appId, userId,
12503                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12504                        reason != null ? reason : "kill uid");
12505            } finally {
12506                Binder.restoreCallingIdentity(identity);
12507            }
12508        }
12509    }
12510
12511    @Override
12512    public boolean killProcessesBelowForeground(String reason) {
12513        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12514            throw new SecurityException("killProcessesBelowForeground() only available to system");
12515        }
12516
12517        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12518    }
12519
12520    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12521        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12522            throw new SecurityException("killProcessesBelowAdj() only available to system");
12523        }
12524
12525        boolean killed = false;
12526        synchronized (mPidsSelfLocked) {
12527            final int size = mPidsSelfLocked.size();
12528            for (int i = 0; i < size; i++) {
12529                final int pid = mPidsSelfLocked.keyAt(i);
12530                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12531                if (proc == null) continue;
12532
12533                final int adj = proc.setAdj;
12534                if (adj > belowAdj && !proc.killedByAm) {
12535                    proc.kill(reason, true);
12536                    killed = true;
12537                }
12538            }
12539        }
12540        return killed;
12541    }
12542
12543    @Override
12544    public void hang(final IBinder who, boolean allowRestart) {
12545        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12546                != PackageManager.PERMISSION_GRANTED) {
12547            throw new SecurityException("Requires permission "
12548                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12549        }
12550
12551        final IBinder.DeathRecipient death = new DeathRecipient() {
12552            @Override
12553            public void binderDied() {
12554                synchronized (this) {
12555                    notifyAll();
12556                }
12557            }
12558        };
12559
12560        try {
12561            who.linkToDeath(death, 0);
12562        } catch (RemoteException e) {
12563            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12564            return;
12565        }
12566
12567        synchronized (this) {
12568            Watchdog.getInstance().setAllowRestart(allowRestart);
12569            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12570            synchronized (death) {
12571                while (who.isBinderAlive()) {
12572                    try {
12573                        death.wait();
12574                    } catch (InterruptedException e) {
12575                    }
12576                }
12577            }
12578            Watchdog.getInstance().setAllowRestart(true);
12579        }
12580    }
12581
12582    @Override
12583    public void restart() {
12584        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12585                != PackageManager.PERMISSION_GRANTED) {
12586            throw new SecurityException("Requires permission "
12587                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12588        }
12589
12590        Log.i(TAG, "Sending shutdown broadcast...");
12591
12592        BroadcastReceiver br = new BroadcastReceiver() {
12593            @Override public void onReceive(Context context, Intent intent) {
12594                // Now the broadcast is done, finish up the low-level shutdown.
12595                Log.i(TAG, "Shutting down activity manager...");
12596                shutdown(10000);
12597                Log.i(TAG, "Shutdown complete, restarting!");
12598                Process.killProcess(Process.myPid());
12599                System.exit(10);
12600            }
12601        };
12602
12603        // First send the high-level shut down broadcast.
12604        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12605        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12606        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12607        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12608        mContext.sendOrderedBroadcastAsUser(intent,
12609                UserHandle.ALL, null, br, mHandler, 0, null, null);
12610        */
12611        br.onReceive(mContext, intent);
12612    }
12613
12614    private long getLowRamTimeSinceIdle(long now) {
12615        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12616    }
12617
12618    @Override
12619    public void performIdleMaintenance() {
12620        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12621                != PackageManager.PERMISSION_GRANTED) {
12622            throw new SecurityException("Requires permission "
12623                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12624        }
12625
12626        synchronized (this) {
12627            final long now = SystemClock.uptimeMillis();
12628            final long timeSinceLastIdle = now - mLastIdleTime;
12629            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12630            mLastIdleTime = now;
12631            mLowRamTimeSinceLastIdle = 0;
12632            if (mLowRamStartTime != 0) {
12633                mLowRamStartTime = now;
12634            }
12635
12636            StringBuilder sb = new StringBuilder(128);
12637            sb.append("Idle maintenance over ");
12638            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12639            sb.append(" low RAM for ");
12640            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12641            Slog.i(TAG, sb.toString());
12642
12643            // If at least 1/3 of our time since the last idle period has been spent
12644            // with RAM low, then we want to kill processes.
12645            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12646
12647            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12648                ProcessRecord proc = mLruProcesses.get(i);
12649                if (proc.notCachedSinceIdle) {
12650                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12651                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12652                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12653                        if (doKilling && proc.initialIdlePss != 0
12654                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12655                            sb = new StringBuilder(128);
12656                            sb.append("Kill");
12657                            sb.append(proc.processName);
12658                            sb.append(" in idle maint: pss=");
12659                            sb.append(proc.lastPss);
12660                            sb.append(", swapPss=");
12661                            sb.append(proc.lastSwapPss);
12662                            sb.append(", initialPss=");
12663                            sb.append(proc.initialIdlePss);
12664                            sb.append(", period=");
12665                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12666                            sb.append(", lowRamPeriod=");
12667                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12668                            Slog.wtfQuiet(TAG, sb.toString());
12669                            proc.kill("idle maint (pss " + proc.lastPss
12670                                    + " from " + proc.initialIdlePss + ")", true);
12671                        }
12672                    }
12673                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12674                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12675                    proc.notCachedSinceIdle = true;
12676                    proc.initialIdlePss = 0;
12677                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12678                            mTestPssMode, isSleeping(), now);
12679                }
12680            }
12681
12682            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12683            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12684        }
12685    }
12686
12687    @Override
12688    public void sendIdleJobTrigger() {
12689        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12690                != PackageManager.PERMISSION_GRANTED) {
12691            throw new SecurityException("Requires permission "
12692                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12693        }
12694
12695        final long ident = Binder.clearCallingIdentity();
12696        try {
12697            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12698                    .setPackage("android")
12699                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12700            broadcastIntent(null, intent, null, null, 0, null, null, null,
12701                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12702        } finally {
12703            Binder.restoreCallingIdentity(ident);
12704        }
12705    }
12706
12707    private void retrieveSettings() {
12708        final ContentResolver resolver = mContext.getContentResolver();
12709        final boolean freeformWindowManagement =
12710                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12711                        || Settings.Global.getInt(
12712                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12713        final boolean supportsPictureInPicture =
12714                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12715
12716        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12717        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12718        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12719        final boolean alwaysFinishActivities =
12720                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12721        final boolean lenientBackgroundCheck =
12722                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12723        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12724        final boolean forceResizable = Settings.Global.getInt(
12725                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12726        // Transfer any global setting for forcing RTL layout, into a System Property
12727        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12728
12729        final Configuration configuration = new Configuration();
12730        Settings.System.getConfiguration(resolver, configuration);
12731        if (forceRtl) {
12732            // This will take care of setting the correct layout direction flags
12733            configuration.setLayoutDirection(configuration.locale);
12734        }
12735
12736        synchronized (this) {
12737            mDebugApp = mOrigDebugApp = debugApp;
12738            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12739            mAlwaysFinishActivities = alwaysFinishActivities;
12740            mLenientBackgroundCheck = lenientBackgroundCheck;
12741            mForceResizableActivities = forceResizable;
12742            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12743            if (supportsMultiWindow || forceResizable) {
12744                mSupportsMultiWindow = true;
12745                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12746                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12747            } else {
12748                mSupportsMultiWindow = false;
12749                mSupportsFreeformWindowManagement = false;
12750                mSupportsPictureInPicture = false;
12751            }
12752            // This happens before any activities are started, so we can
12753            // change mConfiguration in-place.
12754            updateConfigurationLocked(configuration, null, true);
12755            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12756                    "Initial config: " + mConfiguration);
12757
12758            // Load resources only after the current configuration has been set.
12759            final Resources res = mContext.getResources();
12760            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12761            mThumbnailWidth = res.getDimensionPixelSize(
12762                    com.android.internal.R.dimen.thumbnail_width);
12763            mThumbnailHeight = res.getDimensionPixelSize(
12764                    com.android.internal.R.dimen.thumbnail_height);
12765            mFullscreenThumbnailScale = res.getFraction(
12766                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12767            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12768                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12769            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12770                    com.android.internal.R.string.config_appsNotReportingCrashes));
12771        }
12772    }
12773
12774    public boolean testIsSystemReady() {
12775        // no need to synchronize(this) just to read & return the value
12776        return mSystemReady;
12777    }
12778
12779    public void systemReady(final Runnable goingCallback) {
12780        synchronized(this) {
12781            if (mSystemReady) {
12782                // If we're done calling all the receivers, run the next "boot phase" passed in
12783                // by the SystemServer
12784                if (goingCallback != null) {
12785                    goingCallback.run();
12786                }
12787                return;
12788            }
12789
12790            mLocalDeviceIdleController
12791                    = LocalServices.getService(DeviceIdleController.LocalService.class);
12792
12793            // Make sure we have the current profile info, since it is needed for security checks.
12794            mUserController.onSystemReady();
12795            mRecentTasks.onSystemReadyLocked();
12796            mAppOpsService.systemReady();
12797            mSystemReady = true;
12798        }
12799
12800        ArrayList<ProcessRecord> procsToKill = null;
12801        synchronized(mPidsSelfLocked) {
12802            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12803                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12804                if (!isAllowedWhileBooting(proc.info)){
12805                    if (procsToKill == null) {
12806                        procsToKill = new ArrayList<ProcessRecord>();
12807                    }
12808                    procsToKill.add(proc);
12809                }
12810            }
12811        }
12812
12813        synchronized(this) {
12814            if (procsToKill != null) {
12815                for (int i=procsToKill.size()-1; i>=0; i--) {
12816                    ProcessRecord proc = procsToKill.get(i);
12817                    Slog.i(TAG, "Removing system update proc: " + proc);
12818                    removeProcessLocked(proc, true, false, "system update done");
12819                }
12820            }
12821
12822            // Now that we have cleaned up any update processes, we
12823            // are ready to start launching real processes and know that
12824            // we won't trample on them any more.
12825            mProcessesReady = true;
12826        }
12827
12828        Slog.i(TAG, "System now ready");
12829        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12830            SystemClock.uptimeMillis());
12831
12832        synchronized(this) {
12833            // Make sure we have no pre-ready processes sitting around.
12834
12835            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12836                ResolveInfo ri = mContext.getPackageManager()
12837                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12838                                STOCK_PM_FLAGS);
12839                CharSequence errorMsg = null;
12840                if (ri != null) {
12841                    ActivityInfo ai = ri.activityInfo;
12842                    ApplicationInfo app = ai.applicationInfo;
12843                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12844                        mTopAction = Intent.ACTION_FACTORY_TEST;
12845                        mTopData = null;
12846                        mTopComponent = new ComponentName(app.packageName,
12847                                ai.name);
12848                    } else {
12849                        errorMsg = mContext.getResources().getText(
12850                                com.android.internal.R.string.factorytest_not_system);
12851                    }
12852                } else {
12853                    errorMsg = mContext.getResources().getText(
12854                            com.android.internal.R.string.factorytest_no_action);
12855                }
12856                if (errorMsg != null) {
12857                    mTopAction = null;
12858                    mTopData = null;
12859                    mTopComponent = null;
12860                    Message msg = Message.obtain();
12861                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12862                    msg.getData().putCharSequence("msg", errorMsg);
12863                    mUiHandler.sendMessage(msg);
12864                }
12865            }
12866        }
12867
12868        retrieveSettings();
12869        final int currentUserId;
12870        synchronized (this) {
12871            currentUserId = mUserController.getCurrentUserIdLocked();
12872            readGrantedUriPermissionsLocked();
12873        }
12874
12875        if (goingCallback != null) goingCallback.run();
12876
12877        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12878                Integer.toString(currentUserId), currentUserId);
12879        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12880                Integer.toString(currentUserId), currentUserId);
12881        mSystemServiceManager.startUser(currentUserId);
12882
12883        synchronized (this) {
12884            // Only start up encryption-aware persistent apps; once user is
12885            // unlocked we'll come back around and start unaware apps
12886            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12887
12888            // Start up initial activity.
12889            mBooting = true;
12890            // Enable home activity for system user, so that the system can always boot
12891            if (UserManager.isSplitSystemUser()) {
12892                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12893                try {
12894                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12895                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12896                            UserHandle.USER_SYSTEM);
12897                } catch (RemoteException e) {
12898                    throw e.rethrowAsRuntimeException();
12899                }
12900            }
12901            startHomeActivityLocked(currentUserId, "systemReady");
12902
12903            try {
12904                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12905                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12906                            + " data partition or your device will be unstable.");
12907                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12908                }
12909            } catch (RemoteException e) {
12910            }
12911
12912            if (!Build.isBuildConsistent()) {
12913                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12914                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12915            }
12916
12917            long ident = Binder.clearCallingIdentity();
12918            try {
12919                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12920                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12921                        | Intent.FLAG_RECEIVER_FOREGROUND);
12922                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12923                broadcastIntentLocked(null, null, intent,
12924                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12925                        null, false, false, MY_PID, Process.SYSTEM_UID,
12926                        currentUserId);
12927                intent = new Intent(Intent.ACTION_USER_STARTING);
12928                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12929                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12930                broadcastIntentLocked(null, null, intent,
12931                        null, new IIntentReceiver.Stub() {
12932                            @Override
12933                            public void performReceive(Intent intent, int resultCode, String data,
12934                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12935                                    throws RemoteException {
12936                            }
12937                        }, 0, null, null,
12938                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12939                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12940            } catch (Throwable t) {
12941                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12942            } finally {
12943                Binder.restoreCallingIdentity(ident);
12944            }
12945            mStackSupervisor.resumeFocusedStackTopActivityLocked();
12946            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12947        }
12948    }
12949
12950    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12951        synchronized (this) {
12952            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12953        }
12954    }
12955
12956    void skipCurrentReceiverLocked(ProcessRecord app) {
12957        for (BroadcastQueue queue : mBroadcastQueues) {
12958            queue.skipCurrentReceiverLocked(app);
12959        }
12960    }
12961
12962    /**
12963     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12964     * The application process will exit immediately after this call returns.
12965     * @param app object of the crashing app, null for the system server
12966     * @param crashInfo describing the exception
12967     */
12968    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12969        ProcessRecord r = findAppProcess(app, "Crash");
12970        final String processName = app == null ? "system_server"
12971                : (r == null ? "unknown" : r.processName);
12972
12973        handleApplicationCrashInner("crash", r, processName, crashInfo);
12974    }
12975
12976    /* Native crash reporting uses this inner version because it needs to be somewhat
12977     * decoupled from the AM-managed cleanup lifecycle
12978     */
12979    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12980            ApplicationErrorReport.CrashInfo crashInfo) {
12981        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12982                UserHandle.getUserId(Binder.getCallingUid()), processName,
12983                r == null ? -1 : r.info.flags,
12984                crashInfo.exceptionClassName,
12985                crashInfo.exceptionMessage,
12986                crashInfo.throwFileName,
12987                crashInfo.throwLineNumber);
12988
12989        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12990
12991        mAppErrors.crashApplication(r, crashInfo);
12992    }
12993
12994    public void handleApplicationStrictModeViolation(
12995            IBinder app,
12996            int violationMask,
12997            StrictMode.ViolationInfo info) {
12998        ProcessRecord r = findAppProcess(app, "StrictMode");
12999        if (r == null) {
13000            return;
13001        }
13002
13003        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13004            Integer stackFingerprint = info.hashCode();
13005            boolean logIt = true;
13006            synchronized (mAlreadyLoggedViolatedStacks) {
13007                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13008                    logIt = false;
13009                    // TODO: sub-sample into EventLog for these, with
13010                    // the info.durationMillis?  Then we'd get
13011                    // the relative pain numbers, without logging all
13012                    // the stack traces repeatedly.  We'd want to do
13013                    // likewise in the client code, which also does
13014                    // dup suppression, before the Binder call.
13015                } else {
13016                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13017                        mAlreadyLoggedViolatedStacks.clear();
13018                    }
13019                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13020                }
13021            }
13022            if (logIt) {
13023                logStrictModeViolationToDropBox(r, info);
13024            }
13025        }
13026
13027        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13028            AppErrorResult result = new AppErrorResult();
13029            synchronized (this) {
13030                final long origId = Binder.clearCallingIdentity();
13031
13032                Message msg = Message.obtain();
13033                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13034                HashMap<String, Object> data = new HashMap<String, Object>();
13035                data.put("result", result);
13036                data.put("app", r);
13037                data.put("violationMask", violationMask);
13038                data.put("info", info);
13039                msg.obj = data;
13040                mUiHandler.sendMessage(msg);
13041
13042                Binder.restoreCallingIdentity(origId);
13043            }
13044            int res = result.get();
13045            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13046        }
13047    }
13048
13049    // Depending on the policy in effect, there could be a bunch of
13050    // these in quick succession so we try to batch these together to
13051    // minimize disk writes, number of dropbox entries, and maximize
13052    // compression, by having more fewer, larger records.
13053    private void logStrictModeViolationToDropBox(
13054            ProcessRecord process,
13055            StrictMode.ViolationInfo info) {
13056        if (info == null) {
13057            return;
13058        }
13059        final boolean isSystemApp = process == null ||
13060                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13061                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13062        final String processName = process == null ? "unknown" : process.processName;
13063        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13064        final DropBoxManager dbox = (DropBoxManager)
13065                mContext.getSystemService(Context.DROPBOX_SERVICE);
13066
13067        // Exit early if the dropbox isn't configured to accept this report type.
13068        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13069
13070        boolean bufferWasEmpty;
13071        boolean needsFlush;
13072        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13073        synchronized (sb) {
13074            bufferWasEmpty = sb.length() == 0;
13075            appendDropBoxProcessHeaders(process, processName, sb);
13076            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13077            sb.append("System-App: ").append(isSystemApp).append("\n");
13078            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13079            if (info.violationNumThisLoop != 0) {
13080                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13081            }
13082            if (info.numAnimationsRunning != 0) {
13083                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13084            }
13085            if (info.broadcastIntentAction != null) {
13086                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13087            }
13088            if (info.durationMillis != -1) {
13089                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13090            }
13091            if (info.numInstances != -1) {
13092                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13093            }
13094            if (info.tags != null) {
13095                for (String tag : info.tags) {
13096                    sb.append("Span-Tag: ").append(tag).append("\n");
13097                }
13098            }
13099            sb.append("\n");
13100            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13101                sb.append(info.crashInfo.stackTrace);
13102                sb.append("\n");
13103            }
13104            if (info.message != null) {
13105                sb.append(info.message);
13106                sb.append("\n");
13107            }
13108
13109            // Only buffer up to ~64k.  Various logging bits truncate
13110            // things at 128k.
13111            needsFlush = (sb.length() > 64 * 1024);
13112        }
13113
13114        // Flush immediately if the buffer's grown too large, or this
13115        // is a non-system app.  Non-system apps are isolated with a
13116        // different tag & policy and not batched.
13117        //
13118        // Batching is useful during internal testing with
13119        // StrictMode settings turned up high.  Without batching,
13120        // thousands of separate files could be created on boot.
13121        if (!isSystemApp || needsFlush) {
13122            new Thread("Error dump: " + dropboxTag) {
13123                @Override
13124                public void run() {
13125                    String report;
13126                    synchronized (sb) {
13127                        report = sb.toString();
13128                        sb.delete(0, sb.length());
13129                        sb.trimToSize();
13130                    }
13131                    if (report.length() != 0) {
13132                        dbox.addText(dropboxTag, report);
13133                    }
13134                }
13135            }.start();
13136            return;
13137        }
13138
13139        // System app batching:
13140        if (!bufferWasEmpty) {
13141            // An existing dropbox-writing thread is outstanding, so
13142            // we don't need to start it up.  The existing thread will
13143            // catch the buffer appends we just did.
13144            return;
13145        }
13146
13147        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13148        // (After this point, we shouldn't access AMS internal data structures.)
13149        new Thread("Error dump: " + dropboxTag) {
13150            @Override
13151            public void run() {
13152                // 5 second sleep to let stacks arrive and be batched together
13153                try {
13154                    Thread.sleep(5000);  // 5 seconds
13155                } catch (InterruptedException e) {}
13156
13157                String errorReport;
13158                synchronized (mStrictModeBuffer) {
13159                    errorReport = mStrictModeBuffer.toString();
13160                    if (errorReport.length() == 0) {
13161                        return;
13162                    }
13163                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13164                    mStrictModeBuffer.trimToSize();
13165                }
13166                dbox.addText(dropboxTag, errorReport);
13167            }
13168        }.start();
13169    }
13170
13171    /**
13172     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13173     * @param app object of the crashing app, null for the system server
13174     * @param tag reported by the caller
13175     * @param system whether this wtf is coming from the system
13176     * @param crashInfo describing the context of the error
13177     * @return true if the process should exit immediately (WTF is fatal)
13178     */
13179    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13180            final ApplicationErrorReport.CrashInfo crashInfo) {
13181        final int callingUid = Binder.getCallingUid();
13182        final int callingPid = Binder.getCallingPid();
13183
13184        if (system) {
13185            // If this is coming from the system, we could very well have low-level
13186            // system locks held, so we want to do this all asynchronously.  And we
13187            // never want this to become fatal, so there is that too.
13188            mHandler.post(new Runnable() {
13189                @Override public void run() {
13190                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13191                }
13192            });
13193            return false;
13194        }
13195
13196        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13197                crashInfo);
13198
13199        if (r != null && r.pid != Process.myPid() &&
13200                Settings.Global.getInt(mContext.getContentResolver(),
13201                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13202            mAppErrors.crashApplication(r, crashInfo);
13203            return true;
13204        } else {
13205            return false;
13206        }
13207    }
13208
13209    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13210            final ApplicationErrorReport.CrashInfo crashInfo) {
13211        final ProcessRecord r = findAppProcess(app, "WTF");
13212        final String processName = app == null ? "system_server"
13213                : (r == null ? "unknown" : r.processName);
13214
13215        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13216                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13217
13218        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13219
13220        return r;
13221    }
13222
13223    /**
13224     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13225     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13226     */
13227    private ProcessRecord findAppProcess(IBinder app, String reason) {
13228        if (app == null) {
13229            return null;
13230        }
13231
13232        synchronized (this) {
13233            final int NP = mProcessNames.getMap().size();
13234            for (int ip=0; ip<NP; ip++) {
13235                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13236                final int NA = apps.size();
13237                for (int ia=0; ia<NA; ia++) {
13238                    ProcessRecord p = apps.valueAt(ia);
13239                    if (p.thread != null && p.thread.asBinder() == app) {
13240                        return p;
13241                    }
13242                }
13243            }
13244
13245            Slog.w(TAG, "Can't find mystery application for " + reason
13246                    + " from pid=" + Binder.getCallingPid()
13247                    + " uid=" + Binder.getCallingUid() + ": " + app);
13248            return null;
13249        }
13250    }
13251
13252    /**
13253     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13254     * to append various headers to the dropbox log text.
13255     */
13256    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13257            StringBuilder sb) {
13258        // Watchdog thread ends up invoking this function (with
13259        // a null ProcessRecord) to add the stack file to dropbox.
13260        // Do not acquire a lock on this (am) in such cases, as it
13261        // could cause a potential deadlock, if and when watchdog
13262        // is invoked due to unavailability of lock on am and it
13263        // would prevent watchdog from killing system_server.
13264        if (process == null) {
13265            sb.append("Process: ").append(processName).append("\n");
13266            return;
13267        }
13268        // Note: ProcessRecord 'process' is guarded by the service
13269        // instance.  (notably process.pkgList, which could otherwise change
13270        // concurrently during execution of this method)
13271        synchronized (this) {
13272            sb.append("Process: ").append(processName).append("\n");
13273            int flags = process.info.flags;
13274            IPackageManager pm = AppGlobals.getPackageManager();
13275            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13276            for (int ip=0; ip<process.pkgList.size(); ip++) {
13277                String pkg = process.pkgList.keyAt(ip);
13278                sb.append("Package: ").append(pkg);
13279                try {
13280                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13281                    if (pi != null) {
13282                        sb.append(" v").append(pi.versionCode);
13283                        if (pi.versionName != null) {
13284                            sb.append(" (").append(pi.versionName).append(")");
13285                        }
13286                    }
13287                } catch (RemoteException e) {
13288                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13289                }
13290                sb.append("\n");
13291            }
13292        }
13293    }
13294
13295    private static String processClass(ProcessRecord process) {
13296        if (process == null || process.pid == MY_PID) {
13297            return "system_server";
13298        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13299            return "system_app";
13300        } else {
13301            return "data_app";
13302        }
13303    }
13304
13305    private volatile long mWtfClusterStart;
13306    private volatile int mWtfClusterCount;
13307
13308    /**
13309     * Write a description of an error (crash, WTF, ANR) to the drop box.
13310     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13311     * @param process which caused the error, null means the system server
13312     * @param activity which triggered the error, null if unknown
13313     * @param parent activity related to the error, null if unknown
13314     * @param subject line related to the error, null if absent
13315     * @param report in long form describing the error, null if absent
13316     * @param logFile to include in the report, null if none
13317     * @param crashInfo giving an application stack trace, null if absent
13318     */
13319    public void addErrorToDropBox(String eventType,
13320            ProcessRecord process, String processName, ActivityRecord activity,
13321            ActivityRecord parent, String subject,
13322            final String report, final File logFile,
13323            final ApplicationErrorReport.CrashInfo crashInfo) {
13324        // NOTE -- this must never acquire the ActivityManagerService lock,
13325        // otherwise the watchdog may be prevented from resetting the system.
13326
13327        final String dropboxTag = processClass(process) + "_" + eventType;
13328        final DropBoxManager dbox = (DropBoxManager)
13329                mContext.getSystemService(Context.DROPBOX_SERVICE);
13330
13331        // Exit early if the dropbox isn't configured to accept this report type.
13332        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13333
13334        // Rate-limit how often we're willing to do the heavy lifting below to
13335        // collect and record logs; currently 5 logs per 10 second period.
13336        final long now = SystemClock.elapsedRealtime();
13337        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13338            mWtfClusterStart = now;
13339            mWtfClusterCount = 1;
13340        } else {
13341            if (mWtfClusterCount++ >= 5) return;
13342        }
13343
13344        final StringBuilder sb = new StringBuilder(1024);
13345        appendDropBoxProcessHeaders(process, processName, sb);
13346        if (process != null) {
13347            sb.append("Foreground: ")
13348                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13349                    .append("\n");
13350        }
13351        if (activity != null) {
13352            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13353        }
13354        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13355            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13356        }
13357        if (parent != null && parent != activity) {
13358            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13359        }
13360        if (subject != null) {
13361            sb.append("Subject: ").append(subject).append("\n");
13362        }
13363        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13364        if (Debug.isDebuggerConnected()) {
13365            sb.append("Debugger: Connected\n");
13366        }
13367        sb.append("\n");
13368
13369        // Do the rest in a worker thread to avoid blocking the caller on I/O
13370        // (After this point, we shouldn't access AMS internal data structures.)
13371        Thread worker = new Thread("Error dump: " + dropboxTag) {
13372            @Override
13373            public void run() {
13374                if (report != null) {
13375                    sb.append(report);
13376                }
13377                if (logFile != null) {
13378                    try {
13379                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13380                                    "\n\n[[TRUNCATED]]"));
13381                    } catch (IOException e) {
13382                        Slog.e(TAG, "Error reading " + logFile, e);
13383                    }
13384                }
13385                if (crashInfo != null && crashInfo.stackTrace != null) {
13386                    sb.append(crashInfo.stackTrace);
13387                }
13388
13389                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13390                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13391                if (lines > 0) {
13392                    sb.append("\n");
13393
13394                    // Merge several logcat streams, and take the last N lines
13395                    InputStreamReader input = null;
13396                    try {
13397                        java.lang.Process logcat = new ProcessBuilder(
13398                                "/system/bin/timeout", "-k", "15s", "10s",
13399                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13400                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13401                                        .redirectErrorStream(true).start();
13402
13403                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13404                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13405                        input = new InputStreamReader(logcat.getInputStream());
13406
13407                        int num;
13408                        char[] buf = new char[8192];
13409                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13410                    } catch (IOException e) {
13411                        Slog.e(TAG, "Error running logcat", e);
13412                    } finally {
13413                        if (input != null) try { input.close(); } catch (IOException e) {}
13414                    }
13415                }
13416
13417                dbox.addText(dropboxTag, sb.toString());
13418            }
13419        };
13420
13421        if (process == null) {
13422            // If process is null, we are being called from some internal code
13423            // and may be about to die -- run this synchronously.
13424            worker.run();
13425        } else {
13426            worker.start();
13427        }
13428    }
13429
13430    @Override
13431    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13432        enforceNotIsolatedCaller("getProcessesInErrorState");
13433        // assume our apps are happy - lazy create the list
13434        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13435
13436        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13437                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13438        int userId = UserHandle.getUserId(Binder.getCallingUid());
13439
13440        synchronized (this) {
13441
13442            // iterate across all processes
13443            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13444                ProcessRecord app = mLruProcesses.get(i);
13445                if (!allUsers && app.userId != userId) {
13446                    continue;
13447                }
13448                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13449                    // This one's in trouble, so we'll generate a report for it
13450                    // crashes are higher priority (in case there's a crash *and* an anr)
13451                    ActivityManager.ProcessErrorStateInfo report = null;
13452                    if (app.crashing) {
13453                        report = app.crashingReport;
13454                    } else if (app.notResponding) {
13455                        report = app.notRespondingReport;
13456                    }
13457
13458                    if (report != null) {
13459                        if (errList == null) {
13460                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13461                        }
13462                        errList.add(report);
13463                    } else {
13464                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13465                                " crashing = " + app.crashing +
13466                                " notResponding = " + app.notResponding);
13467                    }
13468                }
13469            }
13470        }
13471
13472        return errList;
13473    }
13474
13475    static int procStateToImportance(int procState, int memAdj,
13476            ActivityManager.RunningAppProcessInfo currApp) {
13477        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13478        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13479            currApp.lru = memAdj;
13480        } else {
13481            currApp.lru = 0;
13482        }
13483        return imp;
13484    }
13485
13486    private void fillInProcMemInfo(ProcessRecord app,
13487            ActivityManager.RunningAppProcessInfo outInfo) {
13488        outInfo.pid = app.pid;
13489        outInfo.uid = app.info.uid;
13490        if (mHeavyWeightProcess == app) {
13491            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13492        }
13493        if (app.persistent) {
13494            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13495        }
13496        if (app.activities.size() > 0) {
13497            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13498        }
13499        outInfo.lastTrimLevel = app.trimMemoryLevel;
13500        int adj = app.curAdj;
13501        int procState = app.curProcState;
13502        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13503        outInfo.importanceReasonCode = app.adjTypeCode;
13504        outInfo.processState = app.curProcState;
13505    }
13506
13507    @Override
13508    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13509        enforceNotIsolatedCaller("getRunningAppProcesses");
13510
13511        final int callingUid = Binder.getCallingUid();
13512
13513        // Lazy instantiation of list
13514        List<ActivityManager.RunningAppProcessInfo> runList = null;
13515        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13516                callingUid) == PackageManager.PERMISSION_GRANTED;
13517        final int userId = UserHandle.getUserId(callingUid);
13518        final boolean allUids = isGetTasksAllowed(
13519                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13520
13521        synchronized (this) {
13522            // Iterate across all processes
13523            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13524                ProcessRecord app = mLruProcesses.get(i);
13525                if ((!allUsers && app.userId != userId)
13526                        || (!allUids && app.uid != callingUid)) {
13527                    continue;
13528                }
13529                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13530                    // Generate process state info for running application
13531                    ActivityManager.RunningAppProcessInfo currApp =
13532                        new ActivityManager.RunningAppProcessInfo(app.processName,
13533                                app.pid, app.getPackageList());
13534                    fillInProcMemInfo(app, currApp);
13535                    if (app.adjSource instanceof ProcessRecord) {
13536                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13537                        currApp.importanceReasonImportance =
13538                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13539                                        app.adjSourceProcState);
13540                    } else if (app.adjSource instanceof ActivityRecord) {
13541                        ActivityRecord r = (ActivityRecord)app.adjSource;
13542                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13543                    }
13544                    if (app.adjTarget instanceof ComponentName) {
13545                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13546                    }
13547                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13548                    //        + " lru=" + currApp.lru);
13549                    if (runList == null) {
13550                        runList = new ArrayList<>();
13551                    }
13552                    runList.add(currApp);
13553                }
13554            }
13555        }
13556        return runList;
13557    }
13558
13559    @Override
13560    public List<ApplicationInfo> getRunningExternalApplications() {
13561        enforceNotIsolatedCaller("getRunningExternalApplications");
13562        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13563        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13564        if (runningApps != null && runningApps.size() > 0) {
13565            Set<String> extList = new HashSet<String>();
13566            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13567                if (app.pkgList != null) {
13568                    for (String pkg : app.pkgList) {
13569                        extList.add(pkg);
13570                    }
13571                }
13572            }
13573            IPackageManager pm = AppGlobals.getPackageManager();
13574            for (String pkg : extList) {
13575                try {
13576                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13577                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13578                        retList.add(info);
13579                    }
13580                } catch (RemoteException e) {
13581                }
13582            }
13583        }
13584        return retList;
13585    }
13586
13587    @Override
13588    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13589        enforceNotIsolatedCaller("getMyMemoryState");
13590        synchronized (this) {
13591            ProcessRecord proc;
13592            synchronized (mPidsSelfLocked) {
13593                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13594            }
13595            fillInProcMemInfo(proc, outInfo);
13596        }
13597    }
13598
13599    @Override
13600    public int getMemoryTrimLevel() {
13601        enforceNotIsolatedCaller("getMyMemoryState");
13602        synchronized (this) {
13603            return mLastMemoryLevel;
13604        }
13605    }
13606
13607    @Override
13608    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13609            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13610        (new ActivityManagerShellCommand(this, false)).exec(
13611                this, in, out, err, args, resultReceiver);
13612    }
13613
13614    @Override
13615    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13616        if (checkCallingPermission(android.Manifest.permission.DUMP)
13617                != PackageManager.PERMISSION_GRANTED) {
13618            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13619                    + Binder.getCallingPid()
13620                    + ", uid=" + Binder.getCallingUid()
13621                    + " without permission "
13622                    + android.Manifest.permission.DUMP);
13623            return;
13624        }
13625
13626        boolean dumpAll = false;
13627        boolean dumpClient = false;
13628        String dumpPackage = null;
13629
13630        int opti = 0;
13631        while (opti < args.length) {
13632            String opt = args[opti];
13633            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13634                break;
13635            }
13636            opti++;
13637            if ("-a".equals(opt)) {
13638                dumpAll = true;
13639            } else if ("-c".equals(opt)) {
13640                dumpClient = true;
13641            } else if ("-p".equals(opt)) {
13642                if (opti < args.length) {
13643                    dumpPackage = args[opti];
13644                    opti++;
13645                } else {
13646                    pw.println("Error: -p option requires package argument");
13647                    return;
13648                }
13649                dumpClient = true;
13650            } else if ("-h".equals(opt)) {
13651                ActivityManagerShellCommand.dumpHelp(pw, true);
13652                return;
13653            } else {
13654                pw.println("Unknown argument: " + opt + "; use -h for help");
13655            }
13656        }
13657
13658        long origId = Binder.clearCallingIdentity();
13659        boolean more = false;
13660        // Is the caller requesting to dump a particular piece of data?
13661        if (opti < args.length) {
13662            String cmd = args[opti];
13663            opti++;
13664            if ("activities".equals(cmd) || "a".equals(cmd)) {
13665                synchronized (this) {
13666                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13667                }
13668            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13669                synchronized (this) {
13670                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13671                }
13672            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13673                String[] newArgs;
13674                String name;
13675                if (opti >= args.length) {
13676                    name = null;
13677                    newArgs = EMPTY_STRING_ARRAY;
13678                } else {
13679                    dumpPackage = args[opti];
13680                    opti++;
13681                    newArgs = new String[args.length - opti];
13682                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13683                            args.length - opti);
13684                }
13685                synchronized (this) {
13686                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13687                }
13688            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13689                String[] newArgs;
13690                String name;
13691                if (opti >= args.length) {
13692                    name = null;
13693                    newArgs = EMPTY_STRING_ARRAY;
13694                } else {
13695                    dumpPackage = args[opti];
13696                    opti++;
13697                    newArgs = new String[args.length - opti];
13698                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13699                            args.length - opti);
13700                }
13701                synchronized (this) {
13702                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13703                }
13704            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13705                String[] newArgs;
13706                String name;
13707                if (opti >= args.length) {
13708                    name = null;
13709                    newArgs = EMPTY_STRING_ARRAY;
13710                } else {
13711                    dumpPackage = args[opti];
13712                    opti++;
13713                    newArgs = new String[args.length - opti];
13714                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13715                            args.length - opti);
13716                }
13717                synchronized (this) {
13718                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13719                }
13720            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13721                synchronized (this) {
13722                    dumpOomLocked(fd, pw, args, opti, true);
13723                }
13724            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13725                synchronized (this) {
13726                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13727                }
13728            } else if ("provider".equals(cmd)) {
13729                String[] newArgs;
13730                String name;
13731                if (opti >= args.length) {
13732                    name = null;
13733                    newArgs = EMPTY_STRING_ARRAY;
13734                } else {
13735                    name = args[opti];
13736                    opti++;
13737                    newArgs = new String[args.length - opti];
13738                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13739                }
13740                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13741                    pw.println("No providers match: " + name);
13742                    pw.println("Use -h for help.");
13743                }
13744            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13745                synchronized (this) {
13746                    dumpProvidersLocked(fd, pw, args, opti, true, null);
13747                }
13748            } else if ("service".equals(cmd)) {
13749                String[] newArgs;
13750                String name;
13751                if (opti >= args.length) {
13752                    name = null;
13753                    newArgs = EMPTY_STRING_ARRAY;
13754                } else {
13755                    name = args[opti];
13756                    opti++;
13757                    newArgs = new String[args.length - opti];
13758                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13759                            args.length - opti);
13760                }
13761                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13762                    pw.println("No services match: " + name);
13763                    pw.println("Use -h for help.");
13764                }
13765            } else if ("package".equals(cmd)) {
13766                String[] newArgs;
13767                if (opti >= args.length) {
13768                    pw.println("package: no package name specified");
13769                    pw.println("Use -h for help.");
13770                } else {
13771                    dumpPackage = args[opti];
13772                    opti++;
13773                    newArgs = new String[args.length - opti];
13774                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13775                            args.length - opti);
13776                    args = newArgs;
13777                    opti = 0;
13778                    more = true;
13779                }
13780            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13781                synchronized (this) {
13782                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13783                }
13784            } else if ("services".equals(cmd) || "s".equals(cmd)) {
13785                synchronized (this) {
13786                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13787                }
13788            } else if ("locks".equals(cmd)) {
13789                LockGuard.dump(fd, pw, args);
13790            } else {
13791                // Dumping a single activity?
13792                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13793                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13794                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13795                    if (res < 0) {
13796                        pw.println("Bad activity command, or no activities match: " + cmd);
13797                        pw.println("Use -h for help.");
13798                    }
13799                }
13800            }
13801            if (!more) {
13802                Binder.restoreCallingIdentity(origId);
13803                return;
13804            }
13805        }
13806
13807        // No piece of data specified, dump everything.
13808        synchronized (this) {
13809            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13810            pw.println();
13811            if (dumpAll) {
13812                pw.println("-------------------------------------------------------------------------------");
13813            }
13814            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13815            pw.println();
13816            if (dumpAll) {
13817                pw.println("-------------------------------------------------------------------------------");
13818            }
13819            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13820            pw.println();
13821            if (dumpAll) {
13822                pw.println("-------------------------------------------------------------------------------");
13823            }
13824            dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13825            pw.println();
13826            if (dumpAll) {
13827                pw.println("-------------------------------------------------------------------------------");
13828            }
13829            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13830            pw.println();
13831            if (dumpAll) {
13832                pw.println("-------------------------------------------------------------------------------");
13833            }
13834            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13835            pw.println();
13836            if (dumpAll) {
13837                pw.println("-------------------------------------------------------------------------------");
13838            }
13839            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13840            if (mAssociations.size() > 0) {
13841                pw.println();
13842                if (dumpAll) {
13843                    pw.println("-------------------------------------------------------------------------------");
13844                }
13845                dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13846            }
13847            pw.println();
13848            if (dumpAll) {
13849                pw.println("-------------------------------------------------------------------------------");
13850            }
13851            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13852        }
13853        Binder.restoreCallingIdentity(origId);
13854    }
13855
13856    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13857            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13858        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13859
13860        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13861                dumpPackage);
13862        boolean needSep = printedAnything;
13863
13864        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13865                dumpPackage, needSep, "  mFocusedActivity: ");
13866        if (printed) {
13867            printedAnything = true;
13868            needSep = false;
13869        }
13870
13871        if (dumpPackage == null) {
13872            if (needSep) {
13873                pw.println();
13874            }
13875            needSep = true;
13876            printedAnything = true;
13877            mStackSupervisor.dump(pw, "  ");
13878        }
13879
13880        if (!printedAnything) {
13881            pw.println("  (nothing)");
13882        }
13883    }
13884
13885    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13886            int opti, boolean dumpAll, String dumpPackage) {
13887        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13888
13889        boolean printedAnything = false;
13890
13891        if (mRecentTasks != null && mRecentTasks.size() > 0) {
13892            boolean printedHeader = false;
13893
13894            final int N = mRecentTasks.size();
13895            for (int i=0; i<N; i++) {
13896                TaskRecord tr = mRecentTasks.get(i);
13897                if (dumpPackage != null) {
13898                    if (tr.realActivity == null ||
13899                            !dumpPackage.equals(tr.realActivity)) {
13900                        continue;
13901                    }
13902                }
13903                if (!printedHeader) {
13904                    pw.println("  Recent tasks:");
13905                    printedHeader = true;
13906                    printedAnything = true;
13907                }
13908                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
13909                        pw.println(tr);
13910                if (dumpAll) {
13911                    mRecentTasks.get(i).dump(pw, "    ");
13912                }
13913            }
13914        }
13915
13916        if (!printedAnything) {
13917            pw.println("  (nothing)");
13918        }
13919    }
13920
13921    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13922            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13923        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13924
13925        int dumpUid = 0;
13926        if (dumpPackage != null) {
13927            IPackageManager pm = AppGlobals.getPackageManager();
13928            try {
13929                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13930            } catch (RemoteException e) {
13931            }
13932        }
13933
13934        boolean printedAnything = false;
13935
13936        final long now = SystemClock.uptimeMillis();
13937
13938        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13939            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13940                    = mAssociations.valueAt(i1);
13941            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13942                SparseArray<ArrayMap<String, Association>> sourceUids
13943                        = targetComponents.valueAt(i2);
13944                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13945                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13946                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13947                        Association ass = sourceProcesses.valueAt(i4);
13948                        if (dumpPackage != null) {
13949                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13950                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13951                                continue;
13952                            }
13953                        }
13954                        printedAnything = true;
13955                        pw.print("  ");
13956                        pw.print(ass.mTargetProcess);
13957                        pw.print("/");
13958                        UserHandle.formatUid(pw, ass.mTargetUid);
13959                        pw.print(" <- ");
13960                        pw.print(ass.mSourceProcess);
13961                        pw.print("/");
13962                        UserHandle.formatUid(pw, ass.mSourceUid);
13963                        pw.println();
13964                        pw.print("    via ");
13965                        pw.print(ass.mTargetComponent.flattenToShortString());
13966                        pw.println();
13967                        pw.print("    ");
13968                        long dur = ass.mTime;
13969                        if (ass.mNesting > 0) {
13970                            dur += now - ass.mStartTime;
13971                        }
13972                        TimeUtils.formatDuration(dur, pw);
13973                        pw.print(" (");
13974                        pw.print(ass.mCount);
13975                        pw.print(" times)");
13976                        pw.print("  ");
13977                        for (int i=0; i<ass.mStateTimes.length; i++) {
13978                            long amt = ass.mStateTimes[i];
13979                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13980                                amt += now - ass.mLastStateUptime;
13981                            }
13982                            if (amt != 0) {
13983                                pw.print(" ");
13984                                pw.print(ProcessList.makeProcStateString(
13985                                            i + ActivityManager.MIN_PROCESS_STATE));
13986                                pw.print("=");
13987                                TimeUtils.formatDuration(amt, pw);
13988                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
13989                                    pw.print("*");
13990                                }
13991                            }
13992                        }
13993                        pw.println();
13994                        if (ass.mNesting > 0) {
13995                            pw.print("    Currently active: ");
13996                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
13997                            pw.println();
13998                        }
13999                    }
14000                }
14001            }
14002
14003        }
14004
14005        if (!printedAnything) {
14006            pw.println("  (nothing)");
14007        }
14008    }
14009
14010    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14011            String header, boolean needSep) {
14012        boolean printed = false;
14013        int whichAppId = -1;
14014        if (dumpPackage != null) {
14015            try {
14016                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14017                        dumpPackage, 0);
14018                whichAppId = UserHandle.getAppId(info.uid);
14019            } catch (NameNotFoundException e) {
14020                e.printStackTrace();
14021            }
14022        }
14023        for (int i=0; i<uids.size(); i++) {
14024            UidRecord uidRec = uids.valueAt(i);
14025            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14026                continue;
14027            }
14028            if (!printed) {
14029                printed = true;
14030                if (needSep) {
14031                    pw.println();
14032                }
14033                pw.print("  ");
14034                pw.println(header);
14035                needSep = true;
14036            }
14037            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14038            pw.print(": "); pw.println(uidRec);
14039        }
14040        return printed;
14041    }
14042
14043    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14044            int opti, boolean dumpAll, String dumpPackage) {
14045        boolean needSep = false;
14046        boolean printedAnything = false;
14047        int numPers = 0;
14048
14049        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14050
14051        if (dumpAll) {
14052            final int NP = mProcessNames.getMap().size();
14053            for (int ip=0; ip<NP; ip++) {
14054                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14055                final int NA = procs.size();
14056                for (int ia=0; ia<NA; ia++) {
14057                    ProcessRecord r = procs.valueAt(ia);
14058                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14059                        continue;
14060                    }
14061                    if (!needSep) {
14062                        pw.println("  All known processes:");
14063                        needSep = true;
14064                        printedAnything = true;
14065                    }
14066                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14067                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14068                        pw.print(" "); pw.println(r);
14069                    r.dump(pw, "    ");
14070                    if (r.persistent) {
14071                        numPers++;
14072                    }
14073                }
14074            }
14075        }
14076
14077        if (mIsolatedProcesses.size() > 0) {
14078            boolean printed = false;
14079            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14080                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14081                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14082                    continue;
14083                }
14084                if (!printed) {
14085                    if (needSep) {
14086                        pw.println();
14087                    }
14088                    pw.println("  Isolated process list (sorted by uid):");
14089                    printedAnything = true;
14090                    printed = true;
14091                    needSep = true;
14092                }
14093                pw.println(String.format("%sIsolated #%2d: %s",
14094                        "    ", i, r.toString()));
14095            }
14096        }
14097
14098        if (mActiveUids.size() > 0) {
14099            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14100                printedAnything = needSep = true;
14101            }
14102        }
14103        if (mValidateUids.size() > 0) {
14104            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14105                printedAnything = needSep = true;
14106            }
14107        }
14108
14109        if (mLruProcesses.size() > 0) {
14110            if (needSep) {
14111                pw.println();
14112            }
14113            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14114                    pw.print(" total, non-act at ");
14115                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14116                    pw.print(", non-svc at ");
14117                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14118                    pw.println("):");
14119            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14120            needSep = true;
14121            printedAnything = true;
14122        }
14123
14124        if (dumpAll || dumpPackage != null) {
14125            synchronized (mPidsSelfLocked) {
14126                boolean printed = false;
14127                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14128                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14129                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14130                        continue;
14131                    }
14132                    if (!printed) {
14133                        if (needSep) pw.println();
14134                        needSep = true;
14135                        pw.println("  PID mappings:");
14136                        printed = true;
14137                        printedAnything = true;
14138                    }
14139                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14140                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14141                }
14142            }
14143        }
14144
14145        if (mForegroundProcesses.size() > 0) {
14146            synchronized (mPidsSelfLocked) {
14147                boolean printed = false;
14148                for (int i=0; i<mForegroundProcesses.size(); i++) {
14149                    ProcessRecord r = mPidsSelfLocked.get(
14150                            mForegroundProcesses.valueAt(i).pid);
14151                    if (dumpPackage != null && (r == null
14152                            || !r.pkgList.containsKey(dumpPackage))) {
14153                        continue;
14154                    }
14155                    if (!printed) {
14156                        if (needSep) pw.println();
14157                        needSep = true;
14158                        pw.println("  Foreground Processes:");
14159                        printed = true;
14160                        printedAnything = true;
14161                    }
14162                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14163                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14164                }
14165            }
14166        }
14167
14168        if (mPersistentStartingProcesses.size() > 0) {
14169            if (needSep) pw.println();
14170            needSep = true;
14171            printedAnything = true;
14172            pw.println("  Persisent processes that are starting:");
14173            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14174                    "Starting Norm", "Restarting PERS", dumpPackage);
14175        }
14176
14177        if (mRemovedProcesses.size() > 0) {
14178            if (needSep) pw.println();
14179            needSep = true;
14180            printedAnything = true;
14181            pw.println("  Processes that are being removed:");
14182            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14183                    "Removed Norm", "Removed PERS", dumpPackage);
14184        }
14185
14186        if (mProcessesOnHold.size() > 0) {
14187            if (needSep) pw.println();
14188            needSep = true;
14189            printedAnything = true;
14190            pw.println("  Processes that are on old until the system is ready:");
14191            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14192                    "OnHold Norm", "OnHold PERS", dumpPackage);
14193        }
14194
14195        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14196
14197        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14198        if (needSep) {
14199            printedAnything = true;
14200        }
14201
14202        if (dumpPackage == null) {
14203            pw.println();
14204            needSep = false;
14205            mUserController.dump(pw, dumpAll);
14206        }
14207        if (mHomeProcess != null && (dumpPackage == null
14208                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14209            if (needSep) {
14210                pw.println();
14211                needSep = false;
14212            }
14213            pw.println("  mHomeProcess: " + mHomeProcess);
14214        }
14215        if (mPreviousProcess != null && (dumpPackage == null
14216                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14217            if (needSep) {
14218                pw.println();
14219                needSep = false;
14220            }
14221            pw.println("  mPreviousProcess: " + mPreviousProcess);
14222        }
14223        if (dumpAll) {
14224            StringBuilder sb = new StringBuilder(128);
14225            sb.append("  mPreviousProcessVisibleTime: ");
14226            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14227            pw.println(sb);
14228        }
14229        if (mHeavyWeightProcess != null && (dumpPackage == null
14230                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14231            if (needSep) {
14232                pw.println();
14233                needSep = false;
14234            }
14235            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14236        }
14237        if (dumpPackage == null) {
14238            pw.println("  mConfiguration: " + mConfiguration);
14239        }
14240        if (dumpAll) {
14241            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14242            if (mCompatModePackages.getPackages().size() > 0) {
14243                boolean printed = false;
14244                for (Map.Entry<String, Integer> entry
14245                        : mCompatModePackages.getPackages().entrySet()) {
14246                    String pkg = entry.getKey();
14247                    int mode = entry.getValue();
14248                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14249                        continue;
14250                    }
14251                    if (!printed) {
14252                        pw.println("  mScreenCompatPackages:");
14253                        printed = true;
14254                    }
14255                    pw.print("    "); pw.print(pkg); pw.print(": ");
14256                            pw.print(mode); pw.println();
14257                }
14258            }
14259        }
14260        if (dumpPackage == null) {
14261            pw.println("  mWakefulness="
14262                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14263            pw.println("  mSleepTokens=" + mSleepTokens);
14264            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14265                    + lockScreenShownToString());
14266            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14267            if (mRunningVoice != null) {
14268                pw.println("  mRunningVoice=" + mRunningVoice);
14269                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14270            }
14271        }
14272        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14273                || mOrigWaitForDebugger) {
14274            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14275                    || dumpPackage.equals(mOrigDebugApp)) {
14276                if (needSep) {
14277                    pw.println();
14278                    needSep = false;
14279                }
14280                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14281                        + " mDebugTransient=" + mDebugTransient
14282                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14283            }
14284        }
14285        if (mCurAppTimeTracker != null) {
14286            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14287        }
14288        if (mMemWatchProcesses.getMap().size() > 0) {
14289            pw.println("  Mem watch processes:");
14290            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14291                    = mMemWatchProcesses.getMap();
14292            for (int i=0; i<procs.size(); i++) {
14293                final String proc = procs.keyAt(i);
14294                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14295                for (int j=0; j<uids.size(); j++) {
14296                    if (needSep) {
14297                        pw.println();
14298                        needSep = false;
14299                    }
14300                    StringBuilder sb = new StringBuilder();
14301                    sb.append("    ").append(proc).append('/');
14302                    UserHandle.formatUid(sb, uids.keyAt(j));
14303                    Pair<Long, String> val = uids.valueAt(j);
14304                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14305                    if (val.second != null) {
14306                        sb.append(", report to ").append(val.second);
14307                    }
14308                    pw.println(sb.toString());
14309                }
14310            }
14311            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14312            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14313            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14314                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14315        }
14316        if (mTrackAllocationApp != null) {
14317            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14318                if (needSep) {
14319                    pw.println();
14320                    needSep = false;
14321                }
14322                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14323            }
14324        }
14325        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14326                || mProfileFd != null) {
14327            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14328                if (needSep) {
14329                    pw.println();
14330                    needSep = false;
14331                }
14332                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14333                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14334                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14335                        + mAutoStopProfiler);
14336                pw.println("  mProfileType=" + mProfileType);
14337            }
14338        }
14339        if (mNativeDebuggingApp != null) {
14340            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14341                if (needSep) {
14342                    pw.println();
14343                    needSep = false;
14344                }
14345                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14346            }
14347        }
14348        if (dumpPackage == null) {
14349            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14350                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14351                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14352            }
14353            if (mController != null) {
14354                pw.println("  mController=" + mController
14355                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14356            }
14357            if (dumpAll) {
14358                pw.println("  Total persistent processes: " + numPers);
14359                pw.println("  mProcessesReady=" + mProcessesReady
14360                        + " mSystemReady=" + mSystemReady
14361                        + " mBooted=" + mBooted
14362                        + " mFactoryTest=" + mFactoryTest);
14363                pw.println("  mBooting=" + mBooting
14364                        + " mCallFinishBooting=" + mCallFinishBooting
14365                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14366                pw.print("  mLastPowerCheckRealtime=");
14367                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14368                        pw.println("");
14369                pw.print("  mLastPowerCheckUptime=");
14370                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14371                        pw.println("");
14372                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14373                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14374                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14375                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14376                        + " (" + mLruProcesses.size() + " total)"
14377                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14378                        + " mNumServiceProcs=" + mNumServiceProcs
14379                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14380                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14381                        + " mLastMemoryLevel=" + mLastMemoryLevel
14382                        + " mLastNumProcesses=" + mLastNumProcesses);
14383                long now = SystemClock.uptimeMillis();
14384                pw.print("  mLastIdleTime=");
14385                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14386                        pw.print(" mLowRamSinceLastIdle=");
14387                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14388                        pw.println();
14389            }
14390        }
14391
14392        if (!printedAnything) {
14393            pw.println("  (nothing)");
14394        }
14395    }
14396
14397    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14398            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14399        if (mProcessesToGc.size() > 0) {
14400            boolean printed = false;
14401            long now = SystemClock.uptimeMillis();
14402            for (int i=0; i<mProcessesToGc.size(); i++) {
14403                ProcessRecord proc = mProcessesToGc.get(i);
14404                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14405                    continue;
14406                }
14407                if (!printed) {
14408                    if (needSep) pw.println();
14409                    needSep = true;
14410                    pw.println("  Processes that are waiting to GC:");
14411                    printed = true;
14412                }
14413                pw.print("    Process "); pw.println(proc);
14414                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14415                        pw.print(", last gced=");
14416                        pw.print(now-proc.lastRequestedGc);
14417                        pw.print(" ms ago, last lowMem=");
14418                        pw.print(now-proc.lastLowMemory);
14419                        pw.println(" ms ago");
14420
14421            }
14422        }
14423        return needSep;
14424    }
14425
14426    void printOomLevel(PrintWriter pw, String name, int adj) {
14427        pw.print("    ");
14428        if (adj >= 0) {
14429            pw.print(' ');
14430            if (adj < 10) pw.print(' ');
14431        } else {
14432            if (adj > -10) pw.print(' ');
14433        }
14434        pw.print(adj);
14435        pw.print(": ");
14436        pw.print(name);
14437        pw.print(" (");
14438        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14439        pw.println(")");
14440    }
14441
14442    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14443            int opti, boolean dumpAll) {
14444        boolean needSep = false;
14445
14446        if (mLruProcesses.size() > 0) {
14447            if (needSep) pw.println();
14448            needSep = true;
14449            pw.println("  OOM levels:");
14450            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14451            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14452            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14453            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14454            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14455            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14456            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14457            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14458            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14459            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14460            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14461            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14462            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14463            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14464
14465            if (needSep) pw.println();
14466            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14467                    pw.print(" total, non-act at ");
14468                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14469                    pw.print(", non-svc at ");
14470                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14471                    pw.println("):");
14472            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14473            needSep = true;
14474        }
14475
14476        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14477
14478        pw.println();
14479        pw.println("  mHomeProcess: " + mHomeProcess);
14480        pw.println("  mPreviousProcess: " + mPreviousProcess);
14481        if (mHeavyWeightProcess != null) {
14482            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14483        }
14484
14485        return true;
14486    }
14487
14488    /**
14489     * There are three ways to call this:
14490     *  - no provider specified: dump all the providers
14491     *  - a flattened component name that matched an existing provider was specified as the
14492     *    first arg: dump that one provider
14493     *  - the first arg isn't the flattened component name of an existing provider:
14494     *    dump all providers whose component contains the first arg as a substring
14495     */
14496    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14497            int opti, boolean dumpAll) {
14498        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14499    }
14500
14501    static class ItemMatcher {
14502        ArrayList<ComponentName> components;
14503        ArrayList<String> strings;
14504        ArrayList<Integer> objects;
14505        boolean all;
14506
14507        ItemMatcher() {
14508            all = true;
14509        }
14510
14511        void build(String name) {
14512            ComponentName componentName = ComponentName.unflattenFromString(name);
14513            if (componentName != null) {
14514                if (components == null) {
14515                    components = new ArrayList<ComponentName>();
14516                }
14517                components.add(componentName);
14518                all = false;
14519            } else {
14520                int objectId = 0;
14521                // Not a '/' separated full component name; maybe an object ID?
14522                try {
14523                    objectId = Integer.parseInt(name, 16);
14524                    if (objects == null) {
14525                        objects = new ArrayList<Integer>();
14526                    }
14527                    objects.add(objectId);
14528                    all = false;
14529                } catch (RuntimeException e) {
14530                    // Not an integer; just do string match.
14531                    if (strings == null) {
14532                        strings = new ArrayList<String>();
14533                    }
14534                    strings.add(name);
14535                    all = false;
14536                }
14537            }
14538        }
14539
14540        int build(String[] args, int opti) {
14541            for (; opti<args.length; opti++) {
14542                String name = args[opti];
14543                if ("--".equals(name)) {
14544                    return opti+1;
14545                }
14546                build(name);
14547            }
14548            return opti;
14549        }
14550
14551        boolean match(Object object, ComponentName comp) {
14552            if (all) {
14553                return true;
14554            }
14555            if (components != null) {
14556                for (int i=0; i<components.size(); i++) {
14557                    if (components.get(i).equals(comp)) {
14558                        return true;
14559                    }
14560                }
14561            }
14562            if (objects != null) {
14563                for (int i=0; i<objects.size(); i++) {
14564                    if (System.identityHashCode(object) == objects.get(i)) {
14565                        return true;
14566                    }
14567                }
14568            }
14569            if (strings != null) {
14570                String flat = comp.flattenToString();
14571                for (int i=0; i<strings.size(); i++) {
14572                    if (flat.contains(strings.get(i))) {
14573                        return true;
14574                    }
14575                }
14576            }
14577            return false;
14578        }
14579    }
14580
14581    /**
14582     * There are three things that cmd can be:
14583     *  - a flattened component name that matches an existing activity
14584     *  - the cmd arg isn't the flattened component name of an existing activity:
14585     *    dump all activity whose component contains the cmd as a substring
14586     *  - A hex number of the ActivityRecord object instance.
14587     */
14588    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14589            int opti, boolean dumpAll) {
14590        ArrayList<ActivityRecord> activities;
14591
14592        synchronized (this) {
14593            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14594        }
14595
14596        if (activities.size() <= 0) {
14597            return false;
14598        }
14599
14600        String[] newArgs = new String[args.length - opti];
14601        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14602
14603        TaskRecord lastTask = null;
14604        boolean needSep = false;
14605        for (int i=activities.size()-1; i>=0; i--) {
14606            ActivityRecord r = activities.get(i);
14607            if (needSep) {
14608                pw.println();
14609            }
14610            needSep = true;
14611            synchronized (this) {
14612                if (lastTask != r.task) {
14613                    lastTask = r.task;
14614                    pw.print("TASK "); pw.print(lastTask.affinity);
14615                            pw.print(" id="); pw.println(lastTask.taskId);
14616                    if (dumpAll) {
14617                        lastTask.dump(pw, "  ");
14618                    }
14619                }
14620            }
14621            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14622        }
14623        return true;
14624    }
14625
14626    /**
14627     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14628     * there is a thread associated with the activity.
14629     */
14630    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14631            final ActivityRecord r, String[] args, boolean dumpAll) {
14632        String innerPrefix = prefix + "  ";
14633        synchronized (this) {
14634            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14635                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14636                    pw.print(" pid=");
14637                    if (r.app != null) pw.println(r.app.pid);
14638                    else pw.println("(not running)");
14639            if (dumpAll) {
14640                r.dump(pw, innerPrefix);
14641            }
14642        }
14643        if (r.app != null && r.app.thread != null) {
14644            // flush anything that is already in the PrintWriter since the thread is going
14645            // to write to the file descriptor directly
14646            pw.flush();
14647            try {
14648                TransferPipe tp = new TransferPipe();
14649                try {
14650                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14651                            r.appToken, innerPrefix, args);
14652                    tp.go(fd);
14653                } finally {
14654                    tp.kill();
14655                }
14656            } catch (IOException e) {
14657                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14658            } catch (RemoteException e) {
14659                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14660            }
14661        }
14662    }
14663
14664    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14665            int opti, boolean dumpAll, String dumpPackage) {
14666        boolean needSep = false;
14667        boolean onlyHistory = false;
14668        boolean printedAnything = false;
14669
14670        if ("history".equals(dumpPackage)) {
14671            if (opti < args.length && "-s".equals(args[opti])) {
14672                dumpAll = false;
14673            }
14674            onlyHistory = true;
14675            dumpPackage = null;
14676        }
14677
14678        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14679        if (!onlyHistory && dumpAll) {
14680            if (mRegisteredReceivers.size() > 0) {
14681                boolean printed = false;
14682                Iterator it = mRegisteredReceivers.values().iterator();
14683                while (it.hasNext()) {
14684                    ReceiverList r = (ReceiverList)it.next();
14685                    if (dumpPackage != null && (r.app == null ||
14686                            !dumpPackage.equals(r.app.info.packageName))) {
14687                        continue;
14688                    }
14689                    if (!printed) {
14690                        pw.println("  Registered Receivers:");
14691                        needSep = true;
14692                        printed = true;
14693                        printedAnything = true;
14694                    }
14695                    pw.print("  * "); pw.println(r);
14696                    r.dump(pw, "    ");
14697                }
14698            }
14699
14700            if (mReceiverResolver.dump(pw, needSep ?
14701                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
14702                    "    ", dumpPackage, false, false)) {
14703                needSep = true;
14704                printedAnything = true;
14705            }
14706        }
14707
14708        for (BroadcastQueue q : mBroadcastQueues) {
14709            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14710            printedAnything |= needSep;
14711        }
14712
14713        needSep = true;
14714
14715        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14716            for (int user=0; user<mStickyBroadcasts.size(); user++) {
14717                if (needSep) {
14718                    pw.println();
14719                }
14720                needSep = true;
14721                printedAnything = true;
14722                pw.print("  Sticky broadcasts for user ");
14723                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14724                StringBuilder sb = new StringBuilder(128);
14725                for (Map.Entry<String, ArrayList<Intent>> ent
14726                        : mStickyBroadcasts.valueAt(user).entrySet()) {
14727                    pw.print("  * Sticky action "); pw.print(ent.getKey());
14728                    if (dumpAll) {
14729                        pw.println(":");
14730                        ArrayList<Intent> intents = ent.getValue();
14731                        final int N = intents.size();
14732                        for (int i=0; i<N; i++) {
14733                            sb.setLength(0);
14734                            sb.append("    Intent: ");
14735                            intents.get(i).toShortString(sb, false, true, false, false);
14736                            pw.println(sb.toString());
14737                            Bundle bundle = intents.get(i).getExtras();
14738                            if (bundle != null) {
14739                                pw.print("      ");
14740                                pw.println(bundle.toString());
14741                            }
14742                        }
14743                    } else {
14744                        pw.println("");
14745                    }
14746                }
14747            }
14748        }
14749
14750        if (!onlyHistory && dumpAll) {
14751            pw.println();
14752            for (BroadcastQueue queue : mBroadcastQueues) {
14753                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
14754                        + queue.mBroadcastsScheduled);
14755            }
14756            pw.println("  mHandler:");
14757            mHandler.dump(new PrintWriterPrinter(pw), "    ");
14758            needSep = true;
14759            printedAnything = true;
14760        }
14761
14762        if (!printedAnything) {
14763            pw.println("  (nothing)");
14764        }
14765    }
14766
14767    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14768            int opti, boolean dumpAll, String dumpPackage) {
14769        boolean needSep;
14770        boolean printedAnything = false;
14771
14772        ItemMatcher matcher = new ItemMatcher();
14773        matcher.build(args, opti);
14774
14775        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14776
14777        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14778        printedAnything |= needSep;
14779
14780        if (mLaunchingProviders.size() > 0) {
14781            boolean printed = false;
14782            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14783                ContentProviderRecord r = mLaunchingProviders.get(i);
14784                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14785                    continue;
14786                }
14787                if (!printed) {
14788                    if (needSep) pw.println();
14789                    needSep = true;
14790                    pw.println("  Launching content providers:");
14791                    printed = true;
14792                    printedAnything = true;
14793                }
14794                pw.print("  Launching #"); pw.print(i); pw.print(": ");
14795                        pw.println(r);
14796            }
14797        }
14798
14799        if (!printedAnything) {
14800            pw.println("  (nothing)");
14801        }
14802    }
14803
14804    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14805            int opti, boolean dumpAll, String dumpPackage) {
14806        boolean needSep = false;
14807        boolean printedAnything = false;
14808
14809        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14810
14811        if (mGrantedUriPermissions.size() > 0) {
14812            boolean printed = false;
14813            int dumpUid = -2;
14814            if (dumpPackage != null) {
14815                try {
14816                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14817                            MATCH_UNINSTALLED_PACKAGES, 0);
14818                } catch (NameNotFoundException e) {
14819                    dumpUid = -1;
14820                }
14821            }
14822            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14823                int uid = mGrantedUriPermissions.keyAt(i);
14824                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14825                    continue;
14826                }
14827                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14828                if (!printed) {
14829                    if (needSep) pw.println();
14830                    needSep = true;
14831                    pw.println("  Granted Uri Permissions:");
14832                    printed = true;
14833                    printedAnything = true;
14834                }
14835                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
14836                for (UriPermission perm : perms.values()) {
14837                    pw.print("    "); pw.println(perm);
14838                    if (dumpAll) {
14839                        perm.dump(pw, "      ");
14840                    }
14841                }
14842            }
14843        }
14844
14845        if (!printedAnything) {
14846            pw.println("  (nothing)");
14847        }
14848    }
14849
14850    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14851            int opti, boolean dumpAll, String dumpPackage) {
14852        boolean printed = false;
14853
14854        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14855
14856        if (mIntentSenderRecords.size() > 0) {
14857            Iterator<WeakReference<PendingIntentRecord>> it
14858                    = mIntentSenderRecords.values().iterator();
14859            while (it.hasNext()) {
14860                WeakReference<PendingIntentRecord> ref = it.next();
14861                PendingIntentRecord rec = ref != null ? ref.get(): null;
14862                if (dumpPackage != null && (rec == null
14863                        || !dumpPackage.equals(rec.key.packageName))) {
14864                    continue;
14865                }
14866                printed = true;
14867                if (rec != null) {
14868                    pw.print("  * "); pw.println(rec);
14869                    if (dumpAll) {
14870                        rec.dump(pw, "    ");
14871                    }
14872                } else {
14873                    pw.print("  * "); pw.println(ref);
14874                }
14875            }
14876        }
14877
14878        if (!printed) {
14879            pw.println("  (nothing)");
14880        }
14881    }
14882
14883    private static final int dumpProcessList(PrintWriter pw,
14884            ActivityManagerService service, List list,
14885            String prefix, String normalLabel, String persistentLabel,
14886            String dumpPackage) {
14887        int numPers = 0;
14888        final int N = list.size()-1;
14889        for (int i=N; i>=0; i--) {
14890            ProcessRecord r = (ProcessRecord)list.get(i);
14891            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14892                continue;
14893            }
14894            pw.println(String.format("%s%s #%2d: %s",
14895                    prefix, (r.persistent ? persistentLabel : normalLabel),
14896                    i, r.toString()));
14897            if (r.persistent) {
14898                numPers++;
14899            }
14900        }
14901        return numPers;
14902    }
14903
14904    private static final boolean dumpProcessOomList(PrintWriter pw,
14905            ActivityManagerService service, List<ProcessRecord> origList,
14906            String prefix, String normalLabel, String persistentLabel,
14907            boolean inclDetails, String dumpPackage) {
14908
14909        ArrayList<Pair<ProcessRecord, Integer>> list
14910                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14911        for (int i=0; i<origList.size(); i++) {
14912            ProcessRecord r = origList.get(i);
14913            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14914                continue;
14915            }
14916            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14917        }
14918
14919        if (list.size() <= 0) {
14920            return false;
14921        }
14922
14923        Comparator<Pair<ProcessRecord, Integer>> comparator
14924                = new Comparator<Pair<ProcessRecord, Integer>>() {
14925            @Override
14926            public int compare(Pair<ProcessRecord, Integer> object1,
14927                    Pair<ProcessRecord, Integer> object2) {
14928                if (object1.first.setAdj != object2.first.setAdj) {
14929                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14930                }
14931                if (object1.first.setProcState != object2.first.setProcState) {
14932                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14933                }
14934                if (object1.second.intValue() != object2.second.intValue()) {
14935                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14936                }
14937                return 0;
14938            }
14939        };
14940
14941        Collections.sort(list, comparator);
14942
14943        final long curRealtime = SystemClock.elapsedRealtime();
14944        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14945        final long curUptime = SystemClock.uptimeMillis();
14946        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14947
14948        for (int i=list.size()-1; i>=0; i--) {
14949            ProcessRecord r = list.get(i).first;
14950            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14951            char schedGroup;
14952            switch (r.setSchedGroup) {
14953                case ProcessList.SCHED_GROUP_BACKGROUND:
14954                    schedGroup = 'B';
14955                    break;
14956                case ProcessList.SCHED_GROUP_DEFAULT:
14957                    schedGroup = 'F';
14958                    break;
14959                case ProcessList.SCHED_GROUP_TOP_APP:
14960                    schedGroup = 'T';
14961                    break;
14962                default:
14963                    schedGroup = '?';
14964                    break;
14965            }
14966            char foreground;
14967            if (r.foregroundActivities) {
14968                foreground = 'A';
14969            } else if (r.foregroundServices) {
14970                foreground = 'S';
14971            } else {
14972                foreground = ' ';
14973            }
14974            String procState = ProcessList.makeProcStateString(r.curProcState);
14975            pw.print(prefix);
14976            pw.print(r.persistent ? persistentLabel : normalLabel);
14977            pw.print(" #");
14978            int num = (origList.size()-1)-list.get(i).second;
14979            if (num < 10) pw.print(' ');
14980            pw.print(num);
14981            pw.print(": ");
14982            pw.print(oomAdj);
14983            pw.print(' ');
14984            pw.print(schedGroup);
14985            pw.print('/');
14986            pw.print(foreground);
14987            pw.print('/');
14988            pw.print(procState);
14989            pw.print(" trm:");
14990            if (r.trimMemoryLevel < 10) pw.print(' ');
14991            pw.print(r.trimMemoryLevel);
14992            pw.print(' ');
14993            pw.print(r.toShortString());
14994            pw.print(" (");
14995            pw.print(r.adjType);
14996            pw.println(')');
14997            if (r.adjSource != null || r.adjTarget != null) {
14998                pw.print(prefix);
14999                pw.print("    ");
15000                if (r.adjTarget instanceof ComponentName) {
15001                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15002                } else if (r.adjTarget != null) {
15003                    pw.print(r.adjTarget.toString());
15004                } else {
15005                    pw.print("{null}");
15006                }
15007                pw.print("<=");
15008                if (r.adjSource instanceof ProcessRecord) {
15009                    pw.print("Proc{");
15010                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15011                    pw.println("}");
15012                } else if (r.adjSource != null) {
15013                    pw.println(r.adjSource.toString());
15014                } else {
15015                    pw.println("{null}");
15016                }
15017            }
15018            if (inclDetails) {
15019                pw.print(prefix);
15020                pw.print("    ");
15021                pw.print("oom: max="); pw.print(r.maxAdj);
15022                pw.print(" curRaw="); pw.print(r.curRawAdj);
15023                pw.print(" setRaw="); pw.print(r.setRawAdj);
15024                pw.print(" cur="); pw.print(r.curAdj);
15025                pw.print(" set="); pw.println(r.setAdj);
15026                pw.print(prefix);
15027                pw.print("    ");
15028                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15029                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15030                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15031                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15032                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15033                pw.println();
15034                pw.print(prefix);
15035                pw.print("    ");
15036                pw.print("cached="); pw.print(r.cached);
15037                pw.print(" empty="); pw.print(r.empty);
15038                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15039
15040                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15041                    if (r.lastWakeTime != 0) {
15042                        long wtime;
15043                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15044                        synchronized (stats) {
15045                            wtime = stats.getProcessWakeTime(r.info.uid,
15046                                    r.pid, curRealtime);
15047                        }
15048                        long timeUsed = wtime - r.lastWakeTime;
15049                        pw.print(prefix);
15050                        pw.print("    ");
15051                        pw.print("keep awake over ");
15052                        TimeUtils.formatDuration(realtimeSince, pw);
15053                        pw.print(" used ");
15054                        TimeUtils.formatDuration(timeUsed, pw);
15055                        pw.print(" (");
15056                        pw.print((timeUsed*100)/realtimeSince);
15057                        pw.println("%)");
15058                    }
15059                    if (r.lastCpuTime != 0) {
15060                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15061                        pw.print(prefix);
15062                        pw.print("    ");
15063                        pw.print("run cpu over ");
15064                        TimeUtils.formatDuration(uptimeSince, pw);
15065                        pw.print(" used ");
15066                        TimeUtils.formatDuration(timeUsed, pw);
15067                        pw.print(" (");
15068                        pw.print((timeUsed*100)/uptimeSince);
15069                        pw.println("%)");
15070                    }
15071                }
15072            }
15073        }
15074        return true;
15075    }
15076
15077    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15078            String[] args) {
15079        ArrayList<ProcessRecord> procs;
15080        synchronized (this) {
15081            if (args != null && args.length > start
15082                    && args[start].charAt(0) != '-') {
15083                procs = new ArrayList<ProcessRecord>();
15084                int pid = -1;
15085                try {
15086                    pid = Integer.parseInt(args[start]);
15087                } catch (NumberFormatException e) {
15088                }
15089                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15090                    ProcessRecord proc = mLruProcesses.get(i);
15091                    if (proc.pid == pid) {
15092                        procs.add(proc);
15093                    } else if (allPkgs && proc.pkgList != null
15094                            && proc.pkgList.containsKey(args[start])) {
15095                        procs.add(proc);
15096                    } else if (proc.processName.equals(args[start])) {
15097                        procs.add(proc);
15098                    }
15099                }
15100                if (procs.size() <= 0) {
15101                    return null;
15102                }
15103            } else {
15104                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15105            }
15106        }
15107        return procs;
15108    }
15109
15110    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15111            PrintWriter pw, String[] args) {
15112        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15113        if (procs == null) {
15114            pw.println("No process found for: " + args[0]);
15115            return;
15116        }
15117
15118        long uptime = SystemClock.uptimeMillis();
15119        long realtime = SystemClock.elapsedRealtime();
15120        pw.println("Applications Graphics Acceleration Info:");
15121        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15122
15123        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15124            ProcessRecord r = procs.get(i);
15125            if (r.thread != null) {
15126                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15127                pw.flush();
15128                try {
15129                    TransferPipe tp = new TransferPipe();
15130                    try {
15131                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15132                        tp.go(fd);
15133                    } finally {
15134                        tp.kill();
15135                    }
15136                } catch (IOException e) {
15137                    pw.println("Failure while dumping the app: " + r);
15138                    pw.flush();
15139                } catch (RemoteException e) {
15140                    pw.println("Got a RemoteException while dumping the app " + r);
15141                    pw.flush();
15142                }
15143            }
15144        }
15145    }
15146
15147    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15148        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15149        if (procs == null) {
15150            pw.println("No process found for: " + args[0]);
15151            return;
15152        }
15153
15154        pw.println("Applications Database Info:");
15155
15156        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15157            ProcessRecord r = procs.get(i);
15158            if (r.thread != null) {
15159                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15160                pw.flush();
15161                try {
15162                    TransferPipe tp = new TransferPipe();
15163                    try {
15164                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15165                        tp.go(fd);
15166                    } finally {
15167                        tp.kill();
15168                    }
15169                } catch (IOException e) {
15170                    pw.println("Failure while dumping the app: " + r);
15171                    pw.flush();
15172                } catch (RemoteException e) {
15173                    pw.println("Got a RemoteException while dumping the app " + r);
15174                    pw.flush();
15175                }
15176            }
15177        }
15178    }
15179
15180    final static class MemItem {
15181        final boolean isProc;
15182        final String label;
15183        final String shortLabel;
15184        final long pss;
15185        final long swapPss;
15186        final int id;
15187        final boolean hasActivities;
15188        ArrayList<MemItem> subitems;
15189
15190        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15191                boolean _hasActivities) {
15192            isProc = true;
15193            label = _label;
15194            shortLabel = _shortLabel;
15195            pss = _pss;
15196            swapPss = _swapPss;
15197            id = _id;
15198            hasActivities = _hasActivities;
15199        }
15200
15201        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15202            isProc = false;
15203            label = _label;
15204            shortLabel = _shortLabel;
15205            pss = _pss;
15206            swapPss = _swapPss;
15207            id = _id;
15208            hasActivities = false;
15209        }
15210    }
15211
15212    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15213            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15214        if (sort && !isCompact) {
15215            Collections.sort(items, new Comparator<MemItem>() {
15216                @Override
15217                public int compare(MemItem lhs, MemItem rhs) {
15218                    if (lhs.pss < rhs.pss) {
15219                        return 1;
15220                    } else if (lhs.pss > rhs.pss) {
15221                        return -1;
15222                    }
15223                    return 0;
15224                }
15225            });
15226        }
15227
15228        for (int i=0; i<items.size(); i++) {
15229            MemItem mi = items.get(i);
15230            if (!isCompact) {
15231                if (dumpSwapPss) {
15232                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15233                            mi.label, stringifyKBSize(mi.swapPss));
15234                } else {
15235                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15236                }
15237            } else if (mi.isProc) {
15238                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15239                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15240                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15241                pw.println(mi.hasActivities ? ",a" : ",e");
15242            } else {
15243                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15244                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15245            }
15246            if (mi.subitems != null) {
15247                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15248                        true, isCompact, dumpSwapPss);
15249            }
15250        }
15251    }
15252
15253    // These are in KB.
15254    static final long[] DUMP_MEM_BUCKETS = new long[] {
15255        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15256        120*1024, 160*1024, 200*1024,
15257        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15258        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15259    };
15260
15261    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15262            boolean stackLike) {
15263        int start = label.lastIndexOf('.');
15264        if (start >= 0) start++;
15265        else start = 0;
15266        int end = label.length();
15267        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15268            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15269                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15270                out.append(bucket);
15271                out.append(stackLike ? "MB." : "MB ");
15272                out.append(label, start, end);
15273                return;
15274            }
15275        }
15276        out.append(memKB/1024);
15277        out.append(stackLike ? "MB." : "MB ");
15278        out.append(label, start, end);
15279    }
15280
15281    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15282            ProcessList.NATIVE_ADJ,
15283            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15284            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15285            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15286            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15287            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15288            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15289    };
15290    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15291            "Native",
15292            "System", "Persistent", "Persistent Service", "Foreground",
15293            "Visible", "Perceptible",
15294            "Heavy Weight", "Backup",
15295            "A Services", "Home",
15296            "Previous", "B Services", "Cached"
15297    };
15298    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15299            "native",
15300            "sys", "pers", "persvc", "fore",
15301            "vis", "percept",
15302            "heavy", "backup",
15303            "servicea", "home",
15304            "prev", "serviceb", "cached"
15305    };
15306
15307    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15308            long realtime, boolean isCheckinRequest, boolean isCompact) {
15309        if (isCompact) {
15310            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15311        }
15312        if (isCheckinRequest || isCompact) {
15313            // short checkin version
15314            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15315        } else {
15316            pw.println("Applications Memory Usage (in Kilobytes):");
15317            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15318        }
15319    }
15320
15321    private static final int KSM_SHARED = 0;
15322    private static final int KSM_SHARING = 1;
15323    private static final int KSM_UNSHARED = 2;
15324    private static final int KSM_VOLATILE = 3;
15325
15326    private final long[] getKsmInfo() {
15327        long[] longOut = new long[4];
15328        final int[] SINGLE_LONG_FORMAT = new int[] {
15329            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15330        };
15331        long[] longTmp = new long[1];
15332        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15333                SINGLE_LONG_FORMAT, null, longTmp, null);
15334        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15335        longTmp[0] = 0;
15336        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15337                SINGLE_LONG_FORMAT, null, longTmp, null);
15338        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15339        longTmp[0] = 0;
15340        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15341                SINGLE_LONG_FORMAT, null, longTmp, null);
15342        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15343        longTmp[0] = 0;
15344        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15345                SINGLE_LONG_FORMAT, null, longTmp, null);
15346        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15347        return longOut;
15348    }
15349
15350    private static String stringifySize(long size, int order) {
15351        Locale locale = Locale.US;
15352        switch (order) {
15353            case 1:
15354                return String.format(locale, "%,13d", size);
15355            case 1024:
15356                return String.format(locale, "%,9dK", size / 1024);
15357            case 1024 * 1024:
15358                return String.format(locale, "%,5dM", size / 1024 / 1024);
15359            case 1024 * 1024 * 1024:
15360                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15361            default:
15362                throw new IllegalArgumentException("Invalid size order");
15363        }
15364    }
15365
15366    private static String stringifyKBSize(long size) {
15367        return stringifySize(size * 1024, 1024);
15368    }
15369
15370    // Update this version number in case you change the 'compact' format
15371    private static final int MEMINFO_COMPACT_VERSION = 1;
15372
15373    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15374            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15375        boolean dumpDetails = false;
15376        boolean dumpFullDetails = false;
15377        boolean dumpDalvik = false;
15378        boolean dumpSummaryOnly = false;
15379        boolean dumpUnreachable = false;
15380        boolean oomOnly = false;
15381        boolean isCompact = false;
15382        boolean localOnly = false;
15383        boolean packages = false;
15384        boolean isCheckinRequest = false;
15385        boolean dumpSwapPss = false;
15386
15387        int opti = 0;
15388        while (opti < args.length) {
15389            String opt = args[opti];
15390            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15391                break;
15392            }
15393            opti++;
15394            if ("-a".equals(opt)) {
15395                dumpDetails = true;
15396                dumpFullDetails = true;
15397                dumpDalvik = true;
15398                dumpSwapPss = true;
15399            } else if ("-d".equals(opt)) {
15400                dumpDalvik = true;
15401            } else if ("-c".equals(opt)) {
15402                isCompact = true;
15403            } else if ("-s".equals(opt)) {
15404                dumpDetails = true;
15405                dumpSummaryOnly = true;
15406            } else if ("-S".equals(opt)) {
15407                dumpSwapPss = true;
15408            } else if ("--unreachable".equals(opt)) {
15409                dumpUnreachable = true;
15410            } else if ("--oom".equals(opt)) {
15411                oomOnly = true;
15412            } else if ("--local".equals(opt)) {
15413                localOnly = true;
15414            } else if ("--package".equals(opt)) {
15415                packages = true;
15416            } else if ("--checkin".equals(opt)) {
15417                isCheckinRequest = true;
15418
15419            } else if ("-h".equals(opt)) {
15420                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15421                pw.println("  -a: include all available information for each process.");
15422                pw.println("  -d: include dalvik details.");
15423                pw.println("  -c: dump in a compact machine-parseable representation.");
15424                pw.println("  -s: dump only summary of application memory usage.");
15425                pw.println("  -S: dump also SwapPss.");
15426                pw.println("  --oom: only show processes organized by oom adj.");
15427                pw.println("  --local: only collect details locally, don't call process.");
15428                pw.println("  --package: interpret process arg as package, dumping all");
15429                pw.println("             processes that have loaded that package.");
15430                pw.println("  --checkin: dump data for a checkin");
15431                pw.println("If [process] is specified it can be the name or ");
15432                pw.println("pid of a specific process to dump.");
15433                return;
15434            } else {
15435                pw.println("Unknown argument: " + opt + "; use -h for help");
15436            }
15437        }
15438
15439        long uptime = SystemClock.uptimeMillis();
15440        long realtime = SystemClock.elapsedRealtime();
15441        final long[] tmpLong = new long[1];
15442
15443        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15444        if (procs == null) {
15445            // No Java processes.  Maybe they want to print a native process.
15446            if (args != null && args.length > opti
15447                    && args[opti].charAt(0) != '-') {
15448                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15449                        = new ArrayList<ProcessCpuTracker.Stats>();
15450                updateCpuStatsNow();
15451                int findPid = -1;
15452                try {
15453                    findPid = Integer.parseInt(args[opti]);
15454                } catch (NumberFormatException e) {
15455                }
15456                synchronized (mProcessCpuTracker) {
15457                    final int N = mProcessCpuTracker.countStats();
15458                    for (int i=0; i<N; i++) {
15459                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15460                        if (st.pid == findPid || (st.baseName != null
15461                                && st.baseName.equals(args[opti]))) {
15462                            nativeProcs.add(st);
15463                        }
15464                    }
15465                }
15466                if (nativeProcs.size() > 0) {
15467                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15468                            isCompact);
15469                    Debug.MemoryInfo mi = null;
15470                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15471                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15472                        final int pid = r.pid;
15473                        if (!isCheckinRequest && dumpDetails) {
15474                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15475                        }
15476                        if (mi == null) {
15477                            mi = new Debug.MemoryInfo();
15478                        }
15479                        if (dumpDetails || (!brief && !oomOnly)) {
15480                            Debug.getMemoryInfo(pid, mi);
15481                        } else {
15482                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15483                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15484                        }
15485                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15486                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15487                        if (isCheckinRequest) {
15488                            pw.println();
15489                        }
15490                    }
15491                    return;
15492                }
15493            }
15494            pw.println("No process found for: " + args[opti]);
15495            return;
15496        }
15497
15498        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15499            dumpDetails = true;
15500        }
15501
15502        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15503
15504        String[] innerArgs = new String[args.length-opti];
15505        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15506
15507        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15508        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15509        long nativePss = 0;
15510        long nativeSwapPss = 0;
15511        long dalvikPss = 0;
15512        long dalvikSwapPss = 0;
15513        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15514                EmptyArray.LONG;
15515        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15516                EmptyArray.LONG;
15517        long otherPss = 0;
15518        long otherSwapPss = 0;
15519        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15520        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15521
15522        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15523        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15524        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15525                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15526
15527        long totalPss = 0;
15528        long totalSwapPss = 0;
15529        long cachedPss = 0;
15530        long cachedSwapPss = 0;
15531        boolean hasSwapPss = false;
15532
15533        Debug.MemoryInfo mi = null;
15534        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15535            final ProcessRecord r = procs.get(i);
15536            final IApplicationThread thread;
15537            final int pid;
15538            final int oomAdj;
15539            final boolean hasActivities;
15540            synchronized (this) {
15541                thread = r.thread;
15542                pid = r.pid;
15543                oomAdj = r.getSetAdjWithServices();
15544                hasActivities = r.activities.size() > 0;
15545            }
15546            if (thread != null) {
15547                if (!isCheckinRequest && dumpDetails) {
15548                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15549                }
15550                if (mi == null) {
15551                    mi = new Debug.MemoryInfo();
15552                }
15553                if (dumpDetails || (!brief && !oomOnly)) {
15554                    Debug.getMemoryInfo(pid, mi);
15555                    hasSwapPss = mi.hasSwappedOutPss;
15556                } else {
15557                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15558                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15559                }
15560                if (dumpDetails) {
15561                    if (localOnly) {
15562                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15563                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15564                        if (isCheckinRequest) {
15565                            pw.println();
15566                        }
15567                    } else {
15568                        try {
15569                            pw.flush();
15570                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15571                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15572                        } catch (RemoteException e) {
15573                            if (!isCheckinRequest) {
15574                                pw.println("Got RemoteException!");
15575                                pw.flush();
15576                            }
15577                        }
15578                    }
15579                }
15580
15581                final long myTotalPss = mi.getTotalPss();
15582                final long myTotalUss = mi.getTotalUss();
15583                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15584
15585                synchronized (this) {
15586                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15587                        // Record this for posterity if the process has been stable.
15588                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15589                    }
15590                }
15591
15592                if (!isCheckinRequest && mi != null) {
15593                    totalPss += myTotalPss;
15594                    totalSwapPss += myTotalSwapPss;
15595                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15596                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15597                            myTotalSwapPss, pid, hasActivities);
15598                    procMems.add(pssItem);
15599                    procMemsMap.put(pid, pssItem);
15600
15601                    nativePss += mi.nativePss;
15602                    nativeSwapPss += mi.nativeSwappedOutPss;
15603                    dalvikPss += mi.dalvikPss;
15604                    dalvikSwapPss += mi.dalvikSwappedOutPss;
15605                    for (int j=0; j<dalvikSubitemPss.length; j++) {
15606                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15607                        dalvikSubitemSwapPss[j] +=
15608                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15609                    }
15610                    otherPss += mi.otherPss;
15611                    otherSwapPss += mi.otherSwappedOutPss;
15612                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15613                        long mem = mi.getOtherPss(j);
15614                        miscPss[j] += mem;
15615                        otherPss -= mem;
15616                        mem = mi.getOtherSwappedOutPss(j);
15617                        miscSwapPss[j] += mem;
15618                        otherSwapPss -= mem;
15619                    }
15620
15621                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15622                        cachedPss += myTotalPss;
15623                        cachedSwapPss += myTotalSwapPss;
15624                    }
15625
15626                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15627                        if (oomIndex == (oomPss.length - 1)
15628                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15629                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15630                            oomPss[oomIndex] += myTotalPss;
15631                            oomSwapPss[oomIndex] += myTotalSwapPss;
15632                            if (oomProcs[oomIndex] == null) {
15633                                oomProcs[oomIndex] = new ArrayList<MemItem>();
15634                            }
15635                            oomProcs[oomIndex].add(pssItem);
15636                            break;
15637                        }
15638                    }
15639                }
15640            }
15641        }
15642
15643        long nativeProcTotalPss = 0;
15644
15645        if (!isCheckinRequest && procs.size() > 1 && !packages) {
15646            // If we are showing aggregations, also look for native processes to
15647            // include so that our aggregations are more accurate.
15648            updateCpuStatsNow();
15649            mi = null;
15650            synchronized (mProcessCpuTracker) {
15651                final int N = mProcessCpuTracker.countStats();
15652                for (int i=0; i<N; i++) {
15653                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15654                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15655                        if (mi == null) {
15656                            mi = new Debug.MemoryInfo();
15657                        }
15658                        if (!brief && !oomOnly) {
15659                            Debug.getMemoryInfo(st.pid, mi);
15660                        } else {
15661                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15662                            mi.nativePrivateDirty = (int)tmpLong[0];
15663                        }
15664
15665                        final long myTotalPss = mi.getTotalPss();
15666                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15667                        totalPss += myTotalPss;
15668                        nativeProcTotalPss += myTotalPss;
15669
15670                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15671                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15672                        procMems.add(pssItem);
15673
15674                        nativePss += mi.nativePss;
15675                        nativeSwapPss += mi.nativeSwappedOutPss;
15676                        dalvikPss += mi.dalvikPss;
15677                        dalvikSwapPss += mi.dalvikSwappedOutPss;
15678                        for (int j=0; j<dalvikSubitemPss.length; j++) {
15679                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15680                            dalvikSubitemSwapPss[j] +=
15681                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15682                        }
15683                        otherPss += mi.otherPss;
15684                        otherSwapPss += mi.otherSwappedOutPss;
15685                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15686                            long mem = mi.getOtherPss(j);
15687                            miscPss[j] += mem;
15688                            otherPss -= mem;
15689                            mem = mi.getOtherSwappedOutPss(j);
15690                            miscSwapPss[j] += mem;
15691                            otherSwapPss -= mem;
15692                        }
15693                        oomPss[0] += myTotalPss;
15694                        oomSwapPss[0] += myTotalSwapPss;
15695                        if (oomProcs[0] == null) {
15696                            oomProcs[0] = new ArrayList<MemItem>();
15697                        }
15698                        oomProcs[0].add(pssItem);
15699                    }
15700                }
15701            }
15702
15703            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15704
15705            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15706            final MemItem dalvikItem =
15707                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15708            if (dalvikSubitemPss.length > 0) {
15709                dalvikItem.subitems = new ArrayList<MemItem>();
15710                for (int j=0; j<dalvikSubitemPss.length; j++) {
15711                    final String name = Debug.MemoryInfo.getOtherLabel(
15712                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
15713                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15714                                    dalvikSubitemSwapPss[j], j));
15715                }
15716            }
15717            catMems.add(dalvikItem);
15718            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15719            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15720                String label = Debug.MemoryInfo.getOtherLabel(j);
15721                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15722            }
15723
15724            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15725            for (int j=0; j<oomPss.length; j++) {
15726                if (oomPss[j] != 0) {
15727                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15728                            : DUMP_MEM_OOM_LABEL[j];
15729                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15730                            DUMP_MEM_OOM_ADJ[j]);
15731                    item.subitems = oomProcs[j];
15732                    oomMems.add(item);
15733                }
15734            }
15735
15736            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15737            if (!brief && !oomOnly && !isCompact) {
15738                pw.println();
15739                pw.println("Total PSS by process:");
15740                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
15741                pw.println();
15742            }
15743            if (!isCompact) {
15744                pw.println("Total PSS by OOM adjustment:");
15745            }
15746            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
15747            if (!brief && !oomOnly) {
15748                PrintWriter out = categoryPw != null ? categoryPw : pw;
15749                if (!isCompact) {
15750                    out.println();
15751                    out.println("Total PSS by category:");
15752                }
15753                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
15754            }
15755            if (!isCompact) {
15756                pw.println();
15757            }
15758            MemInfoReader memInfo = new MemInfoReader();
15759            memInfo.readMemInfo();
15760            if (nativeProcTotalPss > 0) {
15761                synchronized (this) {
15762                    final long cachedKb = memInfo.getCachedSizeKb();
15763                    final long freeKb = memInfo.getFreeSizeKb();
15764                    final long zramKb = memInfo.getZramTotalSizeKb();
15765                    final long kernelKb = memInfo.getKernelUsedSizeKb();
15766                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15767                            kernelKb*1024, nativeProcTotalPss*1024);
15768                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15769                            nativeProcTotalPss);
15770                }
15771            }
15772            if (!brief) {
15773                if (!isCompact) {
15774                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15775                    pw.print(" (status ");
15776                    switch (mLastMemoryLevel) {
15777                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15778                            pw.println("normal)");
15779                            break;
15780                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15781                            pw.println("moderate)");
15782                            break;
15783                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
15784                            pw.println("low)");
15785                            break;
15786                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15787                            pw.println("critical)");
15788                            break;
15789                        default:
15790                            pw.print(mLastMemoryLevel);
15791                            pw.println(")");
15792                            break;
15793                    }
15794                    pw.print(" Free RAM: ");
15795                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15796                            + memInfo.getFreeSizeKb()));
15797                    pw.print(" (");
15798                    pw.print(stringifyKBSize(cachedPss));
15799                    pw.print(" cached pss + ");
15800                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15801                    pw.print(" cached kernel + ");
15802                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15803                    pw.println(" free)");
15804                } else {
15805                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15806                    pw.print(cachedPss + memInfo.getCachedSizeKb()
15807                            + memInfo.getFreeSizeKb()); pw.print(",");
15808                    pw.println(totalPss - cachedPss);
15809                }
15810            }
15811            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15812                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15813                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15814            if (!isCompact) {
15815                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15816                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15817                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15818                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15819                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15820            } else {
15821                pw.print("lostram,"); pw.println(lostRAM);
15822            }
15823            if (!brief) {
15824                if (memInfo.getZramTotalSizeKb() != 0) {
15825                    if (!isCompact) {
15826                        pw.print("     ZRAM: ");
15827                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15828                                pw.print(" physical used for ");
15829                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15830                                        - memInfo.getSwapFreeSizeKb()));
15831                                pw.print(" in swap (");
15832                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15833                                pw.println(" total swap)");
15834                    } else {
15835                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15836                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15837                                pw.println(memInfo.getSwapFreeSizeKb());
15838                    }
15839                }
15840                final long[] ksm = getKsmInfo();
15841                if (!isCompact) {
15842                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15843                            || ksm[KSM_VOLATILE] != 0) {
15844                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15845                                pw.print(" saved from shared ");
15846                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15847                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15848                                pw.print(" unshared; ");
15849                                pw.print(stringifyKBSize(
15850                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
15851                    }
15852                    pw.print("   Tuning: ");
15853                    pw.print(ActivityManager.staticGetMemoryClass());
15854                    pw.print(" (large ");
15855                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15856                    pw.print("), oom ");
15857                    pw.print(stringifySize(
15858                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15859                    pw.print(", restore limit ");
15860                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15861                    if (ActivityManager.isLowRamDeviceStatic()) {
15862                        pw.print(" (low-ram)");
15863                    }
15864                    if (ActivityManager.isHighEndGfx()) {
15865                        pw.print(" (high-end-gfx)");
15866                    }
15867                    pw.println();
15868                } else {
15869                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15870                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15871                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15872                    pw.print("tuning,");
15873                    pw.print(ActivityManager.staticGetMemoryClass());
15874                    pw.print(',');
15875                    pw.print(ActivityManager.staticGetLargeMemoryClass());
15876                    pw.print(',');
15877                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15878                    if (ActivityManager.isLowRamDeviceStatic()) {
15879                        pw.print(",low-ram");
15880                    }
15881                    if (ActivityManager.isHighEndGfx()) {
15882                        pw.print(",high-end-gfx");
15883                    }
15884                    pw.println();
15885                }
15886            }
15887        }
15888    }
15889
15890    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15891            long memtrack, String name) {
15892        sb.append("  ");
15893        sb.append(ProcessList.makeOomAdjString(oomAdj));
15894        sb.append(' ');
15895        sb.append(ProcessList.makeProcStateString(procState));
15896        sb.append(' ');
15897        ProcessList.appendRamKb(sb, pss);
15898        sb.append(": ");
15899        sb.append(name);
15900        if (memtrack > 0) {
15901            sb.append(" (");
15902            sb.append(stringifyKBSize(memtrack));
15903            sb.append(" memtrack)");
15904        }
15905    }
15906
15907    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15908        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15909        sb.append(" (pid ");
15910        sb.append(mi.pid);
15911        sb.append(") ");
15912        sb.append(mi.adjType);
15913        sb.append('\n');
15914        if (mi.adjReason != null) {
15915            sb.append("                      ");
15916            sb.append(mi.adjReason);
15917            sb.append('\n');
15918        }
15919    }
15920
15921    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15922        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15923        for (int i=0, N=memInfos.size(); i<N; i++) {
15924            ProcessMemInfo mi = memInfos.get(i);
15925            infoMap.put(mi.pid, mi);
15926        }
15927        updateCpuStatsNow();
15928        long[] memtrackTmp = new long[1];
15929        synchronized (mProcessCpuTracker) {
15930            final int N = mProcessCpuTracker.countStats();
15931            for (int i=0; i<N; i++) {
15932                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15933                if (st.vsize > 0) {
15934                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
15935                    if (pss > 0) {
15936                        if (infoMap.indexOfKey(st.pid) < 0) {
15937                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15938                                    ProcessList.NATIVE_ADJ, -1, "native", null);
15939                            mi.pss = pss;
15940                            mi.memtrack = memtrackTmp[0];
15941                            memInfos.add(mi);
15942                        }
15943                    }
15944                }
15945            }
15946        }
15947
15948        long totalPss = 0;
15949        long totalMemtrack = 0;
15950        for (int i=0, N=memInfos.size(); i<N; i++) {
15951            ProcessMemInfo mi = memInfos.get(i);
15952            if (mi.pss == 0) {
15953                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15954                mi.memtrack = memtrackTmp[0];
15955            }
15956            totalPss += mi.pss;
15957            totalMemtrack += mi.memtrack;
15958        }
15959        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15960            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15961                if (lhs.oomAdj != rhs.oomAdj) {
15962                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15963                }
15964                if (lhs.pss != rhs.pss) {
15965                    return lhs.pss < rhs.pss ? 1 : -1;
15966                }
15967                return 0;
15968            }
15969        });
15970
15971        StringBuilder tag = new StringBuilder(128);
15972        StringBuilder stack = new StringBuilder(128);
15973        tag.append("Low on memory -- ");
15974        appendMemBucket(tag, totalPss, "total", false);
15975        appendMemBucket(stack, totalPss, "total", true);
15976
15977        StringBuilder fullNativeBuilder = new StringBuilder(1024);
15978        StringBuilder shortNativeBuilder = new StringBuilder(1024);
15979        StringBuilder fullJavaBuilder = new StringBuilder(1024);
15980
15981        boolean firstLine = true;
15982        int lastOomAdj = Integer.MIN_VALUE;
15983        long extraNativeRam = 0;
15984        long extraNativeMemtrack = 0;
15985        long cachedPss = 0;
15986        for (int i=0, N=memInfos.size(); i<N; i++) {
15987            ProcessMemInfo mi = memInfos.get(i);
15988
15989            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15990                cachedPss += mi.pss;
15991            }
15992
15993            if (mi.oomAdj != ProcessList.NATIVE_ADJ
15994                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
15995                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
15996                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15997                if (lastOomAdj != mi.oomAdj) {
15998                    lastOomAdj = mi.oomAdj;
15999                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16000                        tag.append(" / ");
16001                    }
16002                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16003                        if (firstLine) {
16004                            stack.append(":");
16005                            firstLine = false;
16006                        }
16007                        stack.append("\n\t at ");
16008                    } else {
16009                        stack.append("$");
16010                    }
16011                } else {
16012                    tag.append(" ");
16013                    stack.append("$");
16014                }
16015                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16016                    appendMemBucket(tag, mi.pss, mi.name, false);
16017                }
16018                appendMemBucket(stack, mi.pss, mi.name, true);
16019                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16020                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16021                    stack.append("(");
16022                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16023                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16024                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16025                            stack.append(":");
16026                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16027                        }
16028                    }
16029                    stack.append(")");
16030                }
16031            }
16032
16033            appendMemInfo(fullNativeBuilder, mi);
16034            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16035                // The short form only has native processes that are >= 512K.
16036                if (mi.pss >= 512) {
16037                    appendMemInfo(shortNativeBuilder, mi);
16038                } else {
16039                    extraNativeRam += mi.pss;
16040                    extraNativeMemtrack += mi.memtrack;
16041                }
16042            } else {
16043                // Short form has all other details, but if we have collected RAM
16044                // from smaller native processes let's dump a summary of that.
16045                if (extraNativeRam > 0) {
16046                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16047                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16048                    shortNativeBuilder.append('\n');
16049                    extraNativeRam = 0;
16050                }
16051                appendMemInfo(fullJavaBuilder, mi);
16052            }
16053        }
16054
16055        fullJavaBuilder.append("           ");
16056        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16057        fullJavaBuilder.append(": TOTAL");
16058        if (totalMemtrack > 0) {
16059            fullJavaBuilder.append(" (");
16060            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16061            fullJavaBuilder.append(" memtrack)");
16062        } else {
16063        }
16064        fullJavaBuilder.append("\n");
16065
16066        MemInfoReader memInfo = new MemInfoReader();
16067        memInfo.readMemInfo();
16068        final long[] infos = memInfo.getRawInfo();
16069
16070        StringBuilder memInfoBuilder = new StringBuilder(1024);
16071        Debug.getMemInfo(infos);
16072        memInfoBuilder.append("  MemInfo: ");
16073        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16074        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16075        memInfoBuilder.append(stringifyKBSize(
16076                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16077        memInfoBuilder.append(stringifyKBSize(
16078                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16079        memInfoBuilder.append(stringifyKBSize(
16080                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16081        memInfoBuilder.append("           ");
16082        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16083        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16084        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16085        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16086        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16087            memInfoBuilder.append("  ZRAM: ");
16088            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16089            memInfoBuilder.append(" RAM, ");
16090            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16091            memInfoBuilder.append(" swap total, ");
16092            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16093            memInfoBuilder.append(" swap free\n");
16094        }
16095        final long[] ksm = getKsmInfo();
16096        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16097                || ksm[KSM_VOLATILE] != 0) {
16098            memInfoBuilder.append("  KSM: ");
16099            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16100            memInfoBuilder.append(" saved from shared ");
16101            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16102            memInfoBuilder.append("\n       ");
16103            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16104            memInfoBuilder.append(" unshared; ");
16105            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16106            memInfoBuilder.append(" volatile\n");
16107        }
16108        memInfoBuilder.append("  Free RAM: ");
16109        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16110                + memInfo.getFreeSizeKb()));
16111        memInfoBuilder.append("\n");
16112        memInfoBuilder.append("  Used RAM: ");
16113        memInfoBuilder.append(stringifyKBSize(
16114                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16115        memInfoBuilder.append("\n");
16116        memInfoBuilder.append("  Lost RAM: ");
16117        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16118                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16119                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16120        memInfoBuilder.append("\n");
16121        Slog.i(TAG, "Low on memory:");
16122        Slog.i(TAG, shortNativeBuilder.toString());
16123        Slog.i(TAG, fullJavaBuilder.toString());
16124        Slog.i(TAG, memInfoBuilder.toString());
16125
16126        StringBuilder dropBuilder = new StringBuilder(1024);
16127        /*
16128        StringWriter oomSw = new StringWriter();
16129        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16130        StringWriter catSw = new StringWriter();
16131        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16132        String[] emptyArgs = new String[] { };
16133        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16134        oomPw.flush();
16135        String oomString = oomSw.toString();
16136        */
16137        dropBuilder.append("Low on memory:");
16138        dropBuilder.append(stack);
16139        dropBuilder.append('\n');
16140        dropBuilder.append(fullNativeBuilder);
16141        dropBuilder.append(fullJavaBuilder);
16142        dropBuilder.append('\n');
16143        dropBuilder.append(memInfoBuilder);
16144        dropBuilder.append('\n');
16145        /*
16146        dropBuilder.append(oomString);
16147        dropBuilder.append('\n');
16148        */
16149        StringWriter catSw = new StringWriter();
16150        synchronized (ActivityManagerService.this) {
16151            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16152            String[] emptyArgs = new String[] { };
16153            catPw.println();
16154            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16155            catPw.println();
16156            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16157                    false, false, null);
16158            catPw.println();
16159            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16160            catPw.flush();
16161        }
16162        dropBuilder.append(catSw.toString());
16163        addErrorToDropBox("lowmem", null, "system_server", null,
16164                null, tag.toString(), dropBuilder.toString(), null, null);
16165        //Slog.i(TAG, "Sent to dropbox:");
16166        //Slog.i(TAG, dropBuilder.toString());
16167        synchronized (ActivityManagerService.this) {
16168            long now = SystemClock.uptimeMillis();
16169            if (mLastMemUsageReportTime < now) {
16170                mLastMemUsageReportTime = now;
16171            }
16172        }
16173    }
16174
16175    /**
16176     * Searches array of arguments for the specified string
16177     * @param args array of argument strings
16178     * @param value value to search for
16179     * @return true if the value is contained in the array
16180     */
16181    private static boolean scanArgs(String[] args, String value) {
16182        if (args != null) {
16183            for (String arg : args) {
16184                if (value.equals(arg)) {
16185                    return true;
16186                }
16187            }
16188        }
16189        return false;
16190    }
16191
16192    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16193            ContentProviderRecord cpr, boolean always) {
16194        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16195
16196        if (!inLaunching || always) {
16197            synchronized (cpr) {
16198                cpr.launchingApp = null;
16199                cpr.notifyAll();
16200            }
16201            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16202            String names[] = cpr.info.authority.split(";");
16203            for (int j = 0; j < names.length; j++) {
16204                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16205            }
16206        }
16207
16208        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16209            ContentProviderConnection conn = cpr.connections.get(i);
16210            if (conn.waiting) {
16211                // If this connection is waiting for the provider, then we don't
16212                // need to mess with its process unless we are always removing
16213                // or for some reason the provider is not currently launching.
16214                if (inLaunching && !always) {
16215                    continue;
16216                }
16217            }
16218            ProcessRecord capp = conn.client;
16219            conn.dead = true;
16220            if (conn.stableCount > 0) {
16221                if (!capp.persistent && capp.thread != null
16222                        && capp.pid != 0
16223                        && capp.pid != MY_PID) {
16224                    capp.kill("depends on provider "
16225                            + cpr.name.flattenToShortString()
16226                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16227                }
16228            } else if (capp.thread != null && conn.provider.provider != null) {
16229                try {
16230                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16231                } catch (RemoteException e) {
16232                }
16233                // In the protocol here, we don't expect the client to correctly
16234                // clean up this connection, we'll just remove it.
16235                cpr.connections.remove(i);
16236                if (conn.client.conProviders.remove(conn)) {
16237                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16238                }
16239            }
16240        }
16241
16242        if (inLaunching && always) {
16243            mLaunchingProviders.remove(cpr);
16244        }
16245        return inLaunching;
16246    }
16247
16248    /**
16249     * Main code for cleaning up a process when it has gone away.  This is
16250     * called both as a result of the process dying, or directly when stopping
16251     * a process when running in single process mode.
16252     *
16253     * @return Returns true if the given process has been restarted, so the
16254     * app that was passed in must remain on the process lists.
16255     */
16256    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16257            boolean restarting, boolean allowRestart, int index) {
16258        if (index >= 0) {
16259            removeLruProcessLocked(app);
16260            ProcessList.remove(app.pid);
16261        }
16262
16263        mProcessesToGc.remove(app);
16264        mPendingPssProcesses.remove(app);
16265
16266        // Dismiss any open dialogs.
16267        if (app.crashDialog != null && !app.forceCrashReport) {
16268            app.crashDialog.dismiss();
16269            app.crashDialog = null;
16270        }
16271        if (app.anrDialog != null) {
16272            app.anrDialog.dismiss();
16273            app.anrDialog = null;
16274        }
16275        if (app.waitDialog != null) {
16276            app.waitDialog.dismiss();
16277            app.waitDialog = null;
16278        }
16279
16280        app.crashing = false;
16281        app.notResponding = false;
16282
16283        app.resetPackageList(mProcessStats);
16284        app.unlinkDeathRecipient();
16285        app.makeInactive(mProcessStats);
16286        app.waitingToKill = null;
16287        app.forcingToForeground = null;
16288        updateProcessForegroundLocked(app, false, false);
16289        app.foregroundActivities = false;
16290        app.hasShownUi = false;
16291        app.treatLikeActivity = false;
16292        app.hasAboveClient = false;
16293        app.hasClientActivities = false;
16294
16295        mServices.killServicesLocked(app, allowRestart);
16296
16297        boolean restart = false;
16298
16299        // Remove published content providers.
16300        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16301            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16302            final boolean always = app.bad || !allowRestart;
16303            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16304            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16305                // We left the provider in the launching list, need to
16306                // restart it.
16307                restart = true;
16308            }
16309
16310            cpr.provider = null;
16311            cpr.proc = null;
16312        }
16313        app.pubProviders.clear();
16314
16315        // Take care of any launching providers waiting for this process.
16316        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16317            restart = true;
16318        }
16319
16320        // Unregister from connected content providers.
16321        if (!app.conProviders.isEmpty()) {
16322            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16323                ContentProviderConnection conn = app.conProviders.get(i);
16324                conn.provider.connections.remove(conn);
16325                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16326                        conn.provider.name);
16327            }
16328            app.conProviders.clear();
16329        }
16330
16331        // At this point there may be remaining entries in mLaunchingProviders
16332        // where we were the only one waiting, so they are no longer of use.
16333        // Look for these and clean up if found.
16334        // XXX Commented out for now.  Trying to figure out a way to reproduce
16335        // the actual situation to identify what is actually going on.
16336        if (false) {
16337            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16338                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16339                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16340                    synchronized (cpr) {
16341                        cpr.launchingApp = null;
16342                        cpr.notifyAll();
16343                    }
16344                }
16345            }
16346        }
16347
16348        skipCurrentReceiverLocked(app);
16349
16350        // Unregister any receivers.
16351        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16352            removeReceiverLocked(app.receivers.valueAt(i));
16353        }
16354        app.receivers.clear();
16355
16356        // If the app is undergoing backup, tell the backup manager about it
16357        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16358            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16359                    + mBackupTarget.appInfo + " died during backup");
16360            try {
16361                IBackupManager bm = IBackupManager.Stub.asInterface(
16362                        ServiceManager.getService(Context.BACKUP_SERVICE));
16363                bm.agentDisconnected(app.info.packageName);
16364            } catch (RemoteException e) {
16365                // can't happen; backup manager is local
16366            }
16367        }
16368
16369        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16370            ProcessChangeItem item = mPendingProcessChanges.get(i);
16371            if (item.pid == app.pid) {
16372                mPendingProcessChanges.remove(i);
16373                mAvailProcessChanges.add(item);
16374            }
16375        }
16376        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16377                null).sendToTarget();
16378
16379        // If the caller is restarting this app, then leave it in its
16380        // current lists and let the caller take care of it.
16381        if (restarting) {
16382            return false;
16383        }
16384
16385        if (!app.persistent || app.isolated) {
16386            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16387                    "Removing non-persistent process during cleanup: " + app);
16388            removeProcessNameLocked(app.processName, app.uid);
16389            if (mHeavyWeightProcess == app) {
16390                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16391                        mHeavyWeightProcess.userId, 0));
16392                mHeavyWeightProcess = null;
16393            }
16394        } else if (!app.removed) {
16395            // This app is persistent, so we need to keep its record around.
16396            // If it is not already on the pending app list, add it there
16397            // and start a new process for it.
16398            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16399                mPersistentStartingProcesses.add(app);
16400                restart = true;
16401            }
16402        }
16403        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16404                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16405        mProcessesOnHold.remove(app);
16406
16407        if (app == mHomeProcess) {
16408            mHomeProcess = null;
16409        }
16410        if (app == mPreviousProcess) {
16411            mPreviousProcess = null;
16412        }
16413
16414        if (restart && !app.isolated) {
16415            // We have components that still need to be running in the
16416            // process, so re-launch it.
16417            if (index < 0) {
16418                ProcessList.remove(app.pid);
16419            }
16420            addProcessNameLocked(app);
16421            startProcessLocked(app, "restart", app.processName);
16422            return true;
16423        } else if (app.pid > 0 && app.pid != MY_PID) {
16424            // Goodbye!
16425            boolean removed;
16426            synchronized (mPidsSelfLocked) {
16427                mPidsSelfLocked.remove(app.pid);
16428                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16429            }
16430            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16431            if (app.isolated) {
16432                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16433            }
16434            app.setPid(0);
16435        }
16436        return false;
16437    }
16438
16439    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16440        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16441            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16442            if (cpr.launchingApp == app) {
16443                return true;
16444            }
16445        }
16446        return false;
16447    }
16448
16449    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16450        // Look through the content providers we are waiting to have launched,
16451        // and if any run in this process then either schedule a restart of
16452        // the process or kill the client waiting for it if this process has
16453        // gone bad.
16454        boolean restart = false;
16455        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16456            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16457            if (cpr.launchingApp == app) {
16458                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16459                    restart = true;
16460                } else {
16461                    removeDyingProviderLocked(app, cpr, true);
16462                }
16463            }
16464        }
16465        return restart;
16466    }
16467
16468    // =========================================================
16469    // SERVICES
16470    // =========================================================
16471
16472    @Override
16473    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16474            int flags) {
16475        enforceNotIsolatedCaller("getServices");
16476        synchronized (this) {
16477            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16478        }
16479    }
16480
16481    @Override
16482    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16483        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16484        synchronized (this) {
16485            return mServices.getRunningServiceControlPanelLocked(name);
16486        }
16487    }
16488
16489    @Override
16490    public ComponentName startService(IApplicationThread caller, Intent service,
16491            String resolvedType, String callingPackage, int userId)
16492            throws TransactionTooLargeException {
16493        enforceNotIsolatedCaller("startService");
16494        // Refuse possible leaked file descriptors
16495        if (service != null && service.hasFileDescriptors() == true) {
16496            throw new IllegalArgumentException("File descriptors passed in Intent");
16497        }
16498
16499        if (callingPackage == null) {
16500            throw new IllegalArgumentException("callingPackage cannot be null");
16501        }
16502
16503        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16504                "startService: " + service + " type=" + resolvedType);
16505        synchronized(this) {
16506            final int callingPid = Binder.getCallingPid();
16507            final int callingUid = Binder.getCallingUid();
16508            final long origId = Binder.clearCallingIdentity();
16509            ComponentName res = mServices.startServiceLocked(caller, service,
16510                    resolvedType, callingPid, callingUid, callingPackage, userId);
16511            Binder.restoreCallingIdentity(origId);
16512            return res;
16513        }
16514    }
16515
16516    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16517            String callingPackage, int userId)
16518            throws TransactionTooLargeException {
16519        synchronized(this) {
16520            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16521                    "startServiceInPackage: " + service + " type=" + resolvedType);
16522            final long origId = Binder.clearCallingIdentity();
16523            ComponentName res = mServices.startServiceLocked(null, service,
16524                    resolvedType, -1, uid, callingPackage, userId);
16525            Binder.restoreCallingIdentity(origId);
16526            return res;
16527        }
16528    }
16529
16530    @Override
16531    public int stopService(IApplicationThread caller, Intent service,
16532            String resolvedType, int userId) {
16533        enforceNotIsolatedCaller("stopService");
16534        // Refuse possible leaked file descriptors
16535        if (service != null && service.hasFileDescriptors() == true) {
16536            throw new IllegalArgumentException("File descriptors passed in Intent");
16537        }
16538
16539        synchronized(this) {
16540            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16541        }
16542    }
16543
16544    @Override
16545    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16546        enforceNotIsolatedCaller("peekService");
16547        // Refuse possible leaked file descriptors
16548        if (service != null && service.hasFileDescriptors() == true) {
16549            throw new IllegalArgumentException("File descriptors passed in Intent");
16550        }
16551
16552        if (callingPackage == null) {
16553            throw new IllegalArgumentException("callingPackage cannot be null");
16554        }
16555
16556        synchronized(this) {
16557            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16558        }
16559    }
16560
16561    @Override
16562    public boolean stopServiceToken(ComponentName className, IBinder token,
16563            int startId) {
16564        synchronized(this) {
16565            return mServices.stopServiceTokenLocked(className, token, startId);
16566        }
16567    }
16568
16569    @Override
16570    public void setServiceForeground(ComponentName className, IBinder token,
16571            int id, Notification notification, int flags) {
16572        synchronized(this) {
16573            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16574        }
16575    }
16576
16577    @Override
16578    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16579            boolean requireFull, String name, String callerPackage) {
16580        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16581                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16582    }
16583
16584    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16585            String className, int flags) {
16586        boolean result = false;
16587        // For apps that don't have pre-defined UIDs, check for permission
16588        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16589            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16590                if (ActivityManager.checkUidPermission(
16591                        INTERACT_ACROSS_USERS,
16592                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16593                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16594                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16595                            + " requests FLAG_SINGLE_USER, but app does not hold "
16596                            + INTERACT_ACROSS_USERS;
16597                    Slog.w(TAG, msg);
16598                    throw new SecurityException(msg);
16599                }
16600                // Permission passed
16601                result = true;
16602            }
16603        } else if ("system".equals(componentProcessName)) {
16604            result = true;
16605        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16606            // Phone app and persistent apps are allowed to export singleuser providers.
16607            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16608                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16609        }
16610        if (DEBUG_MU) Slog.v(TAG_MU,
16611                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16612                + Integer.toHexString(flags) + ") = " + result);
16613        return result;
16614    }
16615
16616    /**
16617     * Checks to see if the caller is in the same app as the singleton
16618     * component, or the component is in a special app. It allows special apps
16619     * to export singleton components but prevents exporting singleton
16620     * components for regular apps.
16621     */
16622    boolean isValidSingletonCall(int callingUid, int componentUid) {
16623        int componentAppId = UserHandle.getAppId(componentUid);
16624        return UserHandle.isSameApp(callingUid, componentUid)
16625                || componentAppId == Process.SYSTEM_UID
16626                || componentAppId == Process.PHONE_UID
16627                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16628                        == PackageManager.PERMISSION_GRANTED;
16629    }
16630
16631    public int bindService(IApplicationThread caller, IBinder token, Intent service,
16632            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16633            int userId) throws TransactionTooLargeException {
16634        enforceNotIsolatedCaller("bindService");
16635
16636        // Refuse possible leaked file descriptors
16637        if (service != null && service.hasFileDescriptors() == true) {
16638            throw new IllegalArgumentException("File descriptors passed in Intent");
16639        }
16640
16641        if (callingPackage == null) {
16642            throw new IllegalArgumentException("callingPackage cannot be null");
16643        }
16644
16645        synchronized(this) {
16646            return mServices.bindServiceLocked(caller, token, service,
16647                    resolvedType, connection, flags, callingPackage, userId);
16648        }
16649    }
16650
16651    public boolean unbindService(IServiceConnection connection) {
16652        synchronized (this) {
16653            return mServices.unbindServiceLocked(connection);
16654        }
16655    }
16656
16657    public void publishService(IBinder token, Intent intent, IBinder service) {
16658        // Refuse possible leaked file descriptors
16659        if (intent != null && intent.hasFileDescriptors() == true) {
16660            throw new IllegalArgumentException("File descriptors passed in Intent");
16661        }
16662
16663        synchronized(this) {
16664            if (!(token instanceof ServiceRecord)) {
16665                throw new IllegalArgumentException("Invalid service token");
16666            }
16667            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16668        }
16669    }
16670
16671    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16672        // Refuse possible leaked file descriptors
16673        if (intent != null && intent.hasFileDescriptors() == true) {
16674            throw new IllegalArgumentException("File descriptors passed in Intent");
16675        }
16676
16677        synchronized(this) {
16678            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16679        }
16680    }
16681
16682    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16683        synchronized(this) {
16684            if (!(token instanceof ServiceRecord)) {
16685                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16686                throw new IllegalArgumentException("Invalid service token");
16687            }
16688            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16689        }
16690    }
16691
16692    // =========================================================
16693    // BACKUP AND RESTORE
16694    // =========================================================
16695
16696    // Cause the target app to be launched if necessary and its backup agent
16697    // instantiated.  The backup agent will invoke backupAgentCreated() on the
16698    // activity manager to announce its creation.
16699    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16700        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16701                "bindBackupAgent: app=" + app + " mode=" + backupMode);
16702        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16703
16704        synchronized(this) {
16705            // !!! TODO: currently no check here that we're already bound
16706            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16707            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16708            synchronized (stats) {
16709                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16710            }
16711
16712            // Backup agent is now in use, its package can't be stopped.
16713            try {
16714                AppGlobals.getPackageManager().setPackageStoppedState(
16715                        app.packageName, false, UserHandle.getUserId(app.uid));
16716            } catch (RemoteException e) {
16717            } catch (IllegalArgumentException e) {
16718                Slog.w(TAG, "Failed trying to unstop package "
16719                        + app.packageName + ": " + e);
16720            }
16721
16722            BackupRecord r = new BackupRecord(ss, app, backupMode);
16723            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16724                    ? new ComponentName(app.packageName, app.backupAgentName)
16725                    : new ComponentName("android", "FullBackupAgent");
16726            // startProcessLocked() returns existing proc's record if it's already running
16727            ProcessRecord proc = startProcessLocked(app.processName, app,
16728                    false, 0, "backup", hostingName, false, false, false);
16729            if (proc == null) {
16730                Slog.e(TAG, "Unable to start backup agent process " + r);
16731                return false;
16732            }
16733
16734            r.app = proc;
16735            mBackupTarget = r;
16736            mBackupAppName = app.packageName;
16737
16738            // Try not to kill the process during backup
16739            updateOomAdjLocked(proc);
16740
16741            // If the process is already attached, schedule the creation of the backup agent now.
16742            // If it is not yet live, this will be done when it attaches to the framework.
16743            if (proc.thread != null) {
16744                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16745                try {
16746                    proc.thread.scheduleCreateBackupAgent(app,
16747                            compatibilityInfoForPackageLocked(app), backupMode);
16748                } catch (RemoteException e) {
16749                    // Will time out on the backup manager side
16750                }
16751            } else {
16752                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16753            }
16754            // Invariants: at this point, the target app process exists and the application
16755            // is either already running or in the process of coming up.  mBackupTarget and
16756            // mBackupAppName describe the app, so that when it binds back to the AM we
16757            // know that it's scheduled for a backup-agent operation.
16758        }
16759
16760        return true;
16761    }
16762
16763    @Override
16764    public void clearPendingBackup() {
16765        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16766        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16767
16768        synchronized (this) {
16769            mBackupTarget = null;
16770            mBackupAppName = null;
16771        }
16772    }
16773
16774    // A backup agent has just come up
16775    public void backupAgentCreated(String agentPackageName, IBinder agent) {
16776        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16777                + " = " + agent);
16778
16779        synchronized(this) {
16780            if (!agentPackageName.equals(mBackupAppName)) {
16781                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16782                return;
16783            }
16784        }
16785
16786        long oldIdent = Binder.clearCallingIdentity();
16787        try {
16788            IBackupManager bm = IBackupManager.Stub.asInterface(
16789                    ServiceManager.getService(Context.BACKUP_SERVICE));
16790            bm.agentConnected(agentPackageName, agent);
16791        } catch (RemoteException e) {
16792            // can't happen; the backup manager service is local
16793        } catch (Exception e) {
16794            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16795            e.printStackTrace();
16796        } finally {
16797            Binder.restoreCallingIdentity(oldIdent);
16798        }
16799    }
16800
16801    // done with this agent
16802    public void unbindBackupAgent(ApplicationInfo appInfo) {
16803        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16804        if (appInfo == null) {
16805            Slog.w(TAG, "unbind backup agent for null app");
16806            return;
16807        }
16808
16809        synchronized(this) {
16810            try {
16811                if (mBackupAppName == null) {
16812                    Slog.w(TAG, "Unbinding backup agent with no active backup");
16813                    return;
16814                }
16815
16816                if (!mBackupAppName.equals(appInfo.packageName)) {
16817                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16818                    return;
16819                }
16820
16821                // Not backing this app up any more; reset its OOM adjustment
16822                final ProcessRecord proc = mBackupTarget.app;
16823                updateOomAdjLocked(proc);
16824
16825                // If the app crashed during backup, 'thread' will be null here
16826                if (proc.thread != null) {
16827                    try {
16828                        proc.thread.scheduleDestroyBackupAgent(appInfo,
16829                                compatibilityInfoForPackageLocked(appInfo));
16830                    } catch (Exception e) {
16831                        Slog.e(TAG, "Exception when unbinding backup agent:");
16832                        e.printStackTrace();
16833                    }
16834                }
16835            } finally {
16836                mBackupTarget = null;
16837                mBackupAppName = null;
16838            }
16839        }
16840    }
16841    // =========================================================
16842    // BROADCASTS
16843    // =========================================================
16844
16845    boolean isPendingBroadcastProcessLocked(int pid) {
16846        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16847                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16848    }
16849
16850    void skipPendingBroadcastLocked(int pid) {
16851            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16852            for (BroadcastQueue queue : mBroadcastQueues) {
16853                queue.skipPendingBroadcastLocked(pid);
16854            }
16855    }
16856
16857    // The app just attached; send any pending broadcasts that it should receive
16858    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16859        boolean didSomething = false;
16860        for (BroadcastQueue queue : mBroadcastQueues) {
16861            didSomething |= queue.sendPendingBroadcastsLocked(app);
16862        }
16863        return didSomething;
16864    }
16865
16866    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16867            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16868        enforceNotIsolatedCaller("registerReceiver");
16869        ArrayList<Intent> stickyIntents = null;
16870        ProcessRecord callerApp = null;
16871        int callingUid;
16872        int callingPid;
16873        synchronized(this) {
16874            if (caller != null) {
16875                callerApp = getRecordForAppLocked(caller);
16876                if (callerApp == null) {
16877                    throw new SecurityException(
16878                            "Unable to find app for caller " + caller
16879                            + " (pid=" + Binder.getCallingPid()
16880                            + ") when registering receiver " + receiver);
16881                }
16882                if (callerApp.info.uid != Process.SYSTEM_UID &&
16883                        !callerApp.pkgList.containsKey(callerPackage) &&
16884                        !"android".equals(callerPackage)) {
16885                    throw new SecurityException("Given caller package " + callerPackage
16886                            + " is not running in process " + callerApp);
16887                }
16888                callingUid = callerApp.info.uid;
16889                callingPid = callerApp.pid;
16890            } else {
16891                callerPackage = null;
16892                callingUid = Binder.getCallingUid();
16893                callingPid = Binder.getCallingPid();
16894            }
16895
16896            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16897                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16898
16899            Iterator<String> actions = filter.actionsIterator();
16900            if (actions == null) {
16901                ArrayList<String> noAction = new ArrayList<String>(1);
16902                noAction.add(null);
16903                actions = noAction.iterator();
16904            }
16905
16906            // Collect stickies of users
16907            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16908            while (actions.hasNext()) {
16909                String action = actions.next();
16910                for (int id : userIds) {
16911                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16912                    if (stickies != null) {
16913                        ArrayList<Intent> intents = stickies.get(action);
16914                        if (intents != null) {
16915                            if (stickyIntents == null) {
16916                                stickyIntents = new ArrayList<Intent>();
16917                            }
16918                            stickyIntents.addAll(intents);
16919                        }
16920                    }
16921                }
16922            }
16923        }
16924
16925        ArrayList<Intent> allSticky = null;
16926        if (stickyIntents != null) {
16927            final ContentResolver resolver = mContext.getContentResolver();
16928            // Look for any matching sticky broadcasts...
16929            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16930                Intent intent = stickyIntents.get(i);
16931                // If intent has scheme "content", it will need to acccess
16932                // provider that needs to lock mProviderMap in ActivityThread
16933                // and also it may need to wait application response, so we
16934                // cannot lock ActivityManagerService here.
16935                if (filter.match(resolver, intent, true, TAG) >= 0) {
16936                    if (allSticky == null) {
16937                        allSticky = new ArrayList<Intent>();
16938                    }
16939                    allSticky.add(intent);
16940                }
16941            }
16942        }
16943
16944        // The first sticky in the list is returned directly back to the client.
16945        Intent sticky = allSticky != null ? allSticky.get(0) : null;
16946        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16947        if (receiver == null) {
16948            return sticky;
16949        }
16950
16951        synchronized (this) {
16952            if (callerApp != null && (callerApp.thread == null
16953                    || callerApp.thread.asBinder() != caller.asBinder())) {
16954                // Original caller already died
16955                return null;
16956            }
16957            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16958            if (rl == null) {
16959                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16960                        userId, receiver);
16961                if (rl.app != null) {
16962                    rl.app.receivers.add(rl);
16963                } else {
16964                    try {
16965                        receiver.asBinder().linkToDeath(rl, 0);
16966                    } catch (RemoteException e) {
16967                        return sticky;
16968                    }
16969                    rl.linkedToDeath = true;
16970                }
16971                mRegisteredReceivers.put(receiver.asBinder(), rl);
16972            } else if (rl.uid != callingUid) {
16973                throw new IllegalArgumentException(
16974                        "Receiver requested to register for uid " + callingUid
16975                        + " was previously registered for uid " + rl.uid);
16976            } else if (rl.pid != callingPid) {
16977                throw new IllegalArgumentException(
16978                        "Receiver requested to register for pid " + callingPid
16979                        + " was previously registered for pid " + rl.pid);
16980            } else if (rl.userId != userId) {
16981                throw new IllegalArgumentException(
16982                        "Receiver requested to register for user " + userId
16983                        + " was previously registered for user " + rl.userId);
16984            }
16985            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16986                    permission, callingUid, userId);
16987            rl.add(bf);
16988            if (!bf.debugCheck()) {
16989                Slog.w(TAG, "==> For Dynamic broadcast");
16990            }
16991            mReceiverResolver.addFilter(bf);
16992
16993            // Enqueue broadcasts for all existing stickies that match
16994            // this filter.
16995            if (allSticky != null) {
16996                ArrayList receivers = new ArrayList();
16997                receivers.add(bf);
16998
16999                final int stickyCount = allSticky.size();
17000                for (int i = 0; i < stickyCount; i++) {
17001                    Intent intent = allSticky.get(i);
17002                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17003                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17004                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17005                            null, 0, null, null, false, true, true, -1);
17006                    queue.enqueueParallelBroadcastLocked(r);
17007                    queue.scheduleBroadcastsLocked();
17008                }
17009            }
17010
17011            return sticky;
17012        }
17013    }
17014
17015    public void unregisterReceiver(IIntentReceiver receiver) {
17016        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17017
17018        final long origId = Binder.clearCallingIdentity();
17019        try {
17020            boolean doTrim = false;
17021
17022            synchronized(this) {
17023                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17024                if (rl != null) {
17025                    final BroadcastRecord r = rl.curBroadcast;
17026                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17027                        final boolean doNext = r.queue.finishReceiverLocked(
17028                                r, r.resultCode, r.resultData, r.resultExtras,
17029                                r.resultAbort, false);
17030                        if (doNext) {
17031                            doTrim = true;
17032                            r.queue.processNextBroadcast(false);
17033                        }
17034                    }
17035
17036                    if (rl.app != null) {
17037                        rl.app.receivers.remove(rl);
17038                    }
17039                    removeReceiverLocked(rl);
17040                    if (rl.linkedToDeath) {
17041                        rl.linkedToDeath = false;
17042                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17043                    }
17044                }
17045            }
17046
17047            // If we actually concluded any broadcasts, we might now be able
17048            // to trim the recipients' apps from our working set
17049            if (doTrim) {
17050                trimApplications();
17051                return;
17052            }
17053
17054        } finally {
17055            Binder.restoreCallingIdentity(origId);
17056        }
17057    }
17058
17059    void removeReceiverLocked(ReceiverList rl) {
17060        mRegisteredReceivers.remove(rl.receiver.asBinder());
17061        for (int i = rl.size() - 1; i >= 0; i--) {
17062            mReceiverResolver.removeFilter(rl.get(i));
17063        }
17064    }
17065
17066    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17067        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17068            ProcessRecord r = mLruProcesses.get(i);
17069            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17070                try {
17071                    r.thread.dispatchPackageBroadcast(cmd, packages);
17072                } catch (RemoteException ex) {
17073                }
17074            }
17075        }
17076    }
17077
17078    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17079            int callingUid, int[] users) {
17080        // TODO: come back and remove this assumption to triage all broadcasts
17081        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17082
17083        List<ResolveInfo> receivers = null;
17084        try {
17085            HashSet<ComponentName> singleUserReceivers = null;
17086            boolean scannedFirstReceivers = false;
17087            for (int user : users) {
17088                // Skip users that have Shell restrictions, with exception of always permitted
17089                // Shell broadcasts
17090                if (callingUid == Process.SHELL_UID
17091                        && mUserController.hasUserRestriction(
17092                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17093                        && !isPermittedShellBroadcast(intent)) {
17094                    continue;
17095                }
17096                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17097                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17098                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17099                    // If this is not the system user, we need to check for
17100                    // any receivers that should be filtered out.
17101                    for (int i=0; i<newReceivers.size(); i++) {
17102                        ResolveInfo ri = newReceivers.get(i);
17103                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17104                            newReceivers.remove(i);
17105                            i--;
17106                        }
17107                    }
17108                }
17109                if (newReceivers != null && newReceivers.size() == 0) {
17110                    newReceivers = null;
17111                }
17112                if (receivers == null) {
17113                    receivers = newReceivers;
17114                } else if (newReceivers != null) {
17115                    // We need to concatenate the additional receivers
17116                    // found with what we have do far.  This would be easy,
17117                    // but we also need to de-dup any receivers that are
17118                    // singleUser.
17119                    if (!scannedFirstReceivers) {
17120                        // Collect any single user receivers we had already retrieved.
17121                        scannedFirstReceivers = true;
17122                        for (int i=0; i<receivers.size(); i++) {
17123                            ResolveInfo ri = receivers.get(i);
17124                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17125                                ComponentName cn = new ComponentName(
17126                                        ri.activityInfo.packageName, ri.activityInfo.name);
17127                                if (singleUserReceivers == null) {
17128                                    singleUserReceivers = new HashSet<ComponentName>();
17129                                }
17130                                singleUserReceivers.add(cn);
17131                            }
17132                        }
17133                    }
17134                    // Add the new results to the existing results, tracking
17135                    // and de-dupping single user receivers.
17136                    for (int i=0; i<newReceivers.size(); i++) {
17137                        ResolveInfo ri = newReceivers.get(i);
17138                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17139                            ComponentName cn = new ComponentName(
17140                                    ri.activityInfo.packageName, ri.activityInfo.name);
17141                            if (singleUserReceivers == null) {
17142                                singleUserReceivers = new HashSet<ComponentName>();
17143                            }
17144                            if (!singleUserReceivers.contains(cn)) {
17145                                singleUserReceivers.add(cn);
17146                                receivers.add(ri);
17147                            }
17148                        } else {
17149                            receivers.add(ri);
17150                        }
17151                    }
17152                }
17153            }
17154        } catch (RemoteException ex) {
17155            // pm is in same process, this will never happen.
17156        }
17157        return receivers;
17158    }
17159
17160    private boolean isPermittedShellBroadcast(Intent intent) {
17161        // remote bugreport should always be allowed to be taken
17162        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17163    }
17164
17165    final int broadcastIntentLocked(ProcessRecord callerApp,
17166            String callerPackage, Intent intent, String resolvedType,
17167            IIntentReceiver resultTo, int resultCode, String resultData,
17168            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17169            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17170        intent = new Intent(intent);
17171
17172        // By default broadcasts do not go to stopped apps.
17173        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17174
17175        // If we have not finished booting, don't allow this to launch new processes.
17176        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17177            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17178        }
17179
17180        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17181                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17182                + " ordered=" + ordered + " userid=" + userId);
17183        if ((resultTo != null) && !ordered) {
17184            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17185        }
17186
17187        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17188                ALLOW_NON_FULL, "broadcast", callerPackage);
17189
17190        // Make sure that the user who is receiving this broadcast is running.
17191        // If not, we will just skip it. Make an exception for shutdown broadcasts
17192        // and upgrade steps.
17193
17194        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17195            if ((callingUid != Process.SYSTEM_UID
17196                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17197                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17198                Slog.w(TAG, "Skipping broadcast of " + intent
17199                        + ": user " + userId + " is stopped");
17200                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17201            }
17202        }
17203
17204        BroadcastOptions brOptions = null;
17205        if (bOptions != null) {
17206            brOptions = new BroadcastOptions(bOptions);
17207            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17208                // See if the caller is allowed to do this.  Note we are checking against
17209                // the actual real caller (not whoever provided the operation as say a
17210                // PendingIntent), because that who is actually supplied the arguments.
17211                if (checkComponentPermission(
17212                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17213                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17214                        != PackageManager.PERMISSION_GRANTED) {
17215                    String msg = "Permission Denial: " + intent.getAction()
17216                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17217                            + ", uid=" + callingUid + ")"
17218                            + " requires "
17219                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17220                    Slog.w(TAG, msg);
17221                    throw new SecurityException(msg);
17222                }
17223            }
17224        }
17225
17226        // Verify that protected broadcasts are only being sent by system code,
17227        // and that system code is only sending protected broadcasts.
17228        final String action = intent.getAction();
17229        final boolean isProtectedBroadcast;
17230        try {
17231            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17232        } catch (RemoteException e) {
17233            Slog.w(TAG, "Remote exception", e);
17234            return ActivityManager.BROADCAST_SUCCESS;
17235        }
17236
17237        final boolean isCallerSystem;
17238        switch (UserHandle.getAppId(callingUid)) {
17239            case Process.ROOT_UID:
17240            case Process.SYSTEM_UID:
17241            case Process.PHONE_UID:
17242            case Process.BLUETOOTH_UID:
17243            case Process.NFC_UID:
17244                isCallerSystem = true;
17245                break;
17246            default:
17247                isCallerSystem = (callerApp != null) && callerApp.persistent;
17248                break;
17249        }
17250
17251        if (isCallerSystem) {
17252            if (isProtectedBroadcast
17253                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17254                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17255                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17256                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17257                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17258                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17259                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17260                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17261                // Broadcast is either protected, or it's a public action that
17262                // we've relaxed, so it's fine for system internals to send.
17263            } else {
17264                // The vast majority of broadcasts sent from system internals
17265                // should be protected to avoid security holes, so yell loudly
17266                // to ensure we examine these cases.
17267                Log.wtf(TAG, "Sending non-protected broadcast " + action
17268                        + " from system", new Throwable());
17269            }
17270
17271        } else {
17272            if (isProtectedBroadcast) {
17273                String msg = "Permission Denial: not allowed to send broadcast "
17274                        + action + " from pid="
17275                        + callingPid + ", uid=" + callingUid;
17276                Slog.w(TAG, msg);
17277                throw new SecurityException(msg);
17278
17279            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17280                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17281                // Special case for compatibility: we don't want apps to send this,
17282                // but historically it has not been protected and apps may be using it
17283                // to poke their own app widget.  So, instead of making it protected,
17284                // just limit it to the caller.
17285                if (callerPackage == null) {
17286                    String msg = "Permission Denial: not allowed to send broadcast "
17287                            + action + " from unknown caller.";
17288                    Slog.w(TAG, msg);
17289                    throw new SecurityException(msg);
17290                } else if (intent.getComponent() != null) {
17291                    // They are good enough to send to an explicit component...  verify
17292                    // it is being sent to the calling app.
17293                    if (!intent.getComponent().getPackageName().equals(
17294                            callerPackage)) {
17295                        String msg = "Permission Denial: not allowed to send broadcast "
17296                                + action + " to "
17297                                + intent.getComponent().getPackageName() + " from "
17298                                + callerPackage;
17299                        Slog.w(TAG, msg);
17300                        throw new SecurityException(msg);
17301                    }
17302                } else {
17303                    // Limit broadcast to their own package.
17304                    intent.setPackage(callerPackage);
17305                }
17306            }
17307        }
17308
17309        if (action != null) {
17310            switch (action) {
17311                case Intent.ACTION_UID_REMOVED:
17312                case Intent.ACTION_PACKAGE_REMOVED:
17313                case Intent.ACTION_PACKAGE_CHANGED:
17314                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17315                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17316                case Intent.ACTION_PACKAGES_SUSPENDED:
17317                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17318                    // Handle special intents: if this broadcast is from the package
17319                    // manager about a package being removed, we need to remove all of
17320                    // its activities from the history stack.
17321                    if (checkComponentPermission(
17322                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17323                            callingPid, callingUid, -1, true)
17324                            != PackageManager.PERMISSION_GRANTED) {
17325                        String msg = "Permission Denial: " + intent.getAction()
17326                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17327                                + ", uid=" + callingUid + ")"
17328                                + " requires "
17329                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17330                        Slog.w(TAG, msg);
17331                        throw new SecurityException(msg);
17332                    }
17333                    switch (action) {
17334                        case Intent.ACTION_UID_REMOVED:
17335                            final Bundle intentExtras = intent.getExtras();
17336                            final int uid = intentExtras != null
17337                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17338                            if (uid >= 0) {
17339                                mBatteryStatsService.removeUid(uid);
17340                                mAppOpsService.uidRemoved(uid);
17341                            }
17342                            break;
17343                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17344                            // If resources are unavailable just force stop all those packages
17345                            // and flush the attribute cache as well.
17346                            String list[] =
17347                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17348                            if (list != null && list.length > 0) {
17349                                for (int i = 0; i < list.length; i++) {
17350                                    forceStopPackageLocked(list[i], -1, false, true, true,
17351                                            false, false, userId, "storage unmount");
17352                                }
17353                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17354                                sendPackageBroadcastLocked(
17355                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17356                                        userId);
17357                            }
17358                            break;
17359                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17360                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17361                            break;
17362                        case Intent.ACTION_PACKAGE_REMOVED:
17363                        case Intent.ACTION_PACKAGE_CHANGED:
17364                            Uri data = intent.getData();
17365                            String ssp;
17366                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17367                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17368                                final boolean replacing =
17369                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17370                                final boolean killProcess =
17371                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17372                                final boolean fullUninstall = removed && !replacing;
17373                                if (killProcess) {
17374                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
17375                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
17376                                            false, true, true, false, fullUninstall, userId,
17377                                            removed ? "pkg removed" : "pkg changed");
17378                                }
17379                                if (removed) {
17380                                    final int cmd = killProcess
17381                                            ? IApplicationThread.PACKAGE_REMOVED
17382                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17383                                    sendPackageBroadcastLocked(cmd,
17384                                            new String[] {ssp}, userId);
17385                                    if (fullUninstall) {
17386                                        mAppOpsService.packageRemoved(
17387                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17388
17389                                        // Remove all permissions granted from/to this package
17390                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17391
17392                                        removeTasksByPackageNameLocked(ssp, userId);
17393                                        mBatteryStatsService.notePackageUninstalled(ssp);
17394                                    }
17395                                } else {
17396                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17397                                            intent.getStringArrayExtra(
17398                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17399                                }
17400                            }
17401                            break;
17402                        case Intent.ACTION_PACKAGES_SUSPENDED:
17403                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17404                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17405                                    intent.getAction());
17406                            final String[] packageNames = intent.getStringArrayExtra(
17407                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17408                            final int userHandle = intent.getIntExtra(
17409                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17410
17411                            synchronized(ActivityManagerService.this) {
17412                                mRecentTasks.onPackagesSuspendedChanged(
17413                                        packageNames, suspended, userHandle);
17414                            }
17415                            break;
17416                    }
17417                    break;
17418                case Intent.ACTION_PACKAGE_REPLACED:
17419                {
17420                    final Uri data = intent.getData();
17421                    final String ssp;
17422                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17423                        final ApplicationInfo aInfo =
17424                                getPackageManagerInternalLocked().getApplicationInfo(
17425                                        ssp,
17426                                        userId);
17427                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17428                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17429                                new String[] {ssp}, userId);
17430                    }
17431                    break;
17432                }
17433                case Intent.ACTION_PACKAGE_ADDED:
17434                {
17435                    // Special case for adding a package: by default turn on compatibility mode.
17436                    Uri data = intent.getData();
17437                    String ssp;
17438                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17439                        final boolean replacing =
17440                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17441                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17442
17443                        try {
17444                            ApplicationInfo ai = AppGlobals.getPackageManager().
17445                                    getApplicationInfo(ssp, 0, 0);
17446                            mBatteryStatsService.notePackageInstalled(ssp,
17447                                    ai != null ? ai.versionCode : 0);
17448                        } catch (RemoteException e) {
17449                        }
17450                    }
17451                    break;
17452                }
17453                case Intent.ACTION_TIMEZONE_CHANGED:
17454                    // If this is the time zone changed action, queue up a message that will reset
17455                    // the timezone of all currently running processes. This message will get
17456                    // queued up before the broadcast happens.
17457                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17458                    break;
17459                case Intent.ACTION_TIME_CHANGED:
17460                    // If the user set the time, let all running processes know.
17461                    final int is24Hour =
17462                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17463                                    : 0;
17464                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17465                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17466                    synchronized (stats) {
17467                        stats.noteCurrentTimeChangedLocked();
17468                    }
17469                    break;
17470                case Intent.ACTION_CLEAR_DNS_CACHE:
17471                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17472                    break;
17473                case Proxy.PROXY_CHANGE_ACTION:
17474                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17475                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17476                    break;
17477                case android.hardware.Camera.ACTION_NEW_PICTURE:
17478                case android.hardware.Camera.ACTION_NEW_VIDEO:
17479                    // These broadcasts are no longer allowed by the system, since they can
17480                    // cause significant thrashing at a crictical point (using the camera).
17481                    // Apps should use JobScehduler to monitor for media provider changes.
17482                    Slog.w(TAG, action + " no longer allowed; dropping from "
17483                            + UserHandle.formatUid(callingUid));
17484                    // Lie; we don't want to crash the app.
17485                    return ActivityManager.BROADCAST_SUCCESS;
17486            }
17487        }
17488
17489        // Add to the sticky list if requested.
17490        if (sticky) {
17491            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17492                    callingPid, callingUid)
17493                    != PackageManager.PERMISSION_GRANTED) {
17494                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17495                        + callingPid + ", uid=" + callingUid
17496                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17497                Slog.w(TAG, msg);
17498                throw new SecurityException(msg);
17499            }
17500            if (requiredPermissions != null && requiredPermissions.length > 0) {
17501                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17502                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17503                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17504            }
17505            if (intent.getComponent() != null) {
17506                throw new SecurityException(
17507                        "Sticky broadcasts can't target a specific component");
17508            }
17509            // We use userId directly here, since the "all" target is maintained
17510            // as a separate set of sticky broadcasts.
17511            if (userId != UserHandle.USER_ALL) {
17512                // But first, if this is not a broadcast to all users, then
17513                // make sure it doesn't conflict with an existing broadcast to
17514                // all users.
17515                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17516                        UserHandle.USER_ALL);
17517                if (stickies != null) {
17518                    ArrayList<Intent> list = stickies.get(intent.getAction());
17519                    if (list != null) {
17520                        int N = list.size();
17521                        int i;
17522                        for (i=0; i<N; i++) {
17523                            if (intent.filterEquals(list.get(i))) {
17524                                throw new IllegalArgumentException(
17525                                        "Sticky broadcast " + intent + " for user "
17526                                        + userId + " conflicts with existing global broadcast");
17527                            }
17528                        }
17529                    }
17530                }
17531            }
17532            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17533            if (stickies == null) {
17534                stickies = new ArrayMap<>();
17535                mStickyBroadcasts.put(userId, stickies);
17536            }
17537            ArrayList<Intent> list = stickies.get(intent.getAction());
17538            if (list == null) {
17539                list = new ArrayList<>();
17540                stickies.put(intent.getAction(), list);
17541            }
17542            final int stickiesCount = list.size();
17543            int i;
17544            for (i = 0; i < stickiesCount; i++) {
17545                if (intent.filterEquals(list.get(i))) {
17546                    // This sticky already exists, replace it.
17547                    list.set(i, new Intent(intent));
17548                    break;
17549                }
17550            }
17551            if (i >= stickiesCount) {
17552                list.add(new Intent(intent));
17553            }
17554        }
17555
17556        int[] users;
17557        if (userId == UserHandle.USER_ALL) {
17558            // Caller wants broadcast to go to all started users.
17559            users = mUserController.getStartedUserArrayLocked();
17560        } else {
17561            // Caller wants broadcast to go to one specific user.
17562            users = new int[] {userId};
17563        }
17564
17565        // Figure out who all will receive this broadcast.
17566        List receivers = null;
17567        List<BroadcastFilter> registeredReceivers = null;
17568        // Need to resolve the intent to interested receivers...
17569        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17570                 == 0) {
17571            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17572        }
17573        if (intent.getComponent() == null) {
17574            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17575                // Query one target user at a time, excluding shell-restricted users
17576                for (int i = 0; i < users.length; i++) {
17577                    if (mUserController.hasUserRestriction(
17578                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17579                        continue;
17580                    }
17581                    List<BroadcastFilter> registeredReceiversForUser =
17582                            mReceiverResolver.queryIntent(intent,
17583                                    resolvedType, false, users[i]);
17584                    if (registeredReceivers == null) {
17585                        registeredReceivers = registeredReceiversForUser;
17586                    } else if (registeredReceiversForUser != null) {
17587                        registeredReceivers.addAll(registeredReceiversForUser);
17588                    }
17589                }
17590            } else {
17591                registeredReceivers = mReceiverResolver.queryIntent(intent,
17592                        resolvedType, false, userId);
17593            }
17594        }
17595
17596        final boolean replacePending =
17597                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17598
17599        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17600                + " replacePending=" + replacePending);
17601
17602        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17603        if (!ordered && NR > 0) {
17604            // If we are not serializing this broadcast, then send the
17605            // registered receivers separately so they don't wait for the
17606            // components to be launched.
17607            final BroadcastQueue queue = broadcastQueueForIntent(intent);
17608            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17609                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17610                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17611                    resultExtras, ordered, sticky, false, userId);
17612            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17613            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17614            if (!replaced) {
17615                queue.enqueueParallelBroadcastLocked(r);
17616                queue.scheduleBroadcastsLocked();
17617            }
17618            registeredReceivers = null;
17619            NR = 0;
17620        }
17621
17622        // Merge into one list.
17623        int ir = 0;
17624        if (receivers != null) {
17625            // A special case for PACKAGE_ADDED: do not allow the package
17626            // being added to see this broadcast.  This prevents them from
17627            // using this as a back door to get run as soon as they are
17628            // installed.  Maybe in the future we want to have a special install
17629            // broadcast or such for apps, but we'd like to deliberately make
17630            // this decision.
17631            String skipPackages[] = null;
17632            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17633                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17634                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17635                Uri data = intent.getData();
17636                if (data != null) {
17637                    String pkgName = data.getSchemeSpecificPart();
17638                    if (pkgName != null) {
17639                        skipPackages = new String[] { pkgName };
17640                    }
17641                }
17642            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17643                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17644            }
17645            if (skipPackages != null && (skipPackages.length > 0)) {
17646                for (String skipPackage : skipPackages) {
17647                    if (skipPackage != null) {
17648                        int NT = receivers.size();
17649                        for (int it=0; it<NT; it++) {
17650                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
17651                            if (curt.activityInfo.packageName.equals(skipPackage)) {
17652                                receivers.remove(it);
17653                                it--;
17654                                NT--;
17655                            }
17656                        }
17657                    }
17658                }
17659            }
17660
17661            int NT = receivers != null ? receivers.size() : 0;
17662            int it = 0;
17663            ResolveInfo curt = null;
17664            BroadcastFilter curr = null;
17665            while (it < NT && ir < NR) {
17666                if (curt == null) {
17667                    curt = (ResolveInfo)receivers.get(it);
17668                }
17669                if (curr == null) {
17670                    curr = registeredReceivers.get(ir);
17671                }
17672                if (curr.getPriority() >= curt.priority) {
17673                    // Insert this broadcast record into the final list.
17674                    receivers.add(it, curr);
17675                    ir++;
17676                    curr = null;
17677                    it++;
17678                    NT++;
17679                } else {
17680                    // Skip to the next ResolveInfo in the final list.
17681                    it++;
17682                    curt = null;
17683                }
17684            }
17685        }
17686        while (ir < NR) {
17687            if (receivers == null) {
17688                receivers = new ArrayList();
17689            }
17690            receivers.add(registeredReceivers.get(ir));
17691            ir++;
17692        }
17693
17694        if ((receivers != null && receivers.size() > 0)
17695                || resultTo != null) {
17696            BroadcastQueue queue = broadcastQueueForIntent(intent);
17697            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17698                    callerPackage, callingPid, callingUid, resolvedType,
17699                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17700                    resultData, resultExtras, ordered, sticky, false, userId);
17701
17702            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17703                    + ": prev had " + queue.mOrderedBroadcasts.size());
17704            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17705                    "Enqueueing broadcast " + r.intent.getAction());
17706
17707            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17708            if (!replaced) {
17709                queue.enqueueOrderedBroadcastLocked(r);
17710                queue.scheduleBroadcastsLocked();
17711            }
17712        }
17713
17714        return ActivityManager.BROADCAST_SUCCESS;
17715    }
17716
17717    final Intent verifyBroadcastLocked(Intent intent) {
17718        // Refuse possible leaked file descriptors
17719        if (intent != null && intent.hasFileDescriptors() == true) {
17720            throw new IllegalArgumentException("File descriptors passed in Intent");
17721        }
17722
17723        int flags = intent.getFlags();
17724
17725        if (!mProcessesReady) {
17726            // if the caller really truly claims to know what they're doing, go
17727            // ahead and allow the broadcast without launching any receivers
17728            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17729                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17730            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17731                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17732                        + " before boot completion");
17733                throw new IllegalStateException("Cannot broadcast before boot completed");
17734            }
17735        }
17736
17737        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17738            throw new IllegalArgumentException(
17739                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17740        }
17741
17742        return intent;
17743    }
17744
17745    public final int broadcastIntent(IApplicationThread caller,
17746            Intent intent, String resolvedType, IIntentReceiver resultTo,
17747            int resultCode, String resultData, Bundle resultExtras,
17748            String[] requiredPermissions, int appOp, Bundle bOptions,
17749            boolean serialized, boolean sticky, int userId) {
17750        enforceNotIsolatedCaller("broadcastIntent");
17751        synchronized(this) {
17752            intent = verifyBroadcastLocked(intent);
17753
17754            final ProcessRecord callerApp = getRecordForAppLocked(caller);
17755            final int callingPid = Binder.getCallingPid();
17756            final int callingUid = Binder.getCallingUid();
17757            final long origId = Binder.clearCallingIdentity();
17758            int res = broadcastIntentLocked(callerApp,
17759                    callerApp != null ? callerApp.info.packageName : null,
17760                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17761                    requiredPermissions, appOp, bOptions, serialized, sticky,
17762                    callingPid, callingUid, userId);
17763            Binder.restoreCallingIdentity(origId);
17764            return res;
17765        }
17766    }
17767
17768
17769    int broadcastIntentInPackage(String packageName, int uid,
17770            Intent intent, String resolvedType, IIntentReceiver resultTo,
17771            int resultCode, String resultData, Bundle resultExtras,
17772            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17773            int userId) {
17774        synchronized(this) {
17775            intent = verifyBroadcastLocked(intent);
17776
17777            final long origId = Binder.clearCallingIdentity();
17778            String[] requiredPermissions = requiredPermission == null ? null
17779                    : new String[] {requiredPermission};
17780            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17781                    resultTo, resultCode, resultData, resultExtras,
17782                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17783                    sticky, -1, uid, userId);
17784            Binder.restoreCallingIdentity(origId);
17785            return res;
17786        }
17787    }
17788
17789    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17790        // Refuse possible leaked file descriptors
17791        if (intent != null && intent.hasFileDescriptors() == true) {
17792            throw new IllegalArgumentException("File descriptors passed in Intent");
17793        }
17794
17795        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17796                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17797
17798        synchronized(this) {
17799            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17800                    != PackageManager.PERMISSION_GRANTED) {
17801                String msg = "Permission Denial: unbroadcastIntent() from pid="
17802                        + Binder.getCallingPid()
17803                        + ", uid=" + Binder.getCallingUid()
17804                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17805                Slog.w(TAG, msg);
17806                throw new SecurityException(msg);
17807            }
17808            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17809            if (stickies != null) {
17810                ArrayList<Intent> list = stickies.get(intent.getAction());
17811                if (list != null) {
17812                    int N = list.size();
17813                    int i;
17814                    for (i=0; i<N; i++) {
17815                        if (intent.filterEquals(list.get(i))) {
17816                            list.remove(i);
17817                            break;
17818                        }
17819                    }
17820                    if (list.size() <= 0) {
17821                        stickies.remove(intent.getAction());
17822                    }
17823                }
17824                if (stickies.size() <= 0) {
17825                    mStickyBroadcasts.remove(userId);
17826                }
17827            }
17828        }
17829    }
17830
17831    void backgroundServicesFinishedLocked(int userId) {
17832        for (BroadcastQueue queue : mBroadcastQueues) {
17833            queue.backgroundServicesFinishedLocked(userId);
17834        }
17835    }
17836
17837    public void finishReceiver(IBinder who, int resultCode, String resultData,
17838            Bundle resultExtras, boolean resultAbort, int flags) {
17839        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17840
17841        // Refuse possible leaked file descriptors
17842        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17843            throw new IllegalArgumentException("File descriptors passed in Bundle");
17844        }
17845
17846        final long origId = Binder.clearCallingIdentity();
17847        try {
17848            boolean doNext = false;
17849            BroadcastRecord r;
17850
17851            synchronized(this) {
17852                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17853                        ? mFgBroadcastQueue : mBgBroadcastQueue;
17854                r = queue.getMatchingOrderedReceiver(who);
17855                if (r != null) {
17856                    doNext = r.queue.finishReceiverLocked(r, resultCode,
17857                        resultData, resultExtras, resultAbort, true);
17858                }
17859            }
17860
17861            if (doNext) {
17862                r.queue.processNextBroadcast(false);
17863            }
17864            trimApplications();
17865        } finally {
17866            Binder.restoreCallingIdentity(origId);
17867        }
17868    }
17869
17870    // =========================================================
17871    // INSTRUMENTATION
17872    // =========================================================
17873
17874    public boolean startInstrumentation(ComponentName className,
17875            String profileFile, int flags, Bundle arguments,
17876            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17877            int userId, String abiOverride) {
17878        enforceNotIsolatedCaller("startInstrumentation");
17879        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17880                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17881        // Refuse possible leaked file descriptors
17882        if (arguments != null && arguments.hasFileDescriptors()) {
17883            throw new IllegalArgumentException("File descriptors passed in Bundle");
17884        }
17885
17886        synchronized(this) {
17887            InstrumentationInfo ii = null;
17888            ApplicationInfo ai = null;
17889            try {
17890                ii = mContext.getPackageManager().getInstrumentationInfo(
17891                    className, STOCK_PM_FLAGS);
17892                ai = AppGlobals.getPackageManager().getApplicationInfo(
17893                        ii.targetPackage, STOCK_PM_FLAGS, userId);
17894            } catch (PackageManager.NameNotFoundException e) {
17895            } catch (RemoteException e) {
17896            }
17897            if (ii == null) {
17898                reportStartInstrumentationFailureLocked(watcher, className,
17899                        "Unable to find instrumentation info for: " + className);
17900                return false;
17901            }
17902            if (ai == null) {
17903                reportStartInstrumentationFailureLocked(watcher, className,
17904                        "Unable to find instrumentation target package: " + ii.targetPackage);
17905                return false;
17906            }
17907            if (!ai.hasCode()) {
17908                reportStartInstrumentationFailureLocked(watcher, className,
17909                        "Instrumentation target has no code: " + ii.targetPackage);
17910                return false;
17911            }
17912
17913            int match = mContext.getPackageManager().checkSignatures(
17914                    ii.targetPackage, ii.packageName);
17915            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17916                String msg = "Permission Denial: starting instrumentation "
17917                        + className + " from pid="
17918                        + Binder.getCallingPid()
17919                        + ", uid=" + Binder.getCallingPid()
17920                        + " not allowed because package " + ii.packageName
17921                        + " does not have a signature matching the target "
17922                        + ii.targetPackage;
17923                reportStartInstrumentationFailureLocked(watcher, className, msg);
17924                throw new SecurityException(msg);
17925            }
17926
17927            final long origId = Binder.clearCallingIdentity();
17928            // Instrumentation can kill and relaunch even persistent processes
17929            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17930                    "start instr");
17931            ProcessRecord app = addAppLocked(ai, false, abiOverride);
17932            app.instrumentationClass = className;
17933            app.instrumentationInfo = ai;
17934            app.instrumentationProfileFile = profileFile;
17935            app.instrumentationArguments = arguments;
17936            app.instrumentationWatcher = watcher;
17937            app.instrumentationUiAutomationConnection = uiAutomationConnection;
17938            app.instrumentationResultClass = className;
17939            Binder.restoreCallingIdentity(origId);
17940        }
17941
17942        return true;
17943    }
17944
17945    /**
17946     * Report errors that occur while attempting to start Instrumentation.  Always writes the
17947     * error to the logs, but if somebody is watching, send the report there too.  This enables
17948     * the "am" command to report errors with more information.
17949     *
17950     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
17951     * @param cn The component name of the instrumentation.
17952     * @param report The error report.
17953     */
17954    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17955            ComponentName cn, String report) {
17956        Slog.w(TAG, report);
17957        if (watcher != null) {
17958            Bundle results = new Bundle();
17959            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17960            results.putString("Error", report);
17961            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17962        }
17963    }
17964
17965    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17966        if (app.instrumentationWatcher != null) {
17967            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17968                    app.instrumentationClass, resultCode, results);
17969        }
17970
17971        // Can't call out of the system process with a lock held, so post a message.
17972        if (app.instrumentationUiAutomationConnection != null) {
17973            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17974                    app.instrumentationUiAutomationConnection).sendToTarget();
17975        }
17976
17977        app.instrumentationWatcher = null;
17978        app.instrumentationUiAutomationConnection = null;
17979        app.instrumentationClass = null;
17980        app.instrumentationInfo = null;
17981        app.instrumentationProfileFile = null;
17982        app.instrumentationArguments = null;
17983
17984        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17985                "finished inst");
17986    }
17987
17988    public void finishInstrumentation(IApplicationThread target,
17989            int resultCode, Bundle results) {
17990        int userId = UserHandle.getCallingUserId();
17991        // Refuse possible leaked file descriptors
17992        if (results != null && results.hasFileDescriptors()) {
17993            throw new IllegalArgumentException("File descriptors passed in Intent");
17994        }
17995
17996        synchronized(this) {
17997            ProcessRecord app = getRecordForAppLocked(target);
17998            if (app == null) {
17999                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18000                return;
18001            }
18002            final long origId = Binder.clearCallingIdentity();
18003            finishInstrumentationLocked(app, resultCode, results);
18004            Binder.restoreCallingIdentity(origId);
18005        }
18006    }
18007
18008    // =========================================================
18009    // CONFIGURATION
18010    // =========================================================
18011
18012    public ConfigurationInfo getDeviceConfigurationInfo() {
18013        ConfigurationInfo config = new ConfigurationInfo();
18014        synchronized (this) {
18015            config.reqTouchScreen = mConfiguration.touchscreen;
18016            config.reqKeyboardType = mConfiguration.keyboard;
18017            config.reqNavigation = mConfiguration.navigation;
18018            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18019                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18020                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18021            }
18022            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18023                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18024                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18025            }
18026            config.reqGlEsVersion = GL_ES_VERSION;
18027        }
18028        return config;
18029    }
18030
18031    ActivityStack getFocusedStack() {
18032        return mStackSupervisor.getFocusedStack();
18033    }
18034
18035    @Override
18036    public int getFocusedStackId() throws RemoteException {
18037        ActivityStack focusedStack = getFocusedStack();
18038        if (focusedStack != null) {
18039            return focusedStack.getStackId();
18040        }
18041        return -1;
18042    }
18043
18044    public Configuration getConfiguration() {
18045        Configuration ci;
18046        synchronized(this) {
18047            ci = new Configuration(mConfiguration);
18048            ci.userSetLocale = false;
18049        }
18050        return ci;
18051    }
18052
18053    @Override
18054    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18055        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18056        synchronized (this) {
18057            mSuppressResizeConfigChanges = suppress;
18058        }
18059    }
18060
18061    @Override
18062    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18063        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18064        if (fromStackId == HOME_STACK_ID) {
18065            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18066        }
18067        synchronized (this) {
18068            final long origId = Binder.clearCallingIdentity();
18069            try {
18070                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18071            } finally {
18072                Binder.restoreCallingIdentity(origId);
18073            }
18074        }
18075    }
18076
18077    @Override
18078    public void updatePersistentConfiguration(Configuration values) {
18079        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18080                "updateConfiguration()");
18081        enforceWriteSettingsPermission("updateConfiguration()");
18082        if (values == null) {
18083            throw new NullPointerException("Configuration must not be null");
18084        }
18085
18086        int userId = UserHandle.getCallingUserId();
18087
18088        synchronized(this) {
18089            final long origId = Binder.clearCallingIdentity();
18090            updateConfigurationLocked(values, null, false, true, userId);
18091            Binder.restoreCallingIdentity(origId);
18092        }
18093    }
18094
18095    private void updateFontScaleIfNeeded() {
18096        final int currentUserId;
18097        synchronized(this) {
18098            currentUserId = mUserController.getCurrentUserIdLocked();
18099        }
18100        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18101                FONT_SCALE, 1.0f, currentUserId);
18102        if (mConfiguration.fontScale != scaleFactor) {
18103            final Configuration configuration = mWindowManager.computeNewConfiguration();
18104            configuration.fontScale = scaleFactor;
18105            updatePersistentConfiguration(configuration);
18106        }
18107    }
18108
18109    private void enforceWriteSettingsPermission(String func) {
18110        int uid = Binder.getCallingUid();
18111        if (uid == Process.ROOT_UID) {
18112            return;
18113        }
18114
18115        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18116                Settings.getPackageNameForUid(mContext, uid), false)) {
18117            return;
18118        }
18119
18120        String msg = "Permission Denial: " + func + " from pid="
18121                + Binder.getCallingPid()
18122                + ", uid=" + uid
18123                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18124        Slog.w(TAG, msg);
18125        throw new SecurityException(msg);
18126    }
18127
18128    public void updateConfiguration(Configuration values) {
18129        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18130                "updateConfiguration()");
18131
18132        synchronized(this) {
18133            if (values == null && mWindowManager != null) {
18134                // sentinel: fetch the current configuration from the window manager
18135                values = mWindowManager.computeNewConfiguration();
18136            }
18137
18138            if (mWindowManager != null) {
18139                mProcessList.applyDisplaySize(mWindowManager);
18140            }
18141
18142            final long origId = Binder.clearCallingIdentity();
18143            if (values != null) {
18144                Settings.System.clearConfiguration(values);
18145            }
18146            updateConfigurationLocked(values, null, false);
18147            Binder.restoreCallingIdentity(origId);
18148        }
18149    }
18150
18151    void updateUserConfigurationLocked() {
18152        Configuration configuration = new Configuration(mConfiguration);
18153        Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18154                mUserController.getCurrentUserIdLocked());
18155        updateConfigurationLocked(configuration, null, false);
18156    }
18157
18158    boolean updateConfigurationLocked(Configuration values,
18159            ActivityRecord starting, boolean initLocale) {
18160        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18161        return updateConfigurationLocked(values, starting, initLocale, false,
18162                UserHandle.USER_NULL);
18163    }
18164
18165    // To cache the list of supported system locales
18166    private String[] mSupportedSystemLocales = null;
18167
18168    /**
18169     * Do either or both things: (1) change the current configuration, and (2)
18170     * make sure the given activity is running with the (now) current
18171     * configuration.  Returns true if the activity has been left running, or
18172     * false if <var>starting</var> is being destroyed to match the new
18173     * configuration.
18174     *
18175     * @param userId is only used when persistent parameter is set to true to persist configuration
18176     *               for that particular user
18177     */
18178    private boolean updateConfigurationLocked(Configuration values,
18179            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18180        int changes = 0;
18181
18182        if (mWindowManager != null) {
18183            mWindowManager.deferSurfaceLayout();
18184        }
18185        if (values != null) {
18186            Configuration newConfig = new Configuration(mConfiguration);
18187            changes = newConfig.updateFrom(values);
18188            if (changes != 0) {
18189                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18190                        "Updating configuration to: " + values);
18191
18192                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18193
18194                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18195                    final Locale locale;
18196                    if (values.getLocales().size() == 1) {
18197                        // This is an optimization to avoid the JNI call when the result of
18198                        // getFirstMatch() does not depend on the supported locales.
18199                        locale = values.getLocales().get(0);
18200                    } else {
18201                        if (mSupportedSystemLocales == null) {
18202                            mSupportedSystemLocales =
18203                                    Resources.getSystem().getAssets().getLocales();
18204                        }
18205                        locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18206                    }
18207                    SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18208                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18209                            locale));
18210                }
18211
18212                mConfigurationSeq++;
18213                if (mConfigurationSeq <= 0) {
18214                    mConfigurationSeq = 1;
18215                }
18216                newConfig.seq = mConfigurationSeq;
18217                mConfiguration = newConfig;
18218                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18219                mUsageStatsService.reportConfigurationChange(newConfig,
18220                        mUserController.getCurrentUserIdLocked());
18221                //mUsageStatsService.noteStartConfig(newConfig);
18222
18223                final Configuration configCopy = new Configuration(mConfiguration);
18224
18225                // TODO: If our config changes, should we auto dismiss any currently
18226                // showing dialogs?
18227                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18228
18229                AttributeCache ac = AttributeCache.instance();
18230                if (ac != null) {
18231                    ac.updateConfiguration(configCopy);
18232                }
18233
18234                // Make sure all resources in our process are updated
18235                // right now, so that anyone who is going to retrieve
18236                // resource values after we return will be sure to get
18237                // the new ones.  This is especially important during
18238                // boot, where the first config change needs to guarantee
18239                // all resources have that config before following boot
18240                // code is executed.
18241                mSystemThread.applyConfigurationToResources(configCopy);
18242
18243                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18244                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18245                    msg.obj = new Configuration(configCopy);
18246                    msg.arg1 = userId;
18247                    mHandler.sendMessage(msg);
18248                }
18249
18250                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18251                if (isDensityChange) {
18252                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18253                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18254                }
18255
18256                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18257                    ProcessRecord app = mLruProcesses.get(i);
18258                    try {
18259                        if (app.thread != null) {
18260                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18261                                    + app.processName + " new config " + mConfiguration);
18262                            app.thread.scheduleConfigurationChanged(configCopy);
18263                        }
18264                    } catch (Exception e) {
18265                    }
18266                }
18267                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18268                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18269                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18270                        | Intent.FLAG_RECEIVER_FOREGROUND);
18271                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18272                        null, AppOpsManager.OP_NONE, null, false, false,
18273                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18274                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18275                    // Tell the shortcut manager that the system locale changed.  It needs to know
18276                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18277                    // we "push" from here, rather than having the service listen to the broadcast.
18278                    final ShortcutServiceInternal shortcutService =
18279                            LocalServices.getService(ShortcutServiceInternal.class);
18280                    if (shortcutService != null) {
18281                        shortcutService.onSystemLocaleChangedNoLock();
18282                    }
18283
18284                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18285                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18286                    if (!mProcessesReady) {
18287                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18288                    }
18289                    broadcastIntentLocked(null, null, intent,
18290                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18291                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18292                }
18293            }
18294            // Update the configuration with WM first and check if any of the stacks need to be
18295            // resized due to the configuration change. If so, resize the stacks now and do any
18296            // relaunches if necessary. This way we don't need to relaunch again below in
18297            // ensureActivityConfigurationLocked().
18298            if (mWindowManager != null) {
18299                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18300                if (resizedStacks != null) {
18301                    for (int stackId : resizedStacks) {
18302                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18303                        mStackSupervisor.resizeStackLocked(
18304                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18305                    }
18306                }
18307            }
18308        }
18309
18310        boolean kept = true;
18311        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18312        // mainStack is null during startup.
18313        if (mainStack != null) {
18314            if (changes != 0 && starting == null) {
18315                // If the configuration changed, and the caller is not already
18316                // in the process of starting an activity, then find the top
18317                // activity to check if its configuration needs to change.
18318                starting = mainStack.topRunningActivityLocked();
18319            }
18320
18321            if (starting != null) {
18322                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18323                // And we need to make sure at this point that all other activities
18324                // are made visible with the correct configuration.
18325                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18326                        !PRESERVE_WINDOWS);
18327            }
18328        }
18329        if (mWindowManager != null) {
18330            mWindowManager.continueSurfaceLayout();
18331        }
18332        return kept;
18333    }
18334
18335    /**
18336     * Decide based on the configuration whether we should shouw the ANR,
18337     * crash, etc dialogs.  The idea is that if there is no affordnace to
18338     * press the on-screen buttons, we shouldn't show the dialog.
18339     *
18340     * A thought: SystemUI might also want to get told about this, the Power
18341     * dialog / global actions also might want different behaviors.
18342     */
18343    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18344        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18345                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18346                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18347        final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18348                                    == Configuration.UI_MODE_TYPE_CAR);
18349        return inputMethodExists && uiIsNotCarType && !inVrMode;
18350    }
18351
18352    @Override
18353    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18354        synchronized (this) {
18355            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18356            if (srec != null) {
18357                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18358            }
18359        }
18360        return false;
18361    }
18362
18363    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18364            Intent resultData) {
18365
18366        synchronized (this) {
18367            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18368            if (r != null) {
18369                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18370            }
18371            return false;
18372        }
18373    }
18374
18375    public int getLaunchedFromUid(IBinder activityToken) {
18376        ActivityRecord srec;
18377        synchronized (this) {
18378            srec = ActivityRecord.forTokenLocked(activityToken);
18379        }
18380        if (srec == null) {
18381            return -1;
18382        }
18383        return srec.launchedFromUid;
18384    }
18385
18386    public String getLaunchedFromPackage(IBinder activityToken) {
18387        ActivityRecord srec;
18388        synchronized (this) {
18389            srec = ActivityRecord.forTokenLocked(activityToken);
18390        }
18391        if (srec == null) {
18392            return null;
18393        }
18394        return srec.launchedFromPackage;
18395    }
18396
18397    // =========================================================
18398    // LIFETIME MANAGEMENT
18399    // =========================================================
18400
18401    // Returns which broadcast queue the app is the current [or imminent] receiver
18402    // on, or 'null' if the app is not an active broadcast recipient.
18403    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18404        BroadcastRecord r = app.curReceiver;
18405        if (r != null) {
18406            return r.queue;
18407        }
18408
18409        // It's not the current receiver, but it might be starting up to become one
18410        synchronized (this) {
18411            for (BroadcastQueue queue : mBroadcastQueues) {
18412                r = queue.mPendingBroadcast;
18413                if (r != null && r.curApp == app) {
18414                    // found it; report which queue it's in
18415                    return queue;
18416                }
18417            }
18418        }
18419
18420        return null;
18421    }
18422
18423    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18424            int targetUid, ComponentName targetComponent, String targetProcess) {
18425        if (!mTrackingAssociations) {
18426            return null;
18427        }
18428        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18429                = mAssociations.get(targetUid);
18430        if (components == null) {
18431            components = new ArrayMap<>();
18432            mAssociations.put(targetUid, components);
18433        }
18434        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18435        if (sourceUids == null) {
18436            sourceUids = new SparseArray<>();
18437            components.put(targetComponent, sourceUids);
18438        }
18439        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18440        if (sourceProcesses == null) {
18441            sourceProcesses = new ArrayMap<>();
18442            sourceUids.put(sourceUid, sourceProcesses);
18443        }
18444        Association ass = sourceProcesses.get(sourceProcess);
18445        if (ass == null) {
18446            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18447                    targetProcess);
18448            sourceProcesses.put(sourceProcess, ass);
18449        }
18450        ass.mCount++;
18451        ass.mNesting++;
18452        if (ass.mNesting == 1) {
18453            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18454            ass.mLastState = sourceState;
18455        }
18456        return ass;
18457    }
18458
18459    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18460            ComponentName targetComponent) {
18461        if (!mTrackingAssociations) {
18462            return;
18463        }
18464        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18465                = mAssociations.get(targetUid);
18466        if (components == null) {
18467            return;
18468        }
18469        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18470        if (sourceUids == null) {
18471            return;
18472        }
18473        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18474        if (sourceProcesses == null) {
18475            return;
18476        }
18477        Association ass = sourceProcesses.get(sourceProcess);
18478        if (ass == null || ass.mNesting <= 0) {
18479            return;
18480        }
18481        ass.mNesting--;
18482        if (ass.mNesting == 0) {
18483            long uptime = SystemClock.uptimeMillis();
18484            ass.mTime += uptime - ass.mStartTime;
18485            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18486                    += uptime - ass.mLastStateUptime;
18487            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18488        }
18489    }
18490
18491    private void noteUidProcessState(final int uid, final int state) {
18492        mBatteryStatsService.noteUidProcessState(uid, state);
18493        if (mTrackingAssociations) {
18494            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18495                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18496                        = mAssociations.valueAt(i1);
18497                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18498                    SparseArray<ArrayMap<String, Association>> sourceUids
18499                            = targetComponents.valueAt(i2);
18500                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18501                    if (sourceProcesses != null) {
18502                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18503                            Association ass = sourceProcesses.valueAt(i4);
18504                            if (ass.mNesting >= 1) {
18505                                // currently associated
18506                                long uptime = SystemClock.uptimeMillis();
18507                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18508                                        += uptime - ass.mLastStateUptime;
18509                                ass.mLastState = state;
18510                                ass.mLastStateUptime = uptime;
18511                            }
18512                        }
18513                    }
18514                }
18515            }
18516        }
18517    }
18518
18519    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18520            boolean doingAll, long now) {
18521        if (mAdjSeq == app.adjSeq) {
18522            // This adjustment has already been computed.
18523            return app.curRawAdj;
18524        }
18525
18526        if (app.thread == null) {
18527            app.adjSeq = mAdjSeq;
18528            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18529            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18530            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18531        }
18532
18533        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18534        app.adjSource = null;
18535        app.adjTarget = null;
18536        app.empty = false;
18537        app.cached = false;
18538
18539        final int activitiesSize = app.activities.size();
18540
18541        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18542            // The max adjustment doesn't allow this app to be anything
18543            // below foreground, so it is not worth doing work for it.
18544            app.adjType = "fixed";
18545            app.adjSeq = mAdjSeq;
18546            app.curRawAdj = app.maxAdj;
18547            app.foregroundActivities = false;
18548            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18549            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18550            // System processes can do UI, and when they do we want to have
18551            // them trim their memory after the user leaves the UI.  To
18552            // facilitate this, here we need to determine whether or not it
18553            // is currently showing UI.
18554            app.systemNoUi = true;
18555            if (app == TOP_APP) {
18556                app.systemNoUi = false;
18557            } else if (activitiesSize > 0) {
18558                for (int j = 0; j < activitiesSize; j++) {
18559                    final ActivityRecord r = app.activities.get(j);
18560                    if (r.visible) {
18561                        app.systemNoUi = false;
18562                    }
18563                }
18564            }
18565            if (!app.systemNoUi) {
18566                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18567            }
18568            return (app.curAdj=app.maxAdj);
18569        }
18570
18571        app.systemNoUi = false;
18572
18573        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18574
18575        // Determine the importance of the process, starting with most
18576        // important to least, and assign an appropriate OOM adjustment.
18577        int adj;
18578        int schedGroup;
18579        int procState;
18580        boolean foregroundActivities = false;
18581        BroadcastQueue queue;
18582        if (app == TOP_APP) {
18583            // The last app on the list is the foreground app.
18584            adj = ProcessList.FOREGROUND_APP_ADJ;
18585            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18586            app.adjType = "top-activity";
18587            foregroundActivities = true;
18588            procState = PROCESS_STATE_CUR_TOP;
18589        } else if (app.instrumentationClass != null) {
18590            // Don't want to kill running instrumentation.
18591            adj = ProcessList.FOREGROUND_APP_ADJ;
18592            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18593            app.adjType = "instrumentation";
18594            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18595        } else if ((queue = isReceivingBroadcast(app)) != null) {
18596            // An app that is currently receiving a broadcast also
18597            // counts as being in the foreground for OOM killer purposes.
18598            // It's placed in a sched group based on the nature of the
18599            // broadcast as reflected by which queue it's active in.
18600            adj = ProcessList.FOREGROUND_APP_ADJ;
18601            schedGroup = (queue == mFgBroadcastQueue)
18602                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18603            app.adjType = "broadcast";
18604            procState = ActivityManager.PROCESS_STATE_RECEIVER;
18605        } else if (app.executingServices.size() > 0) {
18606            // An app that is currently executing a service callback also
18607            // counts as being in the foreground.
18608            adj = ProcessList.FOREGROUND_APP_ADJ;
18609            schedGroup = app.execServicesFg ?
18610                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18611            app.adjType = "exec-service";
18612            procState = ActivityManager.PROCESS_STATE_SERVICE;
18613            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18614        } else {
18615            // As far as we know the process is empty.  We may change our mind later.
18616            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18617            // At this point we don't actually know the adjustment.  Use the cached adj
18618            // value that the caller wants us to.
18619            adj = cachedAdj;
18620            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18621            app.cached = true;
18622            app.empty = true;
18623            app.adjType = "cch-empty";
18624        }
18625
18626        // Examine all activities if not already foreground.
18627        if (!foregroundActivities && activitiesSize > 0) {
18628            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18629            for (int j = 0; j < activitiesSize; j++) {
18630                final ActivityRecord r = app.activities.get(j);
18631                if (r.app != app) {
18632                    Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18633                            + " instead of expected " + app);
18634                    if (r.app == null || (r.app.uid == app.uid)) {
18635                        // Only fix things up when they look sane
18636                        r.app = app;
18637                    } else {
18638                        continue;
18639                    }
18640                }
18641                if (r.visible) {
18642                    // App has a visible activity; only upgrade adjustment.
18643                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18644                        adj = ProcessList.VISIBLE_APP_ADJ;
18645                        app.adjType = "visible";
18646                    }
18647                    if (procState > PROCESS_STATE_CUR_TOP) {
18648                        procState = PROCESS_STATE_CUR_TOP;
18649                    }
18650                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18651                    app.cached = false;
18652                    app.empty = false;
18653                    foregroundActivities = true;
18654                    if (r.task != null && minLayer > 0) {
18655                        final int layer = r.task.mLayerRank;
18656                        if (layer >= 0 && minLayer > layer) {
18657                            minLayer = layer;
18658                        }
18659                    }
18660                    break;
18661                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18662                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18663                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18664                        app.adjType = "pausing";
18665                    }
18666                    if (procState > PROCESS_STATE_CUR_TOP) {
18667                        procState = PROCESS_STATE_CUR_TOP;
18668                    }
18669                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18670                    app.cached = false;
18671                    app.empty = false;
18672                    foregroundActivities = true;
18673                } else if (r.state == ActivityState.STOPPING) {
18674                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18675                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18676                        app.adjType = "stopping";
18677                    }
18678                    // For the process state, we will at this point consider the
18679                    // process to be cached.  It will be cached either as an activity
18680                    // or empty depending on whether the activity is finishing.  We do
18681                    // this so that we can treat the process as cached for purposes of
18682                    // memory trimming (determing current memory level, trim command to
18683                    // send to process) since there can be an arbitrary number of stopping
18684                    // processes and they should soon all go into the cached state.
18685                    if (!r.finishing) {
18686                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18687                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18688                        }
18689                    }
18690                    app.cached = false;
18691                    app.empty = false;
18692                    foregroundActivities = true;
18693                } else {
18694                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18695                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18696                        app.adjType = "cch-act";
18697                    }
18698                }
18699            }
18700            if (adj == ProcessList.VISIBLE_APP_ADJ) {
18701                adj += minLayer;
18702            }
18703        }
18704
18705        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18706                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18707            if (app.foregroundServices) {
18708                // The user is aware of this app, so make it visible.
18709                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18710                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18711                app.cached = false;
18712                app.adjType = "fg-service";
18713                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18714            } else if (app.forcingToForeground != null) {
18715                // The user is aware of this app, so make it visible.
18716                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18717                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18718                app.cached = false;
18719                app.adjType = "force-fg";
18720                app.adjSource = app.forcingToForeground;
18721                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18722            }
18723        }
18724
18725        if (app == mHeavyWeightProcess) {
18726            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18727                // We don't want to kill the current heavy-weight process.
18728                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18729                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18730                app.cached = false;
18731                app.adjType = "heavy";
18732            }
18733            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18734                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18735            }
18736        }
18737
18738        if (app == mHomeProcess) {
18739            if (adj > ProcessList.HOME_APP_ADJ) {
18740                // This process is hosting what we currently consider to be the
18741                // home app, so we don't want to let it go into the background.
18742                adj = ProcessList.HOME_APP_ADJ;
18743                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18744                app.cached = false;
18745                app.adjType = "home";
18746            }
18747            if (procState > ActivityManager.PROCESS_STATE_HOME) {
18748                procState = ActivityManager.PROCESS_STATE_HOME;
18749            }
18750        }
18751
18752        if (app == mPreviousProcess && app.activities.size() > 0) {
18753            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18754                // This was the previous process that showed UI to the user.
18755                // We want to try to keep it around more aggressively, to give
18756                // a good experience around switching between two apps.
18757                adj = ProcessList.PREVIOUS_APP_ADJ;
18758                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18759                app.cached = false;
18760                app.adjType = "previous";
18761            }
18762            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18763                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18764            }
18765        }
18766
18767        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18768                + " reason=" + app.adjType);
18769
18770        // By default, we use the computed adjustment.  It may be changed if
18771        // there are applications dependent on our services or providers, but
18772        // this gives us a baseline and makes sure we don't get into an
18773        // infinite recursion.
18774        app.adjSeq = mAdjSeq;
18775        app.curRawAdj = adj;
18776        app.hasStartedServices = false;
18777
18778        if (mBackupTarget != null && app == mBackupTarget.app) {
18779            // If possible we want to avoid killing apps while they're being backed up
18780            if (adj > ProcessList.BACKUP_APP_ADJ) {
18781                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18782                adj = ProcessList.BACKUP_APP_ADJ;
18783                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18784                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18785                }
18786                app.adjType = "backup";
18787                app.cached = false;
18788            }
18789            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18790                procState = ActivityManager.PROCESS_STATE_BACKUP;
18791            }
18792        }
18793
18794        boolean mayBeTop = false;
18795
18796        for (int is = app.services.size()-1;
18797                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18798                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18799                        || procState > ActivityManager.PROCESS_STATE_TOP);
18800                is--) {
18801            ServiceRecord s = app.services.valueAt(is);
18802            if (s.startRequested) {
18803                app.hasStartedServices = true;
18804                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18805                    procState = ActivityManager.PROCESS_STATE_SERVICE;
18806                }
18807                if (app.hasShownUi && app != mHomeProcess) {
18808                    // If this process has shown some UI, let it immediately
18809                    // go to the LRU list because it may be pretty heavy with
18810                    // UI stuff.  We'll tag it with a label just to help
18811                    // debug and understand what is going on.
18812                    if (adj > ProcessList.SERVICE_ADJ) {
18813                        app.adjType = "cch-started-ui-services";
18814                    }
18815                } else {
18816                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18817                        // This service has seen some activity within
18818                        // recent memory, so we will keep its process ahead
18819                        // of the background processes.
18820                        if (adj > ProcessList.SERVICE_ADJ) {
18821                            adj = ProcessList.SERVICE_ADJ;
18822                            app.adjType = "started-services";
18823                            app.cached = false;
18824                        }
18825                    }
18826                    // If we have let the service slide into the background
18827                    // state, still have some text describing what it is doing
18828                    // even though the service no longer has an impact.
18829                    if (adj > ProcessList.SERVICE_ADJ) {
18830                        app.adjType = "cch-started-services";
18831                    }
18832                }
18833            }
18834            for (int conni = s.connections.size()-1;
18835                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18836                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18837                            || procState > ActivityManager.PROCESS_STATE_TOP);
18838                    conni--) {
18839                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18840                for (int i = 0;
18841                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18842                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18843                                || procState > ActivityManager.PROCESS_STATE_TOP);
18844                        i++) {
18845                    // XXX should compute this based on the max of
18846                    // all connected clients.
18847                    ConnectionRecord cr = clist.get(i);
18848                    if (cr.binding.client == app) {
18849                        // Binding to ourself is not interesting.
18850                        continue;
18851                    }
18852                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18853                        ProcessRecord client = cr.binding.client;
18854                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
18855                                TOP_APP, doingAll, now);
18856                        int clientProcState = client.curProcState;
18857                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18858                            // If the other app is cached for any reason, for purposes here
18859                            // we are going to consider it empty.  The specific cached state
18860                            // doesn't propagate except under certain conditions.
18861                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18862                        }
18863                        String adjType = null;
18864                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18865                            // Not doing bind OOM management, so treat
18866                            // this guy more like a started service.
18867                            if (app.hasShownUi && app != mHomeProcess) {
18868                                // If this process has shown some UI, let it immediately
18869                                // go to the LRU list because it may be pretty heavy with
18870                                // UI stuff.  We'll tag it with a label just to help
18871                                // debug and understand what is going on.
18872                                if (adj > clientAdj) {
18873                                    adjType = "cch-bound-ui-services";
18874                                }
18875                                app.cached = false;
18876                                clientAdj = adj;
18877                                clientProcState = procState;
18878                            } else {
18879                                if (now >= (s.lastActivity
18880                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18881                                    // This service has not seen activity within
18882                                    // recent memory, so allow it to drop to the
18883                                    // LRU list if there is no other reason to keep
18884                                    // it around.  We'll also tag it with a label just
18885                                    // to help debug and undertand what is going on.
18886                                    if (adj > clientAdj) {
18887                                        adjType = "cch-bound-services";
18888                                    }
18889                                    clientAdj = adj;
18890                                }
18891                            }
18892                        }
18893                        if (adj > clientAdj) {
18894                            // If this process has recently shown UI, and
18895                            // the process that is binding to it is less
18896                            // important than being visible, then we don't
18897                            // care about the binding as much as we care
18898                            // about letting this process get into the LRU
18899                            // list to be killed and restarted if needed for
18900                            // memory.
18901                            if (app.hasShownUi && app != mHomeProcess
18902                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18903                                adjType = "cch-bound-ui-services";
18904                            } else {
18905                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18906                                        |Context.BIND_IMPORTANT)) != 0) {
18907                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18908                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18909                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18910                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18911                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18912                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18913                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18914                                    adj = clientAdj;
18915                                } else {
18916                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
18917                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18918                                    }
18919                                }
18920                                if (!client.cached) {
18921                                    app.cached = false;
18922                                }
18923                                adjType = "service";
18924                            }
18925                        }
18926                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18927                            // This will treat important bound services identically to
18928                            // the top app, which may behave differently than generic
18929                            // foreground work.
18930                            if (client.curSchedGroup > schedGroup) {
18931                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18932                                    schedGroup = client.curSchedGroup;
18933                                } else {
18934                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18935                                }
18936                            }
18937                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18938                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18939                                    // Special handling of clients who are in the top state.
18940                                    // We *may* want to consider this process to be in the
18941                                    // top state as well, but only if there is not another
18942                                    // reason for it to be running.  Being on the top is a
18943                                    // special state, meaning you are specifically running
18944                                    // for the current top app.  If the process is already
18945                                    // running in the background for some other reason, it
18946                                    // is more important to continue considering it to be
18947                                    // in the background state.
18948                                    mayBeTop = true;
18949                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18950                                } else {
18951                                    // Special handling for above-top states (persistent
18952                                    // processes).  These should not bring the current process
18953                                    // into the top state, since they are not on top.  Instead
18954                                    // give them the best state after that.
18955                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18956                                        clientProcState =
18957                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18958                                    } else if (mWakefulness
18959                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18960                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18961                                                    != 0) {
18962                                        clientProcState =
18963                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18964                                    } else {
18965                                        clientProcState =
18966                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18967                                    }
18968                                }
18969                            }
18970                        } else {
18971                            if (clientProcState <
18972                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18973                                clientProcState =
18974                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18975                            }
18976                        }
18977                        if (procState > clientProcState) {
18978                            procState = clientProcState;
18979                        }
18980                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18981                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18982                            app.pendingUiClean = true;
18983                        }
18984                        if (adjType != null) {
18985                            app.adjType = adjType;
18986                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18987                                    .REASON_SERVICE_IN_USE;
18988                            app.adjSource = cr.binding.client;
18989                            app.adjSourceProcState = clientProcState;
18990                            app.adjTarget = s.name;
18991                        }
18992                    }
18993                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18994                        app.treatLikeActivity = true;
18995                    }
18996                    final ActivityRecord a = cr.activity;
18997                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18998                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18999                            (a.visible || a.state == ActivityState.RESUMED ||
19000                             a.state == ActivityState.PAUSING)) {
19001                            adj = ProcessList.FOREGROUND_APP_ADJ;
19002                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19003                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19004                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19005                                } else {
19006                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19007                                }
19008                            }
19009                            app.cached = false;
19010                            app.adjType = "service";
19011                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19012                                    .REASON_SERVICE_IN_USE;
19013                            app.adjSource = a;
19014                            app.adjSourceProcState = procState;
19015                            app.adjTarget = s.name;
19016                        }
19017                    }
19018                }
19019            }
19020        }
19021
19022        for (int provi = app.pubProviders.size()-1;
19023                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19024                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19025                        || procState > ActivityManager.PROCESS_STATE_TOP);
19026                provi--) {
19027            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19028            for (int i = cpr.connections.size()-1;
19029                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19030                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19031                            || procState > ActivityManager.PROCESS_STATE_TOP);
19032                    i--) {
19033                ContentProviderConnection conn = cpr.connections.get(i);
19034                ProcessRecord client = conn.client;
19035                if (client == app) {
19036                    // Being our own client is not interesting.
19037                    continue;
19038                }
19039                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19040                int clientProcState = client.curProcState;
19041                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19042                    // If the other app is cached for any reason, for purposes here
19043                    // we are going to consider it empty.
19044                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19045                }
19046                if (adj > clientAdj) {
19047                    if (app.hasShownUi && app != mHomeProcess
19048                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19049                        app.adjType = "cch-ui-provider";
19050                    } else {
19051                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19052                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19053                        app.adjType = "provider";
19054                    }
19055                    app.cached &= client.cached;
19056                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19057                            .REASON_PROVIDER_IN_USE;
19058                    app.adjSource = client;
19059                    app.adjSourceProcState = clientProcState;
19060                    app.adjTarget = cpr.name;
19061                }
19062                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19063                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19064                        // Special handling of clients who are in the top state.
19065                        // We *may* want to consider this process to be in the
19066                        // top state as well, but only if there is not another
19067                        // reason for it to be running.  Being on the top is a
19068                        // special state, meaning you are specifically running
19069                        // for the current top app.  If the process is already
19070                        // running in the background for some other reason, it
19071                        // is more important to continue considering it to be
19072                        // in the background state.
19073                        mayBeTop = true;
19074                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19075                    } else {
19076                        // Special handling for above-top states (persistent
19077                        // processes).  These should not bring the current process
19078                        // into the top state, since they are not on top.  Instead
19079                        // give them the best state after that.
19080                        clientProcState =
19081                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19082                    }
19083                }
19084                if (procState > clientProcState) {
19085                    procState = clientProcState;
19086                }
19087                if (client.curSchedGroup > schedGroup) {
19088                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19089                }
19090            }
19091            // If the provider has external (non-framework) process
19092            // dependencies, ensure that its adjustment is at least
19093            // FOREGROUND_APP_ADJ.
19094            if (cpr.hasExternalProcessHandles()) {
19095                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19096                    adj = ProcessList.FOREGROUND_APP_ADJ;
19097                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19098                    app.cached = false;
19099                    app.adjType = "provider";
19100                    app.adjTarget = cpr.name;
19101                }
19102                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19103                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19104                }
19105            }
19106        }
19107
19108        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19109            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19110                adj = ProcessList.PREVIOUS_APP_ADJ;
19111                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19112                app.cached = false;
19113                app.adjType = "provider";
19114            }
19115            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19116                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19117            }
19118        }
19119
19120        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19121            // A client of one of our services or providers is in the top state.  We
19122            // *may* want to be in the top state, but not if we are already running in
19123            // the background for some other reason.  For the decision here, we are going
19124            // to pick out a few specific states that we want to remain in when a client
19125            // is top (states that tend to be longer-term) and otherwise allow it to go
19126            // to the top state.
19127            switch (procState) {
19128                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19129                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19130                case ActivityManager.PROCESS_STATE_SERVICE:
19131                    // These all are longer-term states, so pull them up to the top
19132                    // of the background states, but not all the way to the top state.
19133                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19134                    break;
19135                default:
19136                    // Otherwise, top is a better choice, so take it.
19137                    procState = ActivityManager.PROCESS_STATE_TOP;
19138                    break;
19139            }
19140        }
19141
19142        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19143            if (app.hasClientActivities) {
19144                // This is a cached process, but with client activities.  Mark it so.
19145                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19146                app.adjType = "cch-client-act";
19147            } else if (app.treatLikeActivity) {
19148                // This is a cached process, but somebody wants us to treat it like it has
19149                // an activity, okay!
19150                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19151                app.adjType = "cch-as-act";
19152            }
19153        }
19154
19155        if (adj == ProcessList.SERVICE_ADJ) {
19156            if (doingAll) {
19157                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19158                mNewNumServiceProcs++;
19159                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19160                if (!app.serviceb) {
19161                    // This service isn't far enough down on the LRU list to
19162                    // normally be a B service, but if we are low on RAM and it
19163                    // is large we want to force it down since we would prefer to
19164                    // keep launcher over it.
19165                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19166                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19167                        app.serviceHighRam = true;
19168                        app.serviceb = true;
19169                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19170                    } else {
19171                        mNewNumAServiceProcs++;
19172                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19173                    }
19174                } else {
19175                    app.serviceHighRam = false;
19176                }
19177            }
19178            if (app.serviceb) {
19179                adj = ProcessList.SERVICE_B_ADJ;
19180            }
19181        }
19182
19183        app.curRawAdj = adj;
19184
19185        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19186        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19187        if (adj > app.maxAdj) {
19188            adj = app.maxAdj;
19189            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19190                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19191            }
19192        }
19193
19194        // Do final modification to adj.  Everything we do between here and applying
19195        // the final setAdj must be done in this function, because we will also use
19196        // it when computing the final cached adj later.  Note that we don't need to
19197        // worry about this for max adj above, since max adj will always be used to
19198        // keep it out of the cached vaues.
19199        app.curAdj = app.modifyRawOomAdj(adj);
19200        app.curSchedGroup = schedGroup;
19201        app.curProcState = procState;
19202        app.foregroundActivities = foregroundActivities;
19203
19204        return app.curRawAdj;
19205    }
19206
19207    /**
19208     * Record new PSS sample for a process.
19209     */
19210    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19211            long now) {
19212        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19213                swapPss * 1024);
19214        proc.lastPssTime = now;
19215        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19216        if (DEBUG_PSS) Slog.d(TAG_PSS,
19217                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19218                + " state=" + ProcessList.makeProcStateString(procState));
19219        if (proc.initialIdlePss == 0) {
19220            proc.initialIdlePss = pss;
19221        }
19222        proc.lastPss = pss;
19223        proc.lastSwapPss = swapPss;
19224        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19225            proc.lastCachedPss = pss;
19226            proc.lastCachedSwapPss = swapPss;
19227        }
19228
19229        final SparseArray<Pair<Long, String>> watchUids
19230                = mMemWatchProcesses.getMap().get(proc.processName);
19231        Long check = null;
19232        if (watchUids != null) {
19233            Pair<Long, String> val = watchUids.get(proc.uid);
19234            if (val == null) {
19235                val = watchUids.get(0);
19236            }
19237            if (val != null) {
19238                check = val.first;
19239            }
19240        }
19241        if (check != null) {
19242            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19243                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19244                if (!isDebuggable) {
19245                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19246                        isDebuggable = true;
19247                    }
19248                }
19249                if (isDebuggable) {
19250                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19251                    final ProcessRecord myProc = proc;
19252                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19253                    mMemWatchDumpProcName = proc.processName;
19254                    mMemWatchDumpFile = heapdumpFile.toString();
19255                    mMemWatchDumpPid = proc.pid;
19256                    mMemWatchDumpUid = proc.uid;
19257                    BackgroundThread.getHandler().post(new Runnable() {
19258                        @Override
19259                        public void run() {
19260                            revokeUriPermission(ActivityThread.currentActivityThread()
19261                                            .getApplicationThread(),
19262                                    DumpHeapActivity.JAVA_URI,
19263                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19264                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19265                                    UserHandle.myUserId());
19266                            ParcelFileDescriptor fd = null;
19267                            try {
19268                                heapdumpFile.delete();
19269                                fd = ParcelFileDescriptor.open(heapdumpFile,
19270                                        ParcelFileDescriptor.MODE_CREATE |
19271                                                ParcelFileDescriptor.MODE_TRUNCATE |
19272                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19273                                                ParcelFileDescriptor.MODE_APPEND);
19274                                IApplicationThread thread = myProc.thread;
19275                                if (thread != null) {
19276                                    try {
19277                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19278                                                "Requesting dump heap from "
19279                                                + myProc + " to " + heapdumpFile);
19280                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19281                                    } catch (RemoteException e) {
19282                                    }
19283                                }
19284                            } catch (FileNotFoundException e) {
19285                                e.printStackTrace();
19286                            } finally {
19287                                if (fd != null) {
19288                                    try {
19289                                        fd.close();
19290                                    } catch (IOException e) {
19291                                    }
19292                                }
19293                            }
19294                        }
19295                    });
19296                } else {
19297                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19298                            + ", but debugging not enabled");
19299                }
19300            }
19301        }
19302    }
19303
19304    /**
19305     * Schedule PSS collection of a process.
19306     */
19307    void requestPssLocked(ProcessRecord proc, int procState) {
19308        if (mPendingPssProcesses.contains(proc)) {
19309            return;
19310        }
19311        if (mPendingPssProcesses.size() == 0) {
19312            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19313        }
19314        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19315        proc.pssProcState = procState;
19316        mPendingPssProcesses.add(proc);
19317    }
19318
19319    /**
19320     * Schedule PSS collection of all processes.
19321     */
19322    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19323        if (!always) {
19324            if (now < (mLastFullPssTime +
19325                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19326                return;
19327            }
19328        }
19329        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19330        mLastFullPssTime = now;
19331        mFullPssPending = true;
19332        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19333        mPendingPssProcesses.clear();
19334        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19335            ProcessRecord app = mLruProcesses.get(i);
19336            if (app.thread == null
19337                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19338                continue;
19339            }
19340            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19341                app.pssProcState = app.setProcState;
19342                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19343                        mTestPssMode, isSleeping(), now);
19344                mPendingPssProcesses.add(app);
19345            }
19346        }
19347        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19348    }
19349
19350    public void setTestPssMode(boolean enabled) {
19351        synchronized (this) {
19352            mTestPssMode = enabled;
19353            if (enabled) {
19354                // Whenever we enable the mode, we want to take a snapshot all of current
19355                // process mem use.
19356                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19357            }
19358        }
19359    }
19360
19361    /**
19362     * Ask a given process to GC right now.
19363     */
19364    final void performAppGcLocked(ProcessRecord app) {
19365        try {
19366            app.lastRequestedGc = SystemClock.uptimeMillis();
19367            if (app.thread != null) {
19368                if (app.reportLowMemory) {
19369                    app.reportLowMemory = false;
19370                    app.thread.scheduleLowMemory();
19371                } else {
19372                    app.thread.processInBackground();
19373                }
19374            }
19375        } catch (Exception e) {
19376            // whatever.
19377        }
19378    }
19379
19380    /**
19381     * Returns true if things are idle enough to perform GCs.
19382     */
19383    private final boolean canGcNowLocked() {
19384        boolean processingBroadcasts = false;
19385        for (BroadcastQueue q : mBroadcastQueues) {
19386            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19387                processingBroadcasts = true;
19388            }
19389        }
19390        return !processingBroadcasts
19391                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19392    }
19393
19394    /**
19395     * Perform GCs on all processes that are waiting for it, but only
19396     * if things are idle.
19397     */
19398    final void performAppGcsLocked() {
19399        final int N = mProcessesToGc.size();
19400        if (N <= 0) {
19401            return;
19402        }
19403        if (canGcNowLocked()) {
19404            while (mProcessesToGc.size() > 0) {
19405                ProcessRecord proc = mProcessesToGc.remove(0);
19406                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19407                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19408                            <= SystemClock.uptimeMillis()) {
19409                        // To avoid spamming the system, we will GC processes one
19410                        // at a time, waiting a few seconds between each.
19411                        performAppGcLocked(proc);
19412                        scheduleAppGcsLocked();
19413                        return;
19414                    } else {
19415                        // It hasn't been long enough since we last GCed this
19416                        // process...  put it in the list to wait for its time.
19417                        addProcessToGcListLocked(proc);
19418                        break;
19419                    }
19420                }
19421            }
19422
19423            scheduleAppGcsLocked();
19424        }
19425    }
19426
19427    /**
19428     * If all looks good, perform GCs on all processes waiting for them.
19429     */
19430    final void performAppGcsIfAppropriateLocked() {
19431        if (canGcNowLocked()) {
19432            performAppGcsLocked();
19433            return;
19434        }
19435        // Still not idle, wait some more.
19436        scheduleAppGcsLocked();
19437    }
19438
19439    /**
19440     * Schedule the execution of all pending app GCs.
19441     */
19442    final void scheduleAppGcsLocked() {
19443        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19444
19445        if (mProcessesToGc.size() > 0) {
19446            // Schedule a GC for the time to the next process.
19447            ProcessRecord proc = mProcessesToGc.get(0);
19448            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19449
19450            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19451            long now = SystemClock.uptimeMillis();
19452            if (when < (now+GC_TIMEOUT)) {
19453                when = now + GC_TIMEOUT;
19454            }
19455            mHandler.sendMessageAtTime(msg, when);
19456        }
19457    }
19458
19459    /**
19460     * Add a process to the array of processes waiting to be GCed.  Keeps the
19461     * list in sorted order by the last GC time.  The process can't already be
19462     * on the list.
19463     */
19464    final void addProcessToGcListLocked(ProcessRecord proc) {
19465        boolean added = false;
19466        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19467            if (mProcessesToGc.get(i).lastRequestedGc <
19468                    proc.lastRequestedGc) {
19469                added = true;
19470                mProcessesToGc.add(i+1, proc);
19471                break;
19472            }
19473        }
19474        if (!added) {
19475            mProcessesToGc.add(0, proc);
19476        }
19477    }
19478
19479    /**
19480     * Set up to ask a process to GC itself.  This will either do it
19481     * immediately, or put it on the list of processes to gc the next
19482     * time things are idle.
19483     */
19484    final void scheduleAppGcLocked(ProcessRecord app) {
19485        long now = SystemClock.uptimeMillis();
19486        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19487            return;
19488        }
19489        if (!mProcessesToGc.contains(app)) {
19490            addProcessToGcListLocked(app);
19491            scheduleAppGcsLocked();
19492        }
19493    }
19494
19495    final void checkExcessivePowerUsageLocked(boolean doKills) {
19496        updateCpuStatsNow();
19497
19498        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19499        boolean doWakeKills = doKills;
19500        boolean doCpuKills = doKills;
19501        if (mLastPowerCheckRealtime == 0) {
19502            doWakeKills = false;
19503        }
19504        if (mLastPowerCheckUptime == 0) {
19505            doCpuKills = false;
19506        }
19507        if (stats.isScreenOn()) {
19508            doWakeKills = false;
19509        }
19510        final long curRealtime = SystemClock.elapsedRealtime();
19511        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19512        final long curUptime = SystemClock.uptimeMillis();
19513        final long uptimeSince = curUptime - mLastPowerCheckUptime;
19514        mLastPowerCheckRealtime = curRealtime;
19515        mLastPowerCheckUptime = curUptime;
19516        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19517            doWakeKills = false;
19518        }
19519        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19520            doCpuKills = false;
19521        }
19522        int i = mLruProcesses.size();
19523        while (i > 0) {
19524            i--;
19525            ProcessRecord app = mLruProcesses.get(i);
19526            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19527                long wtime;
19528                synchronized (stats) {
19529                    wtime = stats.getProcessWakeTime(app.info.uid,
19530                            app.pid, curRealtime);
19531                }
19532                long wtimeUsed = wtime - app.lastWakeTime;
19533                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19534                if (DEBUG_POWER) {
19535                    StringBuilder sb = new StringBuilder(128);
19536                    sb.append("Wake for ");
19537                    app.toShortString(sb);
19538                    sb.append(": over ");
19539                    TimeUtils.formatDuration(realtimeSince, sb);
19540                    sb.append(" used ");
19541                    TimeUtils.formatDuration(wtimeUsed, sb);
19542                    sb.append(" (");
19543                    sb.append((wtimeUsed*100)/realtimeSince);
19544                    sb.append("%)");
19545                    Slog.i(TAG_POWER, sb.toString());
19546                    sb.setLength(0);
19547                    sb.append("CPU for ");
19548                    app.toShortString(sb);
19549                    sb.append(": over ");
19550                    TimeUtils.formatDuration(uptimeSince, sb);
19551                    sb.append(" used ");
19552                    TimeUtils.formatDuration(cputimeUsed, sb);
19553                    sb.append(" (");
19554                    sb.append((cputimeUsed*100)/uptimeSince);
19555                    sb.append("%)");
19556                    Slog.i(TAG_POWER, sb.toString());
19557                }
19558                // If a process has held a wake lock for more
19559                // than 50% of the time during this period,
19560                // that sounds bad.  Kill!
19561                if (doWakeKills && realtimeSince > 0
19562                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
19563                    synchronized (stats) {
19564                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19565                                realtimeSince, wtimeUsed);
19566                    }
19567                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19568                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19569                } else if (doCpuKills && uptimeSince > 0
19570                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
19571                    synchronized (stats) {
19572                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19573                                uptimeSince, cputimeUsed);
19574                    }
19575                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19576                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19577                } else {
19578                    app.lastWakeTime = wtime;
19579                    app.lastCpuTime = app.curCpuTime;
19580                }
19581            }
19582        }
19583    }
19584
19585    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19586            long nowElapsed) {
19587        boolean success = true;
19588
19589        if (app.curRawAdj != app.setRawAdj) {
19590            app.setRawAdj = app.curRawAdj;
19591        }
19592
19593        int changes = 0;
19594
19595        if (app.curAdj != app.setAdj) {
19596            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19597            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19598                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19599                    + app.adjType);
19600            app.setAdj = app.curAdj;
19601        }
19602
19603        if (app.setSchedGroup != app.curSchedGroup) {
19604            app.setSchedGroup = app.curSchedGroup;
19605            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19606                    "Setting sched group of " + app.processName
19607                    + " to " + app.curSchedGroup);
19608            if (app.waitingToKill != null && app.curReceiver == null
19609                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19610                app.kill(app.waitingToKill, true);
19611                success = false;
19612            } else {
19613                int processGroup;
19614                switch (app.curSchedGroup) {
19615                    case ProcessList.SCHED_GROUP_BACKGROUND:
19616                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19617                        break;
19618                    case ProcessList.SCHED_GROUP_TOP_APP:
19619                        processGroup = Process.THREAD_GROUP_TOP_APP;
19620                        break;
19621                    default:
19622                        processGroup = Process.THREAD_GROUP_DEFAULT;
19623                        break;
19624                }
19625                if (true) {
19626                    long oldId = Binder.clearCallingIdentity();
19627                    try {
19628                        Process.setProcessGroup(app.pid, processGroup);
19629                    } catch (Exception e) {
19630                        Slog.w(TAG, "Failed setting process group of " + app.pid
19631                                + " to " + app.curSchedGroup);
19632                        e.printStackTrace();
19633                    } finally {
19634                        Binder.restoreCallingIdentity(oldId);
19635                    }
19636                } else {
19637                    if (app.thread != null) {
19638                        try {
19639                            app.thread.setSchedulingGroup(processGroup);
19640                        } catch (RemoteException e) {
19641                        }
19642                    }
19643                }
19644            }
19645        }
19646        if (app.repForegroundActivities != app.foregroundActivities) {
19647            app.repForegroundActivities = app.foregroundActivities;
19648            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19649        }
19650        if (app.repProcState != app.curProcState) {
19651            app.repProcState = app.curProcState;
19652            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19653            if (app.thread != null) {
19654                try {
19655                    if (false) {
19656                        //RuntimeException h = new RuntimeException("here");
19657                        Slog.i(TAG, "Sending new process state " + app.repProcState
19658                                + " to " + app /*, h*/);
19659                    }
19660                    app.thread.setProcessState(app.repProcState);
19661                } catch (RemoteException e) {
19662                }
19663            }
19664        }
19665        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19666                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19667            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19668                // Experimental code to more aggressively collect pss while
19669                // running test...  the problem is that this tends to collect
19670                // the data right when a process is transitioning between process
19671                // states, which well tend to give noisy data.
19672                long start = SystemClock.uptimeMillis();
19673                long pss = Debug.getPss(app.pid, mTmpLong, null);
19674                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19675                mPendingPssProcesses.remove(app);
19676                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19677                        + " to " + app.curProcState + ": "
19678                        + (SystemClock.uptimeMillis()-start) + "ms");
19679            }
19680            app.lastStateTime = now;
19681            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19682                    mTestPssMode, isSleeping(), now);
19683            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19684                    + ProcessList.makeProcStateString(app.setProcState) + " to "
19685                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19686                    + (app.nextPssTime-now) + ": " + app);
19687        } else {
19688            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19689                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19690                    mTestPssMode)))) {
19691                requestPssLocked(app, app.setProcState);
19692                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19693                        mTestPssMode, isSleeping(), now);
19694            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19695                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19696        }
19697        if (app.setProcState != app.curProcState) {
19698            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19699                    "Proc state change of " + app.processName
19700                            + " to " + app.curProcState);
19701            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19702            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19703            if (setImportant && !curImportant) {
19704                // This app is no longer something we consider important enough to allow to
19705                // use arbitrary amounts of battery power.  Note
19706                // its current wake lock time to later know to kill it if
19707                // it is not behaving well.
19708                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19709                synchronized (stats) {
19710                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19711                            app.pid, nowElapsed);
19712                }
19713                app.lastCpuTime = app.curCpuTime;
19714
19715            }
19716            // Inform UsageStats of important process state change
19717            // Must be called before updating setProcState
19718            maybeUpdateUsageStatsLocked(app, nowElapsed);
19719
19720            app.setProcState = app.curProcState;
19721            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19722                app.notCachedSinceIdle = false;
19723            }
19724            if (!doingAll) {
19725                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19726            } else {
19727                app.procStateChanged = true;
19728            }
19729        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19730                > USAGE_STATS_INTERACTION_INTERVAL) {
19731            // For apps that sit around for a long time in the interactive state, we need
19732            // to report this at least once a day so they don't go idle.
19733            maybeUpdateUsageStatsLocked(app, nowElapsed);
19734        }
19735
19736        if (changes != 0) {
19737            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19738                    "Changes in " + app + ": " + changes);
19739            int i = mPendingProcessChanges.size()-1;
19740            ProcessChangeItem item = null;
19741            while (i >= 0) {
19742                item = mPendingProcessChanges.get(i);
19743                if (item.pid == app.pid) {
19744                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19745                            "Re-using existing item: " + item);
19746                    break;
19747                }
19748                i--;
19749            }
19750            if (i < 0) {
19751                // No existing item in pending changes; need a new one.
19752                final int NA = mAvailProcessChanges.size();
19753                if (NA > 0) {
19754                    item = mAvailProcessChanges.remove(NA-1);
19755                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19756                            "Retrieving available item: " + item);
19757                } else {
19758                    item = new ProcessChangeItem();
19759                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19760                            "Allocating new item: " + item);
19761                }
19762                item.changes = 0;
19763                item.pid = app.pid;
19764                item.uid = app.info.uid;
19765                if (mPendingProcessChanges.size() == 0) {
19766                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19767                            "*** Enqueueing dispatch processes changed!");
19768                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19769                }
19770                mPendingProcessChanges.add(item);
19771            }
19772            item.changes |= changes;
19773            item.processState = app.repProcState;
19774            item.foregroundActivities = app.repForegroundActivities;
19775            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19776                    "Item " + Integer.toHexString(System.identityHashCode(item))
19777                    + " " + app.toShortString() + ": changes=" + item.changes
19778                    + " procState=" + item.processState
19779                    + " foreground=" + item.foregroundActivities
19780                    + " type=" + app.adjType + " source=" + app.adjSource
19781                    + " target=" + app.adjTarget);
19782        }
19783
19784        return success;
19785    }
19786
19787    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19788        final UidRecord.ChangeItem pendingChange;
19789        if (uidRec == null || uidRec.pendingChange == null) {
19790            if (mPendingUidChanges.size() == 0) {
19791                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19792                        "*** Enqueueing dispatch uid changed!");
19793                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19794            }
19795            final int NA = mAvailUidChanges.size();
19796            if (NA > 0) {
19797                pendingChange = mAvailUidChanges.remove(NA-1);
19798                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19799                        "Retrieving available item: " + pendingChange);
19800            } else {
19801                pendingChange = new UidRecord.ChangeItem();
19802                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19803                        "Allocating new item: " + pendingChange);
19804            }
19805            if (uidRec != null) {
19806                uidRec.pendingChange = pendingChange;
19807                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19808                    // If this uid is going away, and we haven't yet reported it is gone,
19809                    // then do so now.
19810                    change = UidRecord.CHANGE_GONE_IDLE;
19811                }
19812            } else if (uid < 0) {
19813                throw new IllegalArgumentException("No UidRecord or uid");
19814            }
19815            pendingChange.uidRecord = uidRec;
19816            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19817            mPendingUidChanges.add(pendingChange);
19818        } else {
19819            pendingChange = uidRec.pendingChange;
19820            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19821                change = UidRecord.CHANGE_GONE_IDLE;
19822            }
19823        }
19824        pendingChange.change = change;
19825        pendingChange.processState = uidRec != null
19826                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19827    }
19828
19829    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19830            String authority) {
19831        if (app == null) return;
19832        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19833            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19834            if (userState == null) return;
19835            final long now = SystemClock.elapsedRealtime();
19836            Long lastReported = userState.mProviderLastReportedFg.get(authority);
19837            if (lastReported == null || lastReported < now - 60 * 1000L) {
19838                mUsageStatsService.reportContentProviderUsage(
19839                        authority, providerPkgName, app.userId);
19840                userState.mProviderLastReportedFg.put(authority, now);
19841            }
19842        }
19843    }
19844
19845    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19846        if (DEBUG_USAGE_STATS) {
19847            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19848                    + "] state changes: old = " + app.setProcState + ", new = "
19849                    + app.curProcState);
19850        }
19851        if (mUsageStatsService == null) {
19852            return;
19853        }
19854        boolean isInteraction;
19855        // To avoid some abuse patterns, we are going to be careful about what we consider
19856        // to be an app interaction.  Being the top activity doesn't count while the display
19857        // is sleeping, nor do short foreground services.
19858        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19859            isInteraction = true;
19860            app.fgInteractionTime = 0;
19861        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19862            if (app.fgInteractionTime == 0) {
19863                app.fgInteractionTime = nowElapsed;
19864                isInteraction = false;
19865            } else {
19866                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19867            }
19868        } else {
19869            isInteraction = app.curProcState
19870                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19871            app.fgInteractionTime = 0;
19872        }
19873        if (isInteraction && (!app.reportedInteraction
19874                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19875            app.interactionEventTime = nowElapsed;
19876            String[] packages = app.getPackageList();
19877            if (packages != null) {
19878                for (int i = 0; i < packages.length; i++) {
19879                    mUsageStatsService.reportEvent(packages[i], app.userId,
19880                            UsageEvents.Event.SYSTEM_INTERACTION);
19881                }
19882            }
19883        }
19884        app.reportedInteraction = isInteraction;
19885        if (!isInteraction) {
19886            app.interactionEventTime = 0;
19887        }
19888    }
19889
19890    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19891        if (proc.thread != null) {
19892            if (proc.baseProcessTracker != null) {
19893                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19894            }
19895        }
19896    }
19897
19898    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19899            ProcessRecord TOP_APP, boolean doingAll, long now) {
19900        if (app.thread == null) {
19901            return false;
19902        }
19903
19904        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19905
19906        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19907    }
19908
19909    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19910            boolean oomAdj) {
19911        if (isForeground != proc.foregroundServices) {
19912            proc.foregroundServices = isForeground;
19913            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19914                    proc.info.uid);
19915            if (isForeground) {
19916                if (curProcs == null) {
19917                    curProcs = new ArrayList<ProcessRecord>();
19918                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19919                }
19920                if (!curProcs.contains(proc)) {
19921                    curProcs.add(proc);
19922                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19923                            proc.info.packageName, proc.info.uid);
19924                }
19925            } else {
19926                if (curProcs != null) {
19927                    if (curProcs.remove(proc)) {
19928                        mBatteryStatsService.noteEvent(
19929                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19930                                proc.info.packageName, proc.info.uid);
19931                        if (curProcs.size() <= 0) {
19932                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19933                        }
19934                    }
19935                }
19936            }
19937            if (oomAdj) {
19938                updateOomAdjLocked();
19939            }
19940        }
19941    }
19942
19943    private final ActivityRecord resumedAppLocked() {
19944        ActivityRecord act = mStackSupervisor.resumedAppLocked();
19945        String pkg;
19946        int uid;
19947        if (act != null) {
19948            pkg = act.packageName;
19949            uid = act.info.applicationInfo.uid;
19950        } else {
19951            pkg = null;
19952            uid = -1;
19953        }
19954        // Has the UID or resumed package name changed?
19955        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19956                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19957            if (mCurResumedPackage != null) {
19958                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19959                        mCurResumedPackage, mCurResumedUid);
19960            }
19961            mCurResumedPackage = pkg;
19962            mCurResumedUid = uid;
19963            if (mCurResumedPackage != null) {
19964                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19965                        mCurResumedPackage, mCurResumedUid);
19966            }
19967        }
19968        return act;
19969    }
19970
19971    final boolean updateOomAdjLocked(ProcessRecord app) {
19972        final ActivityRecord TOP_ACT = resumedAppLocked();
19973        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19974        final boolean wasCached = app.cached;
19975
19976        mAdjSeq++;
19977
19978        // This is the desired cached adjusment we want to tell it to use.
19979        // If our app is currently cached, we know it, and that is it.  Otherwise,
19980        // we don't know it yet, and it needs to now be cached we will then
19981        // need to do a complete oom adj.
19982        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19983                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19984        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19985                SystemClock.uptimeMillis());
19986        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19987            // Changed to/from cached state, so apps after it in the LRU
19988            // list may also be changed.
19989            updateOomAdjLocked();
19990        }
19991        return success;
19992    }
19993
19994    final void updateOomAdjLocked() {
19995        final ActivityRecord TOP_ACT = resumedAppLocked();
19996        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19997        final long now = SystemClock.uptimeMillis();
19998        final long nowElapsed = SystemClock.elapsedRealtime();
19999        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20000        final int N = mLruProcesses.size();
20001
20002        if (false) {
20003            RuntimeException e = new RuntimeException();
20004            e.fillInStackTrace();
20005            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20006        }
20007
20008        // Reset state in all uid records.
20009        for (int i=mActiveUids.size()-1; i>=0; i--) {
20010            final UidRecord uidRec = mActiveUids.valueAt(i);
20011            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20012                    "Starting update of " + uidRec);
20013            uidRec.reset();
20014        }
20015
20016        mStackSupervisor.rankTaskLayersIfNeeded();
20017
20018        mAdjSeq++;
20019        mNewNumServiceProcs = 0;
20020        mNewNumAServiceProcs = 0;
20021
20022        final int emptyProcessLimit;
20023        final int cachedProcessLimit;
20024        if (mProcessLimit <= 0) {
20025            emptyProcessLimit = cachedProcessLimit = 0;
20026        } else if (mProcessLimit == 1) {
20027            emptyProcessLimit = 1;
20028            cachedProcessLimit = 0;
20029        } else {
20030            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20031            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20032        }
20033
20034        // Let's determine how many processes we have running vs.
20035        // how many slots we have for background processes; we may want
20036        // to put multiple processes in a slot of there are enough of
20037        // them.
20038        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20039                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20040        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20041        if (numEmptyProcs > cachedProcessLimit) {
20042            // If there are more empty processes than our limit on cached
20043            // processes, then use the cached process limit for the factor.
20044            // This ensures that the really old empty processes get pushed
20045            // down to the bottom, so if we are running low on memory we will
20046            // have a better chance at keeping around more cached processes
20047            // instead of a gazillion empty processes.
20048            numEmptyProcs = cachedProcessLimit;
20049        }
20050        int emptyFactor = numEmptyProcs/numSlots;
20051        if (emptyFactor < 1) emptyFactor = 1;
20052        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20053        if (cachedFactor < 1) cachedFactor = 1;
20054        int stepCached = 0;
20055        int stepEmpty = 0;
20056        int numCached = 0;
20057        int numEmpty = 0;
20058        int numTrimming = 0;
20059
20060        mNumNonCachedProcs = 0;
20061        mNumCachedHiddenProcs = 0;
20062
20063        // First update the OOM adjustment for each of the
20064        // application processes based on their current state.
20065        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20066        int nextCachedAdj = curCachedAdj+1;
20067        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20068        int nextEmptyAdj = curEmptyAdj+2;
20069        for (int i=N-1; i>=0; i--) {
20070            ProcessRecord app = mLruProcesses.get(i);
20071            if (!app.killedByAm && app.thread != null) {
20072                app.procStateChanged = false;
20073                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20074
20075                // If we haven't yet assigned the final cached adj
20076                // to the process, do that now.
20077                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20078                    switch (app.curProcState) {
20079                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20080                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20081                            // This process is a cached process holding activities...
20082                            // assign it the next cached value for that type, and then
20083                            // step that cached level.
20084                            app.curRawAdj = curCachedAdj;
20085                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20086                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20087                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20088                                    + ")");
20089                            if (curCachedAdj != nextCachedAdj) {
20090                                stepCached++;
20091                                if (stepCached >= cachedFactor) {
20092                                    stepCached = 0;
20093                                    curCachedAdj = nextCachedAdj;
20094                                    nextCachedAdj += 2;
20095                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20096                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20097                                    }
20098                                }
20099                            }
20100                            break;
20101                        default:
20102                            // For everything else, assign next empty cached process
20103                            // level and bump that up.  Note that this means that
20104                            // long-running services that have dropped down to the
20105                            // cached level will be treated as empty (since their process
20106                            // state is still as a service), which is what we want.
20107                            app.curRawAdj = curEmptyAdj;
20108                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20109                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20110                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20111                                    + ")");
20112                            if (curEmptyAdj != nextEmptyAdj) {
20113                                stepEmpty++;
20114                                if (stepEmpty >= emptyFactor) {
20115                                    stepEmpty = 0;
20116                                    curEmptyAdj = nextEmptyAdj;
20117                                    nextEmptyAdj += 2;
20118                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20119                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20120                                    }
20121                                }
20122                            }
20123                            break;
20124                    }
20125                }
20126
20127                applyOomAdjLocked(app, true, now, nowElapsed);
20128
20129                // Count the number of process types.
20130                switch (app.curProcState) {
20131                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20132                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20133                        mNumCachedHiddenProcs++;
20134                        numCached++;
20135                        if (numCached > cachedProcessLimit) {
20136                            app.kill("cached #" + numCached, true);
20137                        }
20138                        break;
20139                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20140                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20141                                && app.lastActivityTime < oldTime) {
20142                            app.kill("empty for "
20143                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20144                                    / 1000) + "s", true);
20145                        } else {
20146                            numEmpty++;
20147                            if (numEmpty > emptyProcessLimit) {
20148                                app.kill("empty #" + numEmpty, true);
20149                            }
20150                        }
20151                        break;
20152                    default:
20153                        mNumNonCachedProcs++;
20154                        break;
20155                }
20156
20157                if (app.isolated && app.services.size() <= 0) {
20158                    // If this is an isolated process, and there are no
20159                    // services running in it, then the process is no longer
20160                    // needed.  We agressively kill these because we can by
20161                    // definition not re-use the same process again, and it is
20162                    // good to avoid having whatever code was running in them
20163                    // left sitting around after no longer needed.
20164                    app.kill("isolated not needed", true);
20165                } else {
20166                    // Keeping this process, update its uid.
20167                    final UidRecord uidRec = app.uidRecord;
20168                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20169                        uidRec.curProcState = app.curProcState;
20170                    }
20171                }
20172
20173                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20174                        && !app.killedByAm) {
20175                    numTrimming++;
20176                }
20177            }
20178        }
20179
20180        mNumServiceProcs = mNewNumServiceProcs;
20181
20182        // Now determine the memory trimming level of background processes.
20183        // Unfortunately we need to start at the back of the list to do this
20184        // properly.  We only do this if the number of background apps we
20185        // are managing to keep around is less than half the maximum we desire;
20186        // if we are keeping a good number around, we'll let them use whatever
20187        // memory they want.
20188        final int numCachedAndEmpty = numCached + numEmpty;
20189        int memFactor;
20190        if (numCached <= ProcessList.TRIM_CACHED_APPS
20191                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20192            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20193                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20194            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20195                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20196            } else {
20197                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20198            }
20199        } else {
20200            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20201        }
20202        // We always allow the memory level to go up (better).  We only allow it to go
20203        // down if we are in a state where that is allowed, *and* the total number of processes
20204        // has gone down since last time.
20205        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20206                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20207                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20208        if (memFactor > mLastMemoryLevel) {
20209            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20210                memFactor = mLastMemoryLevel;
20211                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20212            }
20213        }
20214        if (memFactor != mLastMemoryLevel) {
20215            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20216        }
20217        mLastMemoryLevel = memFactor;
20218        mLastNumProcesses = mLruProcesses.size();
20219        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20220        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20221        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20222            if (mLowRamStartTime == 0) {
20223                mLowRamStartTime = now;
20224            }
20225            int step = 0;
20226            int fgTrimLevel;
20227            switch (memFactor) {
20228                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20229                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20230                    break;
20231                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20232                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20233                    break;
20234                default:
20235                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20236                    break;
20237            }
20238            int factor = numTrimming/3;
20239            int minFactor = 2;
20240            if (mHomeProcess != null) minFactor++;
20241            if (mPreviousProcess != null) minFactor++;
20242            if (factor < minFactor) factor = minFactor;
20243            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20244            for (int i=N-1; i>=0; i--) {
20245                ProcessRecord app = mLruProcesses.get(i);
20246                if (allChanged || app.procStateChanged) {
20247                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20248                    app.procStateChanged = false;
20249                }
20250                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20251                        && !app.killedByAm) {
20252                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20253                        try {
20254                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20255                                    "Trimming memory of " + app.processName + " to " + curLevel);
20256                            app.thread.scheduleTrimMemory(curLevel);
20257                        } catch (RemoteException e) {
20258                        }
20259                        if (false) {
20260                            // For now we won't do this; our memory trimming seems
20261                            // to be good enough at this point that destroying
20262                            // activities causes more harm than good.
20263                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20264                                    && app != mHomeProcess && app != mPreviousProcess) {
20265                                // Need to do this on its own message because the stack may not
20266                                // be in a consistent state at this point.
20267                                // For these apps we will also finish their activities
20268                                // to help them free memory.
20269                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20270                            }
20271                        }
20272                    }
20273                    app.trimMemoryLevel = curLevel;
20274                    step++;
20275                    if (step >= factor) {
20276                        step = 0;
20277                        switch (curLevel) {
20278                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20279                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20280                                break;
20281                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20282                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20283                                break;
20284                        }
20285                    }
20286                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20287                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20288                            && app.thread != null) {
20289                        try {
20290                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20291                                    "Trimming memory of heavy-weight " + app.processName
20292                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20293                            app.thread.scheduleTrimMemory(
20294                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20295                        } catch (RemoteException e) {
20296                        }
20297                    }
20298                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20299                } else {
20300                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20301                            || app.systemNoUi) && app.pendingUiClean) {
20302                        // If this application is now in the background and it
20303                        // had done UI, then give it the special trim level to
20304                        // have it free UI resources.
20305                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20306                        if (app.trimMemoryLevel < level && app.thread != null) {
20307                            try {
20308                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20309                                        "Trimming memory of bg-ui " + app.processName
20310                                        + " to " + level);
20311                                app.thread.scheduleTrimMemory(level);
20312                            } catch (RemoteException e) {
20313                            }
20314                        }
20315                        app.pendingUiClean = false;
20316                    }
20317                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20318                        try {
20319                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20320                                    "Trimming memory of fg " + app.processName
20321                                    + " to " + fgTrimLevel);
20322                            app.thread.scheduleTrimMemory(fgTrimLevel);
20323                        } catch (RemoteException e) {
20324                        }
20325                    }
20326                    app.trimMemoryLevel = fgTrimLevel;
20327                }
20328            }
20329        } else {
20330            if (mLowRamStartTime != 0) {
20331                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20332                mLowRamStartTime = 0;
20333            }
20334            for (int i=N-1; i>=0; i--) {
20335                ProcessRecord app = mLruProcesses.get(i);
20336                if (allChanged || app.procStateChanged) {
20337                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20338                    app.procStateChanged = false;
20339                }
20340                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20341                        || app.systemNoUi) && app.pendingUiClean) {
20342                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20343                            && app.thread != null) {
20344                        try {
20345                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20346                                    "Trimming memory of ui hidden " + app.processName
20347                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20348                            app.thread.scheduleTrimMemory(
20349                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20350                        } catch (RemoteException e) {
20351                        }
20352                    }
20353                    app.pendingUiClean = false;
20354                }
20355                app.trimMemoryLevel = 0;
20356            }
20357        }
20358
20359        if (mAlwaysFinishActivities) {
20360            // Need to do this on its own message because the stack may not
20361            // be in a consistent state at this point.
20362            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20363        }
20364
20365        if (allChanged) {
20366            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20367        }
20368
20369        // Update from any uid changes.
20370        for (int i=mActiveUids.size()-1; i>=0; i--) {
20371            final UidRecord uidRec = mActiveUids.valueAt(i);
20372            int uidChange = UidRecord.CHANGE_PROCSTATE;
20373            if (uidRec.setProcState != uidRec.curProcState) {
20374                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20375                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20376                        + " to " + uidRec.curProcState);
20377                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20378                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20379                        uidRec.lastBackgroundTime = nowElapsed;
20380                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20381                            // Note: the background settle time is in elapsed realtime, while
20382                            // the handler time base is uptime.  All this means is that we may
20383                            // stop background uids later than we had intended, but that only
20384                            // happens because the device was sleeping so we are okay anyway.
20385                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20386                        }
20387                    }
20388                } else {
20389                    if (uidRec.idle) {
20390                        uidChange = UidRecord.CHANGE_ACTIVE;
20391                        uidRec.idle = false;
20392                    }
20393                    uidRec.lastBackgroundTime = 0;
20394                }
20395                uidRec.setProcState = uidRec.curProcState;
20396                enqueueUidChangeLocked(uidRec, -1, uidChange);
20397                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20398            }
20399        }
20400
20401        if (mProcessStats.shouldWriteNowLocked(now)) {
20402            mHandler.post(new Runnable() {
20403                @Override public void run() {
20404                    synchronized (ActivityManagerService.this) {
20405                        mProcessStats.writeStateAsyncLocked();
20406                    }
20407                }
20408            });
20409        }
20410
20411        if (DEBUG_OOM_ADJ) {
20412            final long duration = SystemClock.uptimeMillis() - now;
20413            if (false) {
20414                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20415                        new RuntimeException("here").fillInStackTrace());
20416            } else {
20417                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20418            }
20419        }
20420    }
20421
20422    final void idleUids() {
20423        synchronized (this) {
20424            final long nowElapsed = SystemClock.elapsedRealtime();
20425            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20426            long nextTime = 0;
20427            for (int i=mActiveUids.size()-1; i>=0; i--) {
20428                final UidRecord uidRec = mActiveUids.valueAt(i);
20429                final long bgTime = uidRec.lastBackgroundTime;
20430                if (bgTime > 0 && !uidRec.idle) {
20431                    if (bgTime <= maxBgTime) {
20432                        uidRec.idle = true;
20433                        doStopUidLocked(uidRec.uid, uidRec);
20434                    } else {
20435                        if (nextTime == 0 || nextTime > bgTime) {
20436                            nextTime = bgTime;
20437                        }
20438                    }
20439                }
20440            }
20441            if (nextTime > 0) {
20442                mHandler.removeMessages(IDLE_UIDS_MSG);
20443                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20444                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20445            }
20446        }
20447    }
20448
20449    final void runInBackgroundDisabled(int uid) {
20450        synchronized (this) {
20451            UidRecord uidRec = mActiveUids.get(uid);
20452            if (uidRec != null) {
20453                // This uid is actually running...  should it be considered background now?
20454                if (uidRec.idle) {
20455                    doStopUidLocked(uidRec.uid, uidRec);
20456                }
20457            } else {
20458                // This uid isn't actually running...  still send a report about it being "stopped".
20459                doStopUidLocked(uid, null);
20460            }
20461        }
20462    }
20463
20464    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20465        mServices.stopInBackgroundLocked(uid);
20466        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20467    }
20468
20469    final void trimApplications() {
20470        synchronized (this) {
20471            int i;
20472
20473            // First remove any unused application processes whose package
20474            // has been removed.
20475            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20476                final ProcessRecord app = mRemovedProcesses.get(i);
20477                if (app.activities.size() == 0
20478                        && app.curReceiver == null && app.services.size() == 0) {
20479                    Slog.i(
20480                        TAG, "Exiting empty application process "
20481                        + app.toShortString() + " ("
20482                        + (app.thread != null ? app.thread.asBinder() : null)
20483                        + ")\n");
20484                    if (app.pid > 0 && app.pid != MY_PID) {
20485                        app.kill("empty", false);
20486                    } else {
20487                        try {
20488                            app.thread.scheduleExit();
20489                        } catch (Exception e) {
20490                            // Ignore exceptions.
20491                        }
20492                    }
20493                    cleanUpApplicationRecordLocked(app, false, true, -1);
20494                    mRemovedProcesses.remove(i);
20495
20496                    if (app.persistent) {
20497                        addAppLocked(app.info, false, null /* ABI override */);
20498                    }
20499                }
20500            }
20501
20502            // Now update the oom adj for all processes.
20503            updateOomAdjLocked();
20504        }
20505    }
20506
20507    /** This method sends the specified signal to each of the persistent apps */
20508    public void signalPersistentProcesses(int sig) throws RemoteException {
20509        if (sig != Process.SIGNAL_USR1) {
20510            throw new SecurityException("Only SIGNAL_USR1 is allowed");
20511        }
20512
20513        synchronized (this) {
20514            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20515                    != PackageManager.PERMISSION_GRANTED) {
20516                throw new SecurityException("Requires permission "
20517                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20518            }
20519
20520            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20521                ProcessRecord r = mLruProcesses.get(i);
20522                if (r.thread != null && r.persistent) {
20523                    Process.sendSignal(r.pid, sig);
20524                }
20525            }
20526        }
20527    }
20528
20529    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20530        if (proc == null || proc == mProfileProc) {
20531            proc = mProfileProc;
20532            profileType = mProfileType;
20533            clearProfilerLocked();
20534        }
20535        if (proc == null) {
20536            return;
20537        }
20538        try {
20539            proc.thread.profilerControl(false, null, profileType);
20540        } catch (RemoteException e) {
20541            throw new IllegalStateException("Process disappeared");
20542        }
20543    }
20544
20545    private void clearProfilerLocked() {
20546        if (mProfileFd != null) {
20547            try {
20548                mProfileFd.close();
20549            } catch (IOException e) {
20550            }
20551        }
20552        mProfileApp = null;
20553        mProfileProc = null;
20554        mProfileFile = null;
20555        mProfileType = 0;
20556        mAutoStopProfiler = false;
20557        mSamplingInterval = 0;
20558    }
20559
20560    public boolean profileControl(String process, int userId, boolean start,
20561            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20562
20563        try {
20564            synchronized (this) {
20565                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20566                // its own permission.
20567                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20568                        != PackageManager.PERMISSION_GRANTED) {
20569                    throw new SecurityException("Requires permission "
20570                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20571                }
20572
20573                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20574                    throw new IllegalArgumentException("null profile info or fd");
20575                }
20576
20577                ProcessRecord proc = null;
20578                if (process != null) {
20579                    proc = findProcessLocked(process, userId, "profileControl");
20580                }
20581
20582                if (start && (proc == null || proc.thread == null)) {
20583                    throw new IllegalArgumentException("Unknown process: " + process);
20584                }
20585
20586                if (start) {
20587                    stopProfilerLocked(null, 0);
20588                    setProfileApp(proc.info, proc.processName, profilerInfo);
20589                    mProfileProc = proc;
20590                    mProfileType = profileType;
20591                    ParcelFileDescriptor fd = profilerInfo.profileFd;
20592                    try {
20593                        fd = fd.dup();
20594                    } catch (IOException e) {
20595                        fd = null;
20596                    }
20597                    profilerInfo.profileFd = fd;
20598                    proc.thread.profilerControl(start, profilerInfo, profileType);
20599                    fd = null;
20600                    mProfileFd = null;
20601                } else {
20602                    stopProfilerLocked(proc, profileType);
20603                    if (profilerInfo != null && profilerInfo.profileFd != null) {
20604                        try {
20605                            profilerInfo.profileFd.close();
20606                        } catch (IOException e) {
20607                        }
20608                    }
20609                }
20610
20611                return true;
20612            }
20613        } catch (RemoteException e) {
20614            throw new IllegalStateException("Process disappeared");
20615        } finally {
20616            if (profilerInfo != null && profilerInfo.profileFd != null) {
20617                try {
20618                    profilerInfo.profileFd.close();
20619                } catch (IOException e) {
20620                }
20621            }
20622        }
20623    }
20624
20625    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20626        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20627                userId, true, ALLOW_FULL_ONLY, callName, null);
20628        ProcessRecord proc = null;
20629        try {
20630            int pid = Integer.parseInt(process);
20631            synchronized (mPidsSelfLocked) {
20632                proc = mPidsSelfLocked.get(pid);
20633            }
20634        } catch (NumberFormatException e) {
20635        }
20636
20637        if (proc == null) {
20638            ArrayMap<String, SparseArray<ProcessRecord>> all
20639                    = mProcessNames.getMap();
20640            SparseArray<ProcessRecord> procs = all.get(process);
20641            if (procs != null && procs.size() > 0) {
20642                proc = procs.valueAt(0);
20643                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20644                    for (int i=1; i<procs.size(); i++) {
20645                        ProcessRecord thisProc = procs.valueAt(i);
20646                        if (thisProc.userId == userId) {
20647                            proc = thisProc;
20648                            break;
20649                        }
20650                    }
20651                }
20652            }
20653        }
20654
20655        return proc;
20656    }
20657
20658    public boolean dumpHeap(String process, int userId, boolean managed,
20659            String path, ParcelFileDescriptor fd) throws RemoteException {
20660
20661        try {
20662            synchronized (this) {
20663                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20664                // its own permission (same as profileControl).
20665                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20666                        != PackageManager.PERMISSION_GRANTED) {
20667                    throw new SecurityException("Requires permission "
20668                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20669                }
20670
20671                if (fd == null) {
20672                    throw new IllegalArgumentException("null fd");
20673                }
20674
20675                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20676                if (proc == null || proc.thread == null) {
20677                    throw new IllegalArgumentException("Unknown process: " + process);
20678                }
20679
20680                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20681                if (!isDebuggable) {
20682                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20683                        throw new SecurityException("Process not debuggable: " + proc);
20684                    }
20685                }
20686
20687                proc.thread.dumpHeap(managed, path, fd);
20688                fd = null;
20689                return true;
20690            }
20691        } catch (RemoteException e) {
20692            throw new IllegalStateException("Process disappeared");
20693        } finally {
20694            if (fd != null) {
20695                try {
20696                    fd.close();
20697                } catch (IOException e) {
20698                }
20699            }
20700        }
20701    }
20702
20703    @Override
20704    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20705            String reportPackage) {
20706        if (processName != null) {
20707            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20708                    "setDumpHeapDebugLimit()");
20709        } else {
20710            synchronized (mPidsSelfLocked) {
20711                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20712                if (proc == null) {
20713                    throw new SecurityException("No process found for calling pid "
20714                            + Binder.getCallingPid());
20715                }
20716                if (!Build.IS_DEBUGGABLE
20717                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20718                    throw new SecurityException("Not running a debuggable build");
20719                }
20720                processName = proc.processName;
20721                uid = proc.uid;
20722                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20723                    throw new SecurityException("Package " + reportPackage + " is not running in "
20724                            + proc);
20725                }
20726            }
20727        }
20728        synchronized (this) {
20729            if (maxMemSize > 0) {
20730                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20731            } else {
20732                if (uid != 0) {
20733                    mMemWatchProcesses.remove(processName, uid);
20734                } else {
20735                    mMemWatchProcesses.getMap().remove(processName);
20736                }
20737            }
20738        }
20739    }
20740
20741    @Override
20742    public void dumpHeapFinished(String path) {
20743        synchronized (this) {
20744            if (Binder.getCallingPid() != mMemWatchDumpPid) {
20745                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20746                        + " does not match last pid " + mMemWatchDumpPid);
20747                return;
20748            }
20749            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20750                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20751                        + " does not match last path " + mMemWatchDumpFile);
20752                return;
20753            }
20754            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20755            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20756        }
20757    }
20758
20759    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20760    public void monitor() {
20761        synchronized (this) { }
20762    }
20763
20764    void onCoreSettingsChange(Bundle settings) {
20765        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20766            ProcessRecord processRecord = mLruProcesses.get(i);
20767            try {
20768                if (processRecord.thread != null) {
20769                    processRecord.thread.setCoreSettings(settings);
20770                }
20771            } catch (RemoteException re) {
20772                /* ignore */
20773            }
20774        }
20775    }
20776
20777    // Multi-user methods
20778
20779    /**
20780     * Start user, if its not already running, but don't bring it to foreground.
20781     */
20782    @Override
20783    public boolean startUserInBackground(final int userId) {
20784        return mUserController.startUser(userId, /* foreground */ false);
20785    }
20786
20787    @Override
20788    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20789        return mUserController.unlockUser(userId, token, secret, listener);
20790    }
20791
20792    @Override
20793    public boolean switchUser(final int targetUserId) {
20794        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20795        UserInfo currentUserInfo;
20796        UserInfo targetUserInfo;
20797        synchronized (this) {
20798            int currentUserId = mUserController.getCurrentUserIdLocked();
20799            currentUserInfo = mUserController.getUserInfo(currentUserId);
20800            targetUserInfo = mUserController.getUserInfo(targetUserId);
20801            if (targetUserInfo == null) {
20802                Slog.w(TAG, "No user info for user #" + targetUserId);
20803                return false;
20804            }
20805            if (!targetUserInfo.supportsSwitchTo()) {
20806                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20807                return false;
20808            }
20809            if (targetUserInfo.isManagedProfile()) {
20810                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20811                return false;
20812            }
20813            mUserController.setTargetUserIdLocked(targetUserId);
20814        }
20815        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20816        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20817        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20818        return true;
20819    }
20820
20821    void scheduleStartProfilesLocked() {
20822        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20823            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20824                    DateUtils.SECOND_IN_MILLIS);
20825        }
20826    }
20827
20828    @Override
20829    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20830        return mUserController.stopUser(userId, force, callback);
20831    }
20832
20833    @Override
20834    public UserInfo getCurrentUser() {
20835        return mUserController.getCurrentUser();
20836    }
20837
20838    @Override
20839    public boolean isUserRunning(int userId, int flags) {
20840        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20841                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20842            String msg = "Permission Denial: isUserRunning() from pid="
20843                    + Binder.getCallingPid()
20844                    + ", uid=" + Binder.getCallingUid()
20845                    + " requires " + INTERACT_ACROSS_USERS;
20846            Slog.w(TAG, msg);
20847            throw new SecurityException(msg);
20848        }
20849        synchronized (this) {
20850            return mUserController.isUserRunningLocked(userId, flags);
20851        }
20852    }
20853
20854    @Override
20855    public int[] getRunningUserIds() {
20856        if (checkCallingPermission(INTERACT_ACROSS_USERS)
20857                != PackageManager.PERMISSION_GRANTED) {
20858            String msg = "Permission Denial: isUserRunning() from pid="
20859                    + Binder.getCallingPid()
20860                    + ", uid=" + Binder.getCallingUid()
20861                    + " requires " + INTERACT_ACROSS_USERS;
20862            Slog.w(TAG, msg);
20863            throw new SecurityException(msg);
20864        }
20865        synchronized (this) {
20866            return mUserController.getStartedUserArrayLocked();
20867        }
20868    }
20869
20870    @Override
20871    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20872        mUserController.registerUserSwitchObserver(observer);
20873    }
20874
20875    @Override
20876    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20877        mUserController.unregisterUserSwitchObserver(observer);
20878    }
20879
20880    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20881        if (info == null) return null;
20882        ApplicationInfo newInfo = new ApplicationInfo(info);
20883        newInfo.initForUser(userId);
20884        return newInfo;
20885    }
20886
20887    public boolean isUserStopped(int userId) {
20888        synchronized (this) {
20889            return mUserController.getStartedUserStateLocked(userId) == null;
20890        }
20891    }
20892
20893    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20894        if (aInfo == null
20895                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20896            return aInfo;
20897        }
20898
20899        ActivityInfo info = new ActivityInfo(aInfo);
20900        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20901        return info;
20902    }
20903
20904    private boolean processSanityChecksLocked(ProcessRecord process) {
20905        if (process == null || process.thread == null) {
20906            return false;
20907        }
20908
20909        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20910        if (!isDebuggable) {
20911            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20912                return false;
20913            }
20914        }
20915
20916        return true;
20917    }
20918
20919    public boolean startBinderTracking() throws RemoteException {
20920        synchronized (this) {
20921            mBinderTransactionTrackingEnabled = true;
20922            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20923            // permission (same as profileControl).
20924            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20925                    != PackageManager.PERMISSION_GRANTED) {
20926                throw new SecurityException("Requires permission "
20927                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20928            }
20929
20930            for (int i = 0; i < mLruProcesses.size(); i++) {
20931                ProcessRecord process = mLruProcesses.get(i);
20932                if (!processSanityChecksLocked(process)) {
20933                    continue;
20934                }
20935                try {
20936                    process.thread.startBinderTracking();
20937                } catch (RemoteException e) {
20938                    Log.v(TAG, "Process disappared");
20939                }
20940            }
20941            return true;
20942        }
20943    }
20944
20945    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20946        try {
20947            synchronized (this) {
20948                mBinderTransactionTrackingEnabled = false;
20949                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20950                // permission (same as profileControl).
20951                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20952                        != PackageManager.PERMISSION_GRANTED) {
20953                    throw new SecurityException("Requires permission "
20954                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20955                }
20956
20957                if (fd == null) {
20958                    throw new IllegalArgumentException("null fd");
20959                }
20960
20961                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20962                pw.println("Binder transaction traces for all processes.\n");
20963                for (ProcessRecord process : mLruProcesses) {
20964                    if (!processSanityChecksLocked(process)) {
20965                        continue;
20966                    }
20967
20968                    pw.println("Traces for process: " + process.processName);
20969                    pw.flush();
20970                    try {
20971                        TransferPipe tp = new TransferPipe();
20972                        try {
20973                            process.thread.stopBinderTrackingAndDump(
20974                                    tp.getWriteFd().getFileDescriptor());
20975                            tp.go(fd.getFileDescriptor());
20976                        } finally {
20977                            tp.kill();
20978                        }
20979                    } catch (IOException e) {
20980                        pw.println("Failure while dumping IPC traces from " + process +
20981                                ".  Exception: " + e);
20982                        pw.flush();
20983                    } catch (RemoteException e) {
20984                        pw.println("Got a RemoteException while dumping IPC traces from " +
20985                                process + ".  Exception: " + e);
20986                        pw.flush();
20987                    }
20988                }
20989                fd = null;
20990                return true;
20991            }
20992        } finally {
20993            if (fd != null) {
20994                try {
20995                    fd.close();
20996                } catch (IOException e) {
20997                }
20998            }
20999        }
21000    }
21001
21002    private final class LocalService extends ActivityManagerInternal {
21003        @Override
21004        public void onWakefulnessChanged(int wakefulness) {
21005            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21006        }
21007
21008        @Override
21009        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21010                String processName, String abiOverride, int uid, Runnable crashHandler) {
21011            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21012                    processName, abiOverride, uid, crashHandler);
21013        }
21014
21015        @Override
21016        public SleepToken acquireSleepToken(String tag) {
21017            Preconditions.checkNotNull(tag);
21018
21019            synchronized (ActivityManagerService.this) {
21020                SleepTokenImpl token = new SleepTokenImpl(tag);
21021                mSleepTokens.add(token);
21022                updateSleepIfNeededLocked();
21023                applyVrModeIfNeededLocked(mFocusedActivity, false);
21024                return token;
21025            }
21026        }
21027
21028        @Override
21029        public ComponentName getHomeActivityForUser(int userId) {
21030            synchronized (ActivityManagerService.this) {
21031                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21032                return homeActivity == null ? null : homeActivity.realActivity;
21033            }
21034        }
21035
21036        @Override
21037        public void onUserRemoved(int userId) {
21038            synchronized (ActivityManagerService.this) {
21039                ActivityManagerService.this.onUserStoppedLocked(userId);
21040            }
21041        }
21042
21043        @Override
21044        public void onLocalVoiceInteractionStarted(IBinder activity,
21045                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21046            synchronized (ActivityManagerService.this) {
21047                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21048                        voiceSession, voiceInteractor);
21049            }
21050        }
21051
21052        @Override
21053        public void notifyStartingWindowDrawn() {
21054            synchronized (ActivityManagerService.this) {
21055                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21056            }
21057        }
21058
21059        @Override
21060        public void notifyAppTransitionStarting(int reason) {
21061            synchronized (ActivityManagerService.this) {
21062                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21063            }
21064        }
21065
21066        @Override
21067        public void notifyAppTransitionFinished() {
21068            synchronized (ActivityManagerService.this) {
21069                mStackSupervisor.notifyAppTransitionDone();
21070            }
21071        }
21072
21073        @Override
21074        public void notifyAppTransitionCancelled() {
21075            synchronized (ActivityManagerService.this) {
21076                mStackSupervisor.notifyAppTransitionDone();
21077            }
21078        }
21079
21080        @Override
21081        public List<IBinder> getTopVisibleActivities() {
21082            synchronized (ActivityManagerService.this) {
21083                return mStackSupervisor.getTopVisibleActivities();
21084            }
21085        }
21086
21087        @Override
21088        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21089            synchronized (ActivityManagerService.this) {
21090                mStackSupervisor.setDockedStackMinimized(minimized);
21091            }
21092        }
21093
21094        @Override
21095        public void killForegroundAppsForUser(int userHandle) {
21096            synchronized (ActivityManagerService.this) {
21097                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21098                final int NP = mProcessNames.getMap().size();
21099                for (int ip = 0; ip < NP; ip++) {
21100                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21101                    final int NA = apps.size();
21102                    for (int ia = 0; ia < NA; ia++) {
21103                        final ProcessRecord app = apps.valueAt(ia);
21104                        if (app.persistent) {
21105                            // We don't kill persistent processes.
21106                            continue;
21107                        }
21108                        if (app.removed) {
21109                            procs.add(app);
21110                        } else if (app.userId == userHandle && app.foregroundActivities) {
21111                            app.removed = true;
21112                            procs.add(app);
21113                        }
21114                    }
21115                }
21116
21117                final int N = procs.size();
21118                for (int i = 0; i < N; i++) {
21119                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21120                }
21121            }
21122        }
21123    }
21124
21125    private final class SleepTokenImpl extends SleepToken {
21126        private final String mTag;
21127        private final long mAcquireTime;
21128
21129        public SleepTokenImpl(String tag) {
21130            mTag = tag;
21131            mAcquireTime = SystemClock.uptimeMillis();
21132        }
21133
21134        @Override
21135        public void release() {
21136            synchronized (ActivityManagerService.this) {
21137                if (mSleepTokens.remove(this)) {
21138                    updateSleepIfNeededLocked();
21139                }
21140            }
21141        }
21142
21143        @Override
21144        public String toString() {
21145            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21146        }
21147    }
21148
21149    /**
21150     * An implementation of IAppTask, that allows an app to manage its own tasks via
21151     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21152     * only the process that calls getAppTasks() can call the AppTask methods.
21153     */
21154    class AppTaskImpl extends IAppTask.Stub {
21155        private int mTaskId;
21156        private int mCallingUid;
21157
21158        public AppTaskImpl(int taskId, int callingUid) {
21159            mTaskId = taskId;
21160            mCallingUid = callingUid;
21161        }
21162
21163        private void checkCaller() {
21164            if (mCallingUid != Binder.getCallingUid()) {
21165                throw new SecurityException("Caller " + mCallingUid
21166                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21167            }
21168        }
21169
21170        @Override
21171        public void finishAndRemoveTask() {
21172            checkCaller();
21173
21174            synchronized (ActivityManagerService.this) {
21175                long origId = Binder.clearCallingIdentity();
21176                try {
21177                    // We remove the task from recents to preserve backwards
21178                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21179                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21180                    }
21181                } finally {
21182                    Binder.restoreCallingIdentity(origId);
21183                }
21184            }
21185        }
21186
21187        @Override
21188        public ActivityManager.RecentTaskInfo getTaskInfo() {
21189            checkCaller();
21190
21191            synchronized (ActivityManagerService.this) {
21192                long origId = Binder.clearCallingIdentity();
21193                try {
21194                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21195                    if (tr == null) {
21196                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21197                    }
21198                    return createRecentTaskInfoFromTaskRecord(tr);
21199                } finally {
21200                    Binder.restoreCallingIdentity(origId);
21201                }
21202            }
21203        }
21204
21205        @Override
21206        public void moveToFront() {
21207            checkCaller();
21208            // Will bring task to front if it already has a root activity.
21209            final long origId = Binder.clearCallingIdentity();
21210            try {
21211                synchronized (this) {
21212                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21213                }
21214            } finally {
21215                Binder.restoreCallingIdentity(origId);
21216            }
21217        }
21218
21219        @Override
21220        public int startActivity(IBinder whoThread, String callingPackage,
21221                Intent intent, String resolvedType, Bundle bOptions) {
21222            checkCaller();
21223
21224            int callingUser = UserHandle.getCallingUserId();
21225            TaskRecord tr;
21226            IApplicationThread appThread;
21227            synchronized (ActivityManagerService.this) {
21228                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21229                if (tr == null) {
21230                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21231                }
21232                appThread = ApplicationThreadNative.asInterface(whoThread);
21233                if (appThread == null) {
21234                    throw new IllegalArgumentException("Bad app thread " + appThread);
21235                }
21236            }
21237            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21238                    resolvedType, null, null, null, null, 0, 0, null, null,
21239                    null, bOptions, false, callingUser, null, tr);
21240        }
21241
21242        @Override
21243        public void setExcludeFromRecents(boolean exclude) {
21244            checkCaller();
21245
21246            synchronized (ActivityManagerService.this) {
21247                long origId = Binder.clearCallingIdentity();
21248                try {
21249                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21250                    if (tr == null) {
21251                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21252                    }
21253                    Intent intent = tr.getBaseIntent();
21254                    if (exclude) {
21255                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21256                    } else {
21257                        intent.setFlags(intent.getFlags()
21258                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21259                    }
21260                } finally {
21261                    Binder.restoreCallingIdentity(origId);
21262                }
21263            }
21264        }
21265    }
21266
21267    /**
21268     * Kill processes for the user with id userId and that depend on the package named packageName
21269     */
21270    @Override
21271    public void killPackageDependents(String packageName, int userId) {
21272        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21273        if (packageName == null) {
21274            throw new NullPointerException(
21275                    "Cannot kill the dependents of a package without its name.");
21276        }
21277
21278        long callingId = Binder.clearCallingIdentity();
21279        IPackageManager pm = AppGlobals.getPackageManager();
21280        int pkgUid = -1;
21281        try {
21282            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21283        } catch (RemoteException e) {
21284        }
21285        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21286            throw new IllegalArgumentException(
21287                    "Cannot kill dependents of non-existing package " + packageName);
21288        }
21289        try {
21290            synchronized(this) {
21291                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21292                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21293                        "dep: " + packageName);
21294            }
21295        } finally {
21296            Binder.restoreCallingIdentity(callingId);
21297        }
21298    }
21299}
21300