ActivityManagerService.java revision b3bab1634106923ba39bde3123305d2a4c142b49
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import com.android.internal.telephony.TelephonyIntents;
20import com.google.android.collect.Lists;
21import com.google.android.collect.Maps;
22import com.android.internal.R;
23import com.android.internal.annotations.GuardedBy;
24import com.android.internal.app.AssistUtils;
25import com.android.internal.app.DumpHeapActivity;
26import com.android.internal.app.IAppOpsCallback;
27import com.android.internal.app.IAppOpsService;
28import com.android.internal.app.IVoiceInteractor;
29import com.android.internal.app.ProcessMap;
30import com.android.internal.app.SystemUserHomeActivity;
31import com.android.internal.app.procstats.ProcessStats;
32import com.android.internal.os.BackgroundThread;
33import com.android.internal.os.BatteryStatsImpl;
34import com.android.internal.os.IResultReceiver;
35import com.android.internal.os.ProcessCpuTracker;
36import com.android.internal.os.TransferPipe;
37import com.android.internal.os.Zygote;
38import com.android.internal.os.InstallerConnection.InstallerException;
39import com.android.internal.util.ArrayUtils;
40import com.android.internal.util.FastPrintWriter;
41import com.android.internal.util.FastXmlSerializer;
42import com.android.internal.util.MemInfoReader;
43import com.android.internal.util.Preconditions;
44import com.android.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.NonNull;
67import android.annotation.UserIdInt;
68import android.app.Activity;
69import android.app.ActivityManager;
70import android.app.ActivityManager.RunningTaskInfo;
71import android.app.ActivityManager.StackId;
72import android.app.ActivityManager.StackInfo;
73import android.app.ActivityManager.TaskThumbnailInfo;
74import android.app.ActivityManagerInternal;
75import android.app.ActivityManagerInternal.SleepToken;
76import android.app.ActivityManagerNative;
77import android.app.ActivityOptions;
78import android.app.ActivityThread;
79import android.app.AlertDialog;
80import android.app.AppGlobals;
81import android.app.AppOpsManager;
82import android.app.ApplicationErrorReport;
83import android.app.ApplicationThreadNative;
84import android.app.BroadcastOptions;
85import android.app.Dialog;
86import android.app.IActivityContainer;
87import android.app.IActivityContainerCallback;
88import android.app.IActivityController;
89import android.app.IAppTask;
90import android.app.IApplicationThread;
91import android.app.IInstrumentationWatcher;
92import android.app.INotificationManager;
93import android.app.IProcessObserver;
94import android.app.IServiceConnection;
95import android.app.IStopUserCallback;
96import android.app.ITaskStackListener;
97import android.app.IUiAutomationConnection;
98import android.app.IUidObserver;
99import android.app.IUserSwitchObserver;
100import android.app.Instrumentation;
101import android.app.Notification;
102import android.app.NotificationManager;
103import android.app.PendingIntent;
104import android.app.ProfilerInfo;
105import android.app.admin.DevicePolicyManager;
106import android.app.assist.AssistContent;
107import android.app.assist.AssistStructure;
108import android.app.backup.IBackupManager;
109import android.app.usage.UsageEvents;
110import android.app.usage.UsageStatsManagerInternal;
111import android.appwidget.AppWidgetManager;
112import android.content.ActivityNotFoundException;
113import android.content.BroadcastReceiver;
114import android.content.ClipData;
115import android.content.ComponentCallbacks2;
116import android.content.ComponentName;
117import android.content.ContentProvider;
118import android.content.ContentResolver;
119import android.content.Context;
120import android.content.DialogInterface;
121import android.content.IContentProvider;
122import android.content.IIntentReceiver;
123import android.content.IIntentSender;
124import android.content.Intent;
125import android.content.IntentFilter;
126import android.content.IntentSender;
127import android.content.pm.ActivityInfo;
128import android.content.pm.ApplicationInfo;
129import android.content.pm.ConfigurationInfo;
130import android.content.pm.IPackageDataObserver;
131import android.content.pm.IPackageManager;
132import android.content.pm.InstrumentationInfo;
133import android.content.pm.PackageInfo;
134import android.content.pm.PackageManager;
135import android.content.pm.PackageManager.NameNotFoundException;
136import android.content.pm.PackageManagerInternal;
137import android.content.pm.ParceledListSlice;
138import android.content.pm.PathPermission;
139import android.content.pm.PermissionInfo;
140import android.content.pm.ProviderInfo;
141import android.content.pm.ResolveInfo;
142import android.content.pm.ServiceInfo;
143import android.content.pm.ShortcutServiceInternal;
144import android.content.pm.UserInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.content.res.Resources;
148import android.database.ContentObserver;
149import android.graphics.Bitmap;
150import android.graphics.Point;
151import android.graphics.Rect;
152import android.location.LocationManager;
153import android.net.Proxy;
154import android.net.ProxyInfo;
155import android.net.Uri;
156import android.os.BatteryStats;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IProcessInfoService;
170import android.os.IProgressListener;
171import android.os.LocaleList;
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.telecom.TelecomManager;
201import android.text.format.DateUtils;
202import android.text.format.Time;
203import android.text.style.SuggestionSpan;
204import android.util.ArrayMap;
205import android.util.ArraySet;
206import android.util.AtomicFile;
207import android.util.DebugUtils;
208import android.util.DisplayMetrics;
209import android.util.EventLog;
210import android.util.Log;
211import android.util.Pair;
212import android.util.PrintWriterPrinter;
213import android.util.Slog;
214import android.util.SparseArray;
215import android.util.TimeUtils;
216import android.util.Xml;
217import android.view.Display;
218import android.view.Gravity;
219import android.view.LayoutInflater;
220import android.view.View;
221import android.view.WindowManager;
222
223import java.io.File;
224import java.io.FileDescriptor;
225import java.io.FileInputStream;
226import java.io.FileNotFoundException;
227import java.io.FileOutputStream;
228import java.io.IOException;
229import java.io.InputStreamReader;
230import java.io.PrintWriter;
231import java.io.StringWriter;
232import java.lang.ref.WeakReference;
233import java.nio.charset.StandardCharsets;
234import java.util.ArrayList;
235import java.util.Arrays;
236import java.util.Collections;
237import java.util.Comparator;
238import java.util.HashMap;
239import java.util.HashSet;
240import java.util.Iterator;
241import java.util.List;
242import java.util.Locale;
243import java.util.Map;
244import java.util.Objects;
245import java.util.Set;
246import java.util.concurrent.atomic.AtomicBoolean;
247import java.util.concurrent.atomic.AtomicLong;
248
249import dalvik.system.VMRuntime;
250
251import libcore.io.IoUtils;
252import libcore.util.EmptyArray;
253
254import static android.Manifest.permission.INTERACT_ACROSS_USERS;
255import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
256import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
257import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
258import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
259import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
260import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
261import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
262import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
263import static android.app.ActivityManager.StackId.HOME_STACK_ID;
264import static android.app.ActivityManager.StackId.INVALID_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_LEANBACK_ONLY;
268import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
269import static android.content.pm.PackageManager.GET_PROVIDERS;
270import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
271import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
272import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
273import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
274import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
275import static android.content.pm.PackageManager.PERMISSION_GRANTED;
276import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
277import static android.os.Process.PROC_CHAR;
278import static android.os.Process.PROC_OUT_LONG;
279import static android.os.Process.PROC_PARENS;
280import static android.os.Process.PROC_SPACE_TERM;
281import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
282import static android.provider.Settings.Global.DEBUG_APP;
283import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
284import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
285import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
286import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
287import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
288import static android.provider.Settings.System.FONT_SCALE;
289import static com.android.internal.util.XmlUtils.readBooleanAttribute;
290import static com.android.internal.util.XmlUtils.readIntAttribute;
291import static com.android.internal.util.XmlUtils.readLongAttribute;
292import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
293import static com.android.internal.util.XmlUtils.writeIntAttribute;
294import static com.android.internal.util.XmlUtils.writeLongAttribute;
295import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
296import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
297import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
298import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
299import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
300import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
301import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
302import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
303import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
304import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
305import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
306import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
307import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
308import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
309import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
310import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
311import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
312import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
313import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
314import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
315import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
316import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
317import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
318import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
319import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
320import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
321import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
322import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
323import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
324import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
325import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
326import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
327import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
328import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
329import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
330import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
331import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
332import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
333import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
334import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
335import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
336import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
337import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
338import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
339import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
340import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
341import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
342import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
343import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
344import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
345import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
346import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
347import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
348import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
349import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
350import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
351import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
352import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
353import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
354import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
355import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
356import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
357import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
358import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
359import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
360import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
361import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
362import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
363import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
364import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
365import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
366import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
367import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
368import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
369import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
370import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
371import static org.xmlpull.v1.XmlPullParser.START_TAG;
372
373public final class ActivityManagerService extends ActivityManagerNative
374        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
375
376    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
377    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
378    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
379    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
380    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
381    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
382    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
383    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
384    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
385    private static final String TAG_LRU = TAG + POSTFIX_LRU;
386    private static final String TAG_MU = TAG + POSTFIX_MU;
387    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
388    private static final String TAG_POWER = TAG + POSTFIX_POWER;
389    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
390    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
391    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
392    private static final String TAG_PSS = TAG + POSTFIX_PSS;
393    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
394    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
395    private static final String TAG_STACK = TAG + POSTFIX_STACK;
396    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
397    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
398    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
399    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
400    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
401
402    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
403    // here so that while the job scheduler can depend on AMS, the other way around
404    // need not be the case.
405    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
406
407    /** Control over CPU and battery monitoring */
408    // write battery stats every 30 minutes.
409    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
410    static final boolean MONITOR_CPU_USAGE = true;
411    // don't sample cpu less than every 5 seconds.
412    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
413    // wait possibly forever for next cpu sample.
414    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
415    static final boolean MONITOR_THREAD_CPU_USAGE = false;
416
417    // The flags that are set for all calls we make to the package manager.
418    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
419
420    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
421
422    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
423
424    // Amount of time after a call to stopAppSwitches() during which we will
425    // prevent further untrusted switches from happening.
426    static final long APP_SWITCH_DELAY_TIME = 5*1000;
427
428    // How long we wait for a launched process to attach to the activity manager
429    // before we decide it's never going to come up for real.
430    static final int PROC_START_TIMEOUT = 10*1000;
431    // How long we wait for an attached process to publish its content providers
432    // before we decide it must be hung.
433    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
434
435    // How long we will retain processes hosting content providers in the "last activity"
436    // state before allowing them to drop down to the regular cached LRU list.  This is
437    // to avoid thrashing of provider processes under low memory situations.
438    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
439
440    // How long we wait for a launched process to attach to the activity manager
441    // before we decide it's never going to come up for real, when the process was
442    // started with a wrapper for instrumentation (such as Valgrind) because it
443    // could take much longer than usual.
444    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
445
446    // How long to wait after going idle before forcing apps to GC.
447    static final int GC_TIMEOUT = 5*1000;
448
449    // The minimum amount of time between successive GC requests for a process.
450    static final int GC_MIN_INTERVAL = 60*1000;
451
452    // The minimum amount of time between successive PSS requests for a process.
453    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
454
455    // The minimum amount of time between successive PSS requests for a process
456    // when the request is due to the memory state being lowered.
457    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
458
459    // The rate at which we check for apps using excessive power -- 15 mins.
460    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
461
462    // The minimum sample duration we will allow before deciding we have
463    // enough data on wake locks to start killing things.
464    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
465
466    // The minimum sample duration we will allow before deciding we have
467    // enough data on CPU usage to start killing things.
468    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
469
470    // How long we allow a receiver to run before giving up on it.
471    static final int BROADCAST_FG_TIMEOUT = 10*1000;
472    static final int BROADCAST_BG_TIMEOUT = 60*1000;
473
474    // How long we wait until we timeout on key dispatching.
475    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
476
477    // How long we wait until we timeout on key dispatching during instrumentation.
478    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
479
480    // This is the amount of time an app needs to be running a foreground service before
481    // we will consider it to be doing interaction for usage stats.
482    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
483
484    // Maximum amount of time we will allow to elapse before re-reporting usage stats
485    // interaction with foreground processes.
486    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
487
488    // This is the amount of time we allow an app to settle after it goes into the background,
489    // before we start restricting what it can do.
490    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
491
492    // How long to wait in getAssistContextExtras for the activity and foreground services
493    // to respond with the result.
494    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
495
496    // How long top wait when going through the modern assist (which doesn't need to block
497    // on getting this result before starting to launch its UI).
498    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
499
500    // Maximum number of persisted Uri grants a package is allowed
501    static final int MAX_PERSISTED_URI_GRANTS = 128;
502
503    static final int MY_PID = Process.myPid();
504
505    static final String[] EMPTY_STRING_ARRAY = new String[0];
506
507    // How many bytes to write into the dropbox log before truncating
508    static final int DROPBOX_MAX_SIZE = 192 * 1024;
509    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
510    // as one line, but close enough for now.
511    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
512
513    // Access modes for handleIncomingUser.
514    static final int ALLOW_NON_FULL = 0;
515    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
516    static final int ALLOW_FULL_ONLY = 2;
517
518    // Delay in notifying task stack change listeners (in millis)
519    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
520
521    // Necessary ApplicationInfo flags to mark an app as persistent
522    private static final int PERSISTENT_MASK =
523            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
524
525    // Intent sent when remote bugreport collection has been completed
526    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
527            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
528
529    // Delay to disable app launch boost
530    static final int APP_BOOST_MESSAGE_DELAY = 3000;
531    // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
532    static final int APP_BOOST_TIMEOUT = 2500;
533
534    // Used to indicate that a task is removed it should also be removed from recents.
535    private static final boolean REMOVE_FROM_RECENTS = true;
536    // Used to indicate that an app transition should be animated.
537    static final boolean ANIMATE = true;
538
539    // Determines whether to take full screen screenshots
540    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
541    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
542
543    private static native int nativeMigrateToBoost();
544    private static native int nativeMigrateFromBoost();
545    private boolean mIsBoosted = false;
546    private long mBoostStartTime = 0;
547
548    /** All system services */
549    SystemServiceManager mSystemServiceManager;
550
551    private Installer mInstaller;
552
553    /** Run all ActivityStacks through this */
554    final ActivityStackSupervisor mStackSupervisor;
555
556    final ActivityStarter mActivityStarter;
557
558    /** Task stack change listeners. */
559    private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
560            new RemoteCallbackList<ITaskStackListener>();
561
562    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
563
564    public IntentFirewall mIntentFirewall;
565
566    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
567    // default actuion automatically.  Important for devices without direct input
568    // devices.
569    private boolean mShowDialogs = true;
570    private boolean mInVrMode = false;
571
572    BroadcastQueue mFgBroadcastQueue;
573    BroadcastQueue mBgBroadcastQueue;
574    // Convenient for easy iteration over the queues. Foreground is first
575    // so that dispatch of foreground broadcasts gets precedence.
576    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
577
578    BroadcastStats mLastBroadcastStats;
579    BroadcastStats mCurBroadcastStats;
580
581    BroadcastQueue broadcastQueueForIntent(Intent intent) {
582        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
583        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
584                "Broadcast intent " + intent + " on "
585                + (isFg ? "foreground" : "background") + " queue");
586        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
587    }
588
589    /**
590     * Activity we have told the window manager to have key focus.
591     */
592    ActivityRecord mFocusedActivity = null;
593
594    /**
595     * User id of the last activity mFocusedActivity was set to.
596     */
597    private int mLastFocusedUserId;
598
599    /**
600     * If non-null, we are tracking the time the user spends in the currently focused app.
601     */
602    private AppTimeTracker mCurAppTimeTracker;
603
604    /**
605     * List of intents that were used to start the most recent tasks.
606     */
607    final RecentTasks mRecentTasks;
608
609    /**
610     * For addAppTask: cached of the last activity component that was added.
611     */
612    ComponentName mLastAddedTaskComponent;
613
614    /**
615     * For addAppTask: cached of the last activity uid that was added.
616     */
617    int mLastAddedTaskUid;
618
619    /**
620     * For addAppTask: cached of the last ActivityInfo that was added.
621     */
622    ActivityInfo mLastAddedTaskActivity;
623
624    /**
625     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
626     */
627    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
628
629    /**
630     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
631     */
632    String mDeviceOwnerName;
633
634    final UserController mUserController;
635
636    final AppErrors mAppErrors;
637
638    boolean mDoingSetFocusedActivity;
639
640    public boolean canShowErrorDialogs() {
641        return mShowDialogs && !mSleeping && !mShuttingDown;
642    }
643
644    // it's a semaphore; boost when 0->1, reset when 1->0
645    static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
646        @Override protected Integer initialValue() {
647            return 0;
648        }
649    };
650
651    static void boostPriorityForLockedSection() {
652        if (sIsBoosted.get() == 0) {
653            // boost to prio 118 while holding a global lock
654            Process.setThreadPriority(Process.myTid(), -2);
655            //Log.e(TAG, "PRIORITY BOOST:  set priority on TID " + Process.myTid());
656        }
657        int cur = sIsBoosted.get();
658        sIsBoosted.set(cur + 1);
659    }
660
661    static void resetPriorityAfterLockedSection() {
662        sIsBoosted.set(sIsBoosted.get() - 1);
663        if (sIsBoosted.get() == 0) {
664            //Log.e(TAG, "PRIORITY BOOST:  reset priority on TID " + Process.myTid());
665            Process.setThreadPriority(Process.myTid(), 0);
666        }
667    }
668    public class PendingAssistExtras extends Binder implements Runnable {
669        public final ActivityRecord activity;
670        public final Bundle extras;
671        public final Intent intent;
672        public final String hint;
673        public final IResultReceiver receiver;
674        public final int userHandle;
675        public boolean haveResult = false;
676        public Bundle result = null;
677        public AssistStructure structure = null;
678        public AssistContent content = null;
679        public Bundle receiverExtras;
680
681        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
682                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
683            activity = _activity;
684            extras = _extras;
685            intent = _intent;
686            hint = _hint;
687            receiver = _receiver;
688            receiverExtras = _receiverExtras;
689            userHandle = _userHandle;
690        }
691        @Override
692        public void run() {
693            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
694            synchronized (this) {
695                haveResult = true;
696                notifyAll();
697            }
698            pendingAssistExtrasTimedOut(this);
699        }
700    }
701
702    final ArrayList<PendingAssistExtras> mPendingAssistExtras
703            = new ArrayList<PendingAssistExtras>();
704
705    /**
706     * Process management.
707     */
708    final ProcessList mProcessList = new ProcessList();
709
710    /**
711     * All of the applications we currently have running organized by name.
712     * The keys are strings of the application package name (as
713     * returned by the package manager), and the keys are ApplicationRecord
714     * objects.
715     */
716    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
717
718    /**
719     * Tracking long-term execution of processes to look for abuse and other
720     * bad app behavior.
721     */
722    final ProcessStatsService mProcessStats;
723
724    /**
725     * The currently running isolated processes.
726     */
727    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
728
729    /**
730     * Counter for assigning isolated process uids, to avoid frequently reusing the
731     * same ones.
732     */
733    int mNextIsolatedProcessUid = 0;
734
735    /**
736     * The currently running heavy-weight process, if any.
737     */
738    ProcessRecord mHeavyWeightProcess = null;
739
740    /**
741     * All of the processes we currently have running organized by pid.
742     * The keys are the pid running the application.
743     *
744     * <p>NOTE: This object is protected by its own lock, NOT the global
745     * activity manager lock!
746     */
747    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
748
749    /**
750     * All of the processes that have been forced to be foreground.  The key
751     * is the pid of the caller who requested it (we hold a death
752     * link on it).
753     */
754    abstract class ForegroundToken implements IBinder.DeathRecipient {
755        int pid;
756        IBinder token;
757    }
758    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
759
760    /**
761     * List of records for processes that someone had tried to start before the
762     * system was ready.  We don't start them at that point, but ensure they
763     * are started by the time booting is complete.
764     */
765    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
766
767    /**
768     * List of persistent applications that are in the process
769     * of being started.
770     */
771    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
772
773    /**
774     * Processes that are being forcibly torn down.
775     */
776    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
777
778    /**
779     * List of running applications, sorted by recent usage.
780     * The first entry in the list is the least recently used.
781     */
782    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
783
784    /**
785     * Where in mLruProcesses that the processes hosting activities start.
786     */
787    int mLruProcessActivityStart = 0;
788
789    /**
790     * Where in mLruProcesses that the processes hosting services start.
791     * This is after (lower index) than mLruProcessesActivityStart.
792     */
793    int mLruProcessServiceStart = 0;
794
795    /**
796     * List of processes that should gc as soon as things are idle.
797     */
798    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
799
800    /**
801     * Processes we want to collect PSS data from.
802     */
803    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
804
805    private boolean mBinderTransactionTrackingEnabled = false;
806
807    /**
808     * Last time we requested PSS data of all processes.
809     */
810    long mLastFullPssTime = SystemClock.uptimeMillis();
811
812    /**
813     * If set, the next time we collect PSS data we should do a full collection
814     * with data from native processes and the kernel.
815     */
816    boolean mFullPssPending = false;
817
818    /**
819     * This is the process holding what we currently consider to be
820     * the "home" activity.
821     */
822    ProcessRecord mHomeProcess;
823
824    /**
825     * This is the process holding the activity the user last visited that
826     * is in a different process from the one they are currently in.
827     */
828    ProcessRecord mPreviousProcess;
829
830    /**
831     * The time at which the previous process was last visible.
832     */
833    long mPreviousProcessVisibleTime;
834
835    /**
836     * Track all uids that have actively running processes.
837     */
838    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
839
840    /**
841     * This is for verifying the UID report flow.
842     */
843    static final boolean VALIDATE_UID_STATES = true;
844    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
845
846    /**
847     * Packages that the user has asked to have run in screen size
848     * compatibility mode instead of filling the screen.
849     */
850    final CompatModePackages mCompatModePackages;
851
852    /**
853     * Set of IntentSenderRecord objects that are currently active.
854     */
855    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
856            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
857
858    /**
859     * Fingerprints (hashCode()) of stack traces that we've
860     * already logged DropBox entries for.  Guarded by itself.  If
861     * something (rogue user app) forces this over
862     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
863     */
864    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
865    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
866
867    /**
868     * Strict Mode background batched logging state.
869     *
870     * The string buffer is guarded by itself, and its lock is also
871     * used to determine if another batched write is already
872     * in-flight.
873     */
874    private final StringBuilder mStrictModeBuffer = new StringBuilder();
875
876    /**
877     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
878     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
879     */
880    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
881
882    /**
883     * Resolver for broadcast intents to registered receivers.
884     * Holds BroadcastFilter (subclass of IntentFilter).
885     */
886    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
887            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
888        @Override
889        protected boolean allowFilterResult(
890                BroadcastFilter filter, List<BroadcastFilter> dest) {
891            IBinder target = filter.receiverList.receiver.asBinder();
892            for (int i = dest.size() - 1; i >= 0; i--) {
893                if (dest.get(i).receiverList.receiver.asBinder() == target) {
894                    return false;
895                }
896            }
897            return true;
898        }
899
900        @Override
901        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
902            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
903                    || userId == filter.owningUserId) {
904                return super.newResult(filter, match, userId);
905            }
906            return null;
907        }
908
909        @Override
910        protected BroadcastFilter[] newArray(int size) {
911            return new BroadcastFilter[size];
912        }
913
914        @Override
915        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
916            return packageName.equals(filter.packageName);
917        }
918    };
919
920    /**
921     * State of all active sticky broadcasts per user.  Keys are the action of the
922     * sticky Intent, values are an ArrayList of all broadcasted intents with
923     * that action (which should usually be one).  The SparseArray is keyed
924     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
925     * for stickies that are sent to all users.
926     */
927    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
928            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
929
930    final ActiveServices mServices;
931
932    final static class Association {
933        final int mSourceUid;
934        final String mSourceProcess;
935        final int mTargetUid;
936        final ComponentName mTargetComponent;
937        final String mTargetProcess;
938
939        int mCount;
940        long mTime;
941
942        int mNesting;
943        long mStartTime;
944
945        // states of the source process when the bind occurred.
946        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
947        long mLastStateUptime;
948        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
949                - ActivityManager.MIN_PROCESS_STATE+1];
950
951        Association(int sourceUid, String sourceProcess, int targetUid,
952                ComponentName targetComponent, String targetProcess) {
953            mSourceUid = sourceUid;
954            mSourceProcess = sourceProcess;
955            mTargetUid = targetUid;
956            mTargetComponent = targetComponent;
957            mTargetProcess = targetProcess;
958        }
959    }
960
961    /**
962     * When service association tracking is enabled, this is all of the associations we
963     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
964     * -> association data.
965     */
966    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
967            mAssociations = new SparseArray<>();
968    boolean mTrackingAssociations;
969
970    /**
971     * Backup/restore process management
972     */
973    String mBackupAppName = null;
974    BackupRecord mBackupTarget = null;
975
976    final ProviderMap mProviderMap;
977
978    /**
979     * List of content providers who have clients waiting for them.  The
980     * application is currently being launched and the provider will be
981     * removed from this list once it is published.
982     */
983    final ArrayList<ContentProviderRecord> mLaunchingProviders
984            = new ArrayList<ContentProviderRecord>();
985
986    /**
987     * File storing persisted {@link #mGrantedUriPermissions}.
988     */
989    private final AtomicFile mGrantFile;
990
991    /** XML constants used in {@link #mGrantFile} */
992    private static final String TAG_URI_GRANTS = "uri-grants";
993    private static final String TAG_URI_GRANT = "uri-grant";
994    private static final String ATTR_USER_HANDLE = "userHandle";
995    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
996    private static final String ATTR_TARGET_USER_ID = "targetUserId";
997    private static final String ATTR_SOURCE_PKG = "sourcePkg";
998    private static final String ATTR_TARGET_PKG = "targetPkg";
999    private static final String ATTR_URI = "uri";
1000    private static final String ATTR_MODE_FLAGS = "modeFlags";
1001    private static final String ATTR_CREATED_TIME = "createdTime";
1002    private static final String ATTR_PREFIX = "prefix";
1003
1004    /**
1005     * Global set of specific {@link Uri} permissions that have been granted.
1006     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1007     * to {@link UriPermission#uri} to {@link UriPermission}.
1008     */
1009    @GuardedBy("this")
1010    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1011            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1012
1013    public static class GrantUri {
1014        public final int sourceUserId;
1015        public final Uri uri;
1016        public boolean prefix;
1017
1018        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1019            this.sourceUserId = sourceUserId;
1020            this.uri = uri;
1021            this.prefix = prefix;
1022        }
1023
1024        @Override
1025        public int hashCode() {
1026            int hashCode = 1;
1027            hashCode = 31 * hashCode + sourceUserId;
1028            hashCode = 31 * hashCode + uri.hashCode();
1029            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1030            return hashCode;
1031        }
1032
1033        @Override
1034        public boolean equals(Object o) {
1035            if (o instanceof GrantUri) {
1036                GrantUri other = (GrantUri) o;
1037                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1038                        && prefix == other.prefix;
1039            }
1040            return false;
1041        }
1042
1043        @Override
1044        public String toString() {
1045            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1046            if (prefix) result += " [prefix]";
1047            return result;
1048        }
1049
1050        public String toSafeString() {
1051            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1052            if (prefix) result += " [prefix]";
1053            return result;
1054        }
1055
1056        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1057            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1058                    ContentProvider.getUriWithoutUserId(uri), false);
1059        }
1060    }
1061
1062    CoreSettingsObserver mCoreSettingsObserver;
1063
1064    FontScaleSettingObserver mFontScaleSettingObserver;
1065
1066    private final class FontScaleSettingObserver extends ContentObserver {
1067        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1068
1069        public FontScaleSettingObserver() {
1070            super(mHandler);
1071            ContentResolver resolver = mContext.getContentResolver();
1072            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1073        }
1074
1075        @Override
1076        public void onChange(boolean selfChange, Uri uri) {
1077            if (mFontScaleUri.equals(uri)) {
1078                updateFontScaleIfNeeded();
1079            }
1080        }
1081    }
1082
1083    /**
1084     * Thread-local storage used to carry caller permissions over through
1085     * indirect content-provider access.
1086     */
1087    private class Identity {
1088        public final IBinder token;
1089        public final int pid;
1090        public final int uid;
1091
1092        Identity(IBinder _token, int _pid, int _uid) {
1093            token = _token;
1094            pid = _pid;
1095            uid = _uid;
1096        }
1097    }
1098
1099    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1100
1101    /**
1102     * All information we have collected about the runtime performance of
1103     * any user id that can impact battery performance.
1104     */
1105    final BatteryStatsService mBatteryStatsService;
1106
1107    /**
1108     * Information about component usage
1109     */
1110    UsageStatsManagerInternal mUsageStatsService;
1111
1112    /**
1113     * Access to DeviceIdleController service.
1114     */
1115    DeviceIdleController.LocalService mLocalDeviceIdleController;
1116
1117    /**
1118     * Information about and control over application operations
1119     */
1120    final AppOpsService mAppOpsService;
1121
1122    /**
1123     * Current configuration information.  HistoryRecord objects are given
1124     * a reference to this object to indicate which configuration they are
1125     * currently running in, so this object must be kept immutable.
1126     */
1127    Configuration mConfiguration = new Configuration();
1128
1129    /**
1130     * Current sequencing integer of the configuration, for skipping old
1131     * configurations.
1132     */
1133    int mConfigurationSeq = 0;
1134
1135    boolean mSuppressResizeConfigChanges = false;
1136
1137    /**
1138     * Hardware-reported OpenGLES version.
1139     */
1140    final int GL_ES_VERSION;
1141
1142    /**
1143     * List of initialization arguments to pass to all processes when binding applications to them.
1144     * For example, references to the commonly used services.
1145     */
1146    HashMap<String, IBinder> mAppBindArgs;
1147
1148    /**
1149     * Temporary to avoid allocations.  Protected by main lock.
1150     */
1151    final StringBuilder mStringBuilder = new StringBuilder(256);
1152
1153    /**
1154     * Used to control how we initialize the service.
1155     */
1156    ComponentName mTopComponent;
1157    String mTopAction = Intent.ACTION_MAIN;
1158    String mTopData;
1159
1160    volatile boolean mProcessesReady = false;
1161    volatile boolean mSystemReady = false;
1162    volatile boolean mOnBattery = false;
1163    volatile int mFactoryTest;
1164
1165    @GuardedBy("this") boolean mBooting = false;
1166    @GuardedBy("this") boolean mCallFinishBooting = false;
1167    @GuardedBy("this") boolean mBootAnimationComplete = false;
1168    @GuardedBy("this") boolean mLaunchWarningShown = false;
1169    @GuardedBy("this") boolean mCheckedForSetup = false;
1170
1171    Context mContext;
1172
1173    /**
1174     * The time at which we will allow normal application switches again,
1175     * after a call to {@link #stopAppSwitches()}.
1176     */
1177    long mAppSwitchesAllowedTime;
1178
1179    /**
1180     * This is set to true after the first switch after mAppSwitchesAllowedTime
1181     * is set; any switches after that will clear the time.
1182     */
1183    boolean mDidAppSwitch;
1184
1185    /**
1186     * Last time (in realtime) at which we checked for power usage.
1187     */
1188    long mLastPowerCheckRealtime;
1189
1190    /**
1191     * Last time (in uptime) at which we checked for power usage.
1192     */
1193    long mLastPowerCheckUptime;
1194
1195    /**
1196     * Set while we are wanting to sleep, to prevent any
1197     * activities from being started/resumed.
1198     */
1199    private boolean mSleeping = false;
1200
1201    /**
1202     * The process state used for processes that are running the top activities.
1203     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1204     */
1205    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1206
1207    /**
1208     * Set while we are running a voice interaction.  This overrides
1209     * sleeping while it is active.
1210     */
1211    private IVoiceInteractionSession mRunningVoice;
1212
1213    /**
1214     * For some direct access we need to power manager.
1215     */
1216    PowerManagerInternal mLocalPowerManager;
1217
1218    /**
1219     * We want to hold a wake lock while running a voice interaction session, since
1220     * this may happen with the screen off and we need to keep the CPU running to
1221     * be able to continue to interact with the user.
1222     */
1223    PowerManager.WakeLock mVoiceWakeLock;
1224
1225    /**
1226     * State of external calls telling us if the device is awake or asleep.
1227     */
1228    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1229
1230    /**
1231     * A list of tokens that cause the top activity to be put to sleep.
1232     * They are used by components that may hide and block interaction with underlying
1233     * activities.
1234     */
1235    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1236
1237    static final int LOCK_SCREEN_HIDDEN = 0;
1238    static final int LOCK_SCREEN_LEAVING = 1;
1239    static final int LOCK_SCREEN_SHOWN = 2;
1240    /**
1241     * State of external call telling us if the lock screen is shown.
1242     */
1243    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1244
1245    /**
1246     * Set if we are shutting down the system, similar to sleeping.
1247     */
1248    boolean mShuttingDown = false;
1249
1250    /**
1251     * Current sequence id for oom_adj computation traversal.
1252     */
1253    int mAdjSeq = 0;
1254
1255    /**
1256     * Current sequence id for process LRU updating.
1257     */
1258    int mLruSeq = 0;
1259
1260    /**
1261     * Keep track of the non-cached/empty process we last found, to help
1262     * determine how to distribute cached/empty processes next time.
1263     */
1264    int mNumNonCachedProcs = 0;
1265
1266    /**
1267     * Keep track of the number of cached hidden procs, to balance oom adj
1268     * distribution between those and empty procs.
1269     */
1270    int mNumCachedHiddenProcs = 0;
1271
1272    /**
1273     * Keep track of the number of service processes we last found, to
1274     * determine on the next iteration which should be B services.
1275     */
1276    int mNumServiceProcs = 0;
1277    int mNewNumAServiceProcs = 0;
1278    int mNewNumServiceProcs = 0;
1279
1280    /**
1281     * Allow the current computed overall memory level of the system to go down?
1282     * This is set to false when we are killing processes for reasons other than
1283     * memory management, so that the now smaller process list will not be taken as
1284     * an indication that memory is tighter.
1285     */
1286    boolean mAllowLowerMemLevel = false;
1287
1288    /**
1289     * The last computed memory level, for holding when we are in a state that
1290     * processes are going away for other reasons.
1291     */
1292    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1293
1294    /**
1295     * The last total number of process we have, to determine if changes actually look
1296     * like a shrinking number of process due to lower RAM.
1297     */
1298    int mLastNumProcesses;
1299
1300    /**
1301     * The uptime of the last time we performed idle maintenance.
1302     */
1303    long mLastIdleTime = SystemClock.uptimeMillis();
1304
1305    /**
1306     * Total time spent with RAM that has been added in the past since the last idle time.
1307     */
1308    long mLowRamTimeSinceLastIdle = 0;
1309
1310    /**
1311     * If RAM is currently low, when that horrible situation started.
1312     */
1313    long mLowRamStartTime = 0;
1314
1315    /**
1316     * For reporting to battery stats the current top application.
1317     */
1318    private String mCurResumedPackage = null;
1319    private int mCurResumedUid = -1;
1320
1321    /**
1322     * For reporting to battery stats the apps currently running foreground
1323     * service.  The ProcessMap is package/uid tuples; each of these contain
1324     * an array of the currently foreground processes.
1325     */
1326    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1327            = new ProcessMap<ArrayList<ProcessRecord>>();
1328
1329    /**
1330     * This is set if we had to do a delayed dexopt of an app before launching
1331     * it, to increase the ANR timeouts in that case.
1332     */
1333    boolean mDidDexOpt;
1334
1335    /**
1336     * Set if the systemServer made a call to enterSafeMode.
1337     */
1338    boolean mSafeMode;
1339
1340    /**
1341     * If true, we are running under a test environment so will sample PSS from processes
1342     * much more rapidly to try to collect better data when the tests are rapidly
1343     * running through apps.
1344     */
1345    boolean mTestPssMode = false;
1346
1347    String mDebugApp = null;
1348    boolean mWaitForDebugger = false;
1349    boolean mDebugTransient = false;
1350    String mOrigDebugApp = null;
1351    boolean mOrigWaitForDebugger = false;
1352    boolean mAlwaysFinishActivities = false;
1353    boolean mLenientBackgroundCheck = false;
1354    boolean mForceResizableActivities;
1355    boolean mSupportsMultiWindow;
1356    boolean mSupportsFreeformWindowManagement;
1357    boolean mSupportsPictureInPicture;
1358    boolean mSupportsLeanbackOnly;
1359    Rect mDefaultPinnedStackBounds;
1360    IActivityController mController = null;
1361    boolean mControllerIsAMonkey = false;
1362    String mProfileApp = null;
1363    ProcessRecord mProfileProc = null;
1364    String mProfileFile;
1365    ParcelFileDescriptor mProfileFd;
1366    int mSamplingInterval = 0;
1367    boolean mAutoStopProfiler = false;
1368    int mProfileType = 0;
1369    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1370    String mMemWatchDumpProcName;
1371    String mMemWatchDumpFile;
1372    int mMemWatchDumpPid;
1373    int mMemWatchDumpUid;
1374    String mTrackAllocationApp = null;
1375    String mNativeDebuggingApp = null;
1376
1377    final long[] mTmpLong = new long[2];
1378
1379    static final class ProcessChangeItem {
1380        static final int CHANGE_ACTIVITIES = 1<<0;
1381        static final int CHANGE_PROCESS_STATE = 1<<1;
1382        int changes;
1383        int uid;
1384        int pid;
1385        int processState;
1386        boolean foregroundActivities;
1387    }
1388
1389    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1390    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1391
1392    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1393    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1394
1395    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1396    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1397
1398    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1399    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1400
1401    /**
1402     * Runtime CPU use collection thread.  This object's lock is used to
1403     * perform synchronization with the thread (notifying it to run).
1404     */
1405    final Thread mProcessCpuThread;
1406
1407    /**
1408     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1409     * Must acquire this object's lock when accessing it.
1410     * NOTE: this lock will be held while doing long operations (trawling
1411     * through all processes in /proc), so it should never be acquired by
1412     * any critical paths such as when holding the main activity manager lock.
1413     */
1414    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1415            MONITOR_THREAD_CPU_USAGE);
1416    final AtomicLong mLastCpuTime = new AtomicLong(0);
1417    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1418
1419    long mLastWriteTime = 0;
1420
1421    /**
1422     * Used to retain an update lock when the foreground activity is in
1423     * immersive mode.
1424     */
1425    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1426
1427    /**
1428     * Set to true after the system has finished booting.
1429     */
1430    boolean mBooted = false;
1431
1432    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1433    int mProcessLimitOverride = -1;
1434
1435    WindowManagerService mWindowManager;
1436    final ActivityThread mSystemThread;
1437
1438    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1439        final ProcessRecord mApp;
1440        final int mPid;
1441        final IApplicationThread mAppThread;
1442
1443        AppDeathRecipient(ProcessRecord app, int pid,
1444                IApplicationThread thread) {
1445            if (DEBUG_ALL) Slog.v(
1446                TAG, "New death recipient " + this
1447                + " for thread " + thread.asBinder());
1448            mApp = app;
1449            mPid = pid;
1450            mAppThread = thread;
1451        }
1452
1453        @Override
1454        public void binderDied() {
1455            if (DEBUG_ALL) Slog.v(
1456                TAG, "Death received in " + this
1457                + " for thread " + mAppThread.asBinder());
1458            synchronized(ActivityManagerService.this) {
1459                appDiedLocked(mApp, mPid, mAppThread, true);
1460            }
1461        }
1462    }
1463
1464    static final int SHOW_ERROR_UI_MSG = 1;
1465    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1466    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1467    static final int UPDATE_CONFIGURATION_MSG = 4;
1468    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1469    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1470    static final int SERVICE_TIMEOUT_MSG = 12;
1471    static final int UPDATE_TIME_ZONE = 13;
1472    static final int SHOW_UID_ERROR_UI_MSG = 14;
1473    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1474    static final int PROC_START_TIMEOUT_MSG = 20;
1475    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1476    static final int KILL_APPLICATION_MSG = 22;
1477    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1478    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1479    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1480    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1481    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1482    static final int CLEAR_DNS_CACHE_MSG = 28;
1483    static final int UPDATE_HTTP_PROXY_MSG = 29;
1484    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1485    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1486    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1487    static final int REPORT_MEM_USAGE_MSG = 33;
1488    static final int REPORT_USER_SWITCH_MSG = 34;
1489    static final int CONTINUE_USER_SWITCH_MSG = 35;
1490    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1491    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1492    static final int PERSIST_URI_GRANTS_MSG = 38;
1493    static final int REQUEST_ALL_PSS_MSG = 39;
1494    static final int START_PROFILES_MSG = 40;
1495    static final int UPDATE_TIME = 41;
1496    static final int SYSTEM_USER_START_MSG = 42;
1497    static final int SYSTEM_USER_CURRENT_MSG = 43;
1498    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1499    static final int FINISH_BOOTING_MSG = 45;
1500    static final int START_USER_SWITCH_UI_MSG = 46;
1501    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1502    static final int DISMISS_DIALOG_UI_MSG = 48;
1503    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1504    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1505    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1506    static final int DELETE_DUMPHEAP_MSG = 52;
1507    static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1508    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1509    static final int REPORT_TIME_TRACKER_MSG = 55;
1510    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1511    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1512    static final int APP_BOOST_DEACTIVATE_MSG = 58;
1513    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1514    static final int IDLE_UIDS_MSG = 60;
1515    static final int SYSTEM_USER_UNLOCK_MSG = 61;
1516    static final int LOG_STACK_STATE = 62;
1517    static final int VR_MODE_CHANGE_MSG = 63;
1518    static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1519    static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1520    static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1521    static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1522    static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1523    static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1524    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1525
1526    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1527    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1528    static final int FIRST_COMPAT_MODE_MSG = 300;
1529    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1530
1531    static ServiceThread sKillThread = null;
1532    static KillHandler sKillHandler = null;
1533
1534    CompatModeDialog mCompatModeDialog;
1535    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1536    long mLastMemUsageReportTime = 0;
1537
1538    /**
1539     * Flag whether the current user is a "monkey", i.e. whether
1540     * the UI is driven by a UI automation tool.
1541     */
1542    private boolean mUserIsMonkey;
1543
1544    /** Flag whether the device has a Recents UI */
1545    boolean mHasRecents;
1546
1547    /** The dimensions of the thumbnails in the Recents UI. */
1548    int mThumbnailWidth;
1549    int mThumbnailHeight;
1550    float mFullscreenThumbnailScale;
1551
1552    final ServiceThread mHandlerThread;
1553    final MainHandler mHandler;
1554    final UiHandler mUiHandler;
1555
1556    PackageManagerInternal mPackageManagerInt;
1557
1558    // VoiceInteraction session ID that changes for each new request except when
1559    // being called for multiwindow assist in a single session.
1560    private int mViSessionId = 1000;
1561
1562    final class KillHandler extends Handler {
1563        static final int KILL_PROCESS_GROUP_MSG = 4000;
1564
1565        public KillHandler(Looper looper) {
1566            super(looper, null, true);
1567        }
1568
1569        @Override
1570        public void handleMessage(Message msg) {
1571            switch (msg.what) {
1572                case KILL_PROCESS_GROUP_MSG:
1573                {
1574                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1575                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1576                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1577                }
1578                break;
1579
1580                default:
1581                    super.handleMessage(msg);
1582            }
1583        }
1584    }
1585
1586    final class UiHandler extends Handler {
1587        public UiHandler() {
1588            super(com.android.server.UiThread.get().getLooper(), null, true);
1589        }
1590
1591        @Override
1592        public void handleMessage(Message msg) {
1593            switch (msg.what) {
1594            case SHOW_ERROR_UI_MSG: {
1595                mAppErrors.handleShowAppErrorUi(msg);
1596                ensureBootCompleted();
1597            } break;
1598            case SHOW_NOT_RESPONDING_UI_MSG: {
1599                mAppErrors.handleShowAnrUi(msg);
1600                ensureBootCompleted();
1601            } break;
1602            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1603                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1604                synchronized (ActivityManagerService.this) {
1605                    ProcessRecord proc = (ProcessRecord) data.get("app");
1606                    if (proc == null) {
1607                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1608                        break;
1609                    }
1610                    if (proc.crashDialog != null) {
1611                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1612                        return;
1613                    }
1614                    AppErrorResult res = (AppErrorResult) data.get("result");
1615                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1616                        Dialog d = new StrictModeViolationDialog(mContext,
1617                                ActivityManagerService.this, res, proc);
1618                        d.show();
1619                        proc.crashDialog = d;
1620                    } else {
1621                        // The device is asleep, so just pretend that the user
1622                        // saw a crash dialog and hit "force quit".
1623                        res.set(0);
1624                    }
1625                }
1626                ensureBootCompleted();
1627            } break;
1628            case SHOW_FACTORY_ERROR_UI_MSG: {
1629                Dialog d = new FactoryErrorDialog(
1630                    mContext, msg.getData().getCharSequence("msg"));
1631                d.show();
1632                ensureBootCompleted();
1633            } break;
1634            case WAIT_FOR_DEBUGGER_UI_MSG: {
1635                synchronized (ActivityManagerService.this) {
1636                    ProcessRecord app = (ProcessRecord)msg.obj;
1637                    if (msg.arg1 != 0) {
1638                        if (!app.waitedForDebugger) {
1639                            Dialog d = new AppWaitingForDebuggerDialog(
1640                                    ActivityManagerService.this,
1641                                    mContext, app);
1642                            app.waitDialog = d;
1643                            app.waitedForDebugger = true;
1644                            d.show();
1645                        }
1646                    } else {
1647                        if (app.waitDialog != null) {
1648                            app.waitDialog.dismiss();
1649                            app.waitDialog = null;
1650                        }
1651                    }
1652                }
1653            } break;
1654            case SHOW_UID_ERROR_UI_MSG: {
1655                if (mShowDialogs) {
1656                    AlertDialog d = new BaseErrorDialog(mContext);
1657                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1658                    d.setCancelable(false);
1659                    d.setTitle(mContext.getText(R.string.android_system_label));
1660                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1661                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1662                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1663                    d.show();
1664                }
1665            } break;
1666            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1667                if (mShowDialogs) {
1668                    AlertDialog d = new BaseErrorDialog(mContext);
1669                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1670                    d.setCancelable(false);
1671                    d.setTitle(mContext.getText(R.string.android_system_label));
1672                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1673                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1674                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1675                    d.show();
1676                }
1677            } break;
1678            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1679                synchronized (ActivityManagerService.this) {
1680                    ActivityRecord ar = (ActivityRecord) msg.obj;
1681                    if (mCompatModeDialog != null) {
1682                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1683                                ar.info.applicationInfo.packageName)) {
1684                            return;
1685                        }
1686                        mCompatModeDialog.dismiss();
1687                        mCompatModeDialog = null;
1688                    }
1689                    if (ar != null && false) {
1690                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1691                                ar.packageName)) {
1692                            int mode = mCompatModePackages.computeCompatModeLocked(
1693                                    ar.info.applicationInfo);
1694                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1695                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1696                                mCompatModeDialog = new CompatModeDialog(
1697                                        ActivityManagerService.this, mContext,
1698                                        ar.info.applicationInfo);
1699                                mCompatModeDialog.show();
1700                            }
1701                        }
1702                    }
1703                }
1704                break;
1705            }
1706            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1707                synchronized (ActivityManagerService.this) {
1708                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1709                    if (mUnsupportedDisplaySizeDialog != null) {
1710                        mUnsupportedDisplaySizeDialog.dismiss();
1711                        mUnsupportedDisplaySizeDialog = null;
1712                    }
1713                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1714                            ar.packageName)) {
1715                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1716                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1717                        mUnsupportedDisplaySizeDialog.show();
1718                    }
1719                }
1720                break;
1721            }
1722            case START_USER_SWITCH_UI_MSG: {
1723                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1724                break;
1725            }
1726            case DISMISS_DIALOG_UI_MSG: {
1727                final Dialog d = (Dialog) msg.obj;
1728                d.dismiss();
1729                break;
1730            }
1731            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1732                dispatchProcessesChanged();
1733                break;
1734            }
1735            case DISPATCH_PROCESS_DIED_UI_MSG: {
1736                final int pid = msg.arg1;
1737                final int uid = msg.arg2;
1738                dispatchProcessDied(pid, uid);
1739                break;
1740            }
1741            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1742                dispatchUidsChanged();
1743            } break;
1744            }
1745        }
1746    }
1747
1748    final class MainHandler extends Handler {
1749        public MainHandler(Looper looper) {
1750            super(looper, null, true);
1751        }
1752
1753        @Override
1754        public void handleMessage(Message msg) {
1755            switch (msg.what) {
1756            case UPDATE_CONFIGURATION_MSG: {
1757                final ContentResolver resolver = mContext.getContentResolver();
1758                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1759                        msg.arg1);
1760            } break;
1761            case GC_BACKGROUND_PROCESSES_MSG: {
1762                synchronized (ActivityManagerService.this) {
1763                    performAppGcsIfAppropriateLocked();
1764                }
1765            } break;
1766            case SERVICE_TIMEOUT_MSG: {
1767                if (mDidDexOpt) {
1768                    mDidDexOpt = false;
1769                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1770                    nmsg.obj = msg.obj;
1771                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1772                    return;
1773                }
1774                mServices.serviceTimeout((ProcessRecord)msg.obj);
1775            } break;
1776            case UPDATE_TIME_ZONE: {
1777                synchronized (ActivityManagerService.this) {
1778                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1779                        ProcessRecord r = mLruProcesses.get(i);
1780                        if (r.thread != null) {
1781                            try {
1782                                r.thread.updateTimeZone();
1783                            } catch (RemoteException ex) {
1784                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1785                            }
1786                        }
1787                    }
1788                }
1789            } break;
1790            case CLEAR_DNS_CACHE_MSG: {
1791                synchronized (ActivityManagerService.this) {
1792                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1793                        ProcessRecord r = mLruProcesses.get(i);
1794                        if (r.thread != null) {
1795                            try {
1796                                r.thread.clearDnsCache();
1797                            } catch (RemoteException ex) {
1798                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1799                            }
1800                        }
1801                    }
1802                }
1803            } break;
1804            case UPDATE_HTTP_PROXY_MSG: {
1805                ProxyInfo proxy = (ProxyInfo)msg.obj;
1806                String host = "";
1807                String port = "";
1808                String exclList = "";
1809                Uri pacFileUrl = Uri.EMPTY;
1810                if (proxy != null) {
1811                    host = proxy.getHost();
1812                    port = Integer.toString(proxy.getPort());
1813                    exclList = proxy.getExclusionListAsString();
1814                    pacFileUrl = proxy.getPacFileUrl();
1815                }
1816                synchronized (ActivityManagerService.this) {
1817                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1818                        ProcessRecord r = mLruProcesses.get(i);
1819                        if (r.thread != null) {
1820                            try {
1821                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1822                            } catch (RemoteException ex) {
1823                                Slog.w(TAG, "Failed to update http proxy for: " +
1824                                        r.info.processName);
1825                            }
1826                        }
1827                    }
1828                }
1829            } break;
1830            case PROC_START_TIMEOUT_MSG: {
1831                if (mDidDexOpt) {
1832                    mDidDexOpt = false;
1833                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1834                    nmsg.obj = msg.obj;
1835                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1836                    return;
1837                }
1838                ProcessRecord app = (ProcessRecord)msg.obj;
1839                synchronized (ActivityManagerService.this) {
1840                    processStartTimedOutLocked(app);
1841                }
1842            } break;
1843            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1844                ProcessRecord app = (ProcessRecord)msg.obj;
1845                synchronized (ActivityManagerService.this) {
1846                    processContentProviderPublishTimedOutLocked(app);
1847                }
1848            } break;
1849            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1850                synchronized (ActivityManagerService.this) {
1851                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1852                }
1853            } break;
1854            case KILL_APPLICATION_MSG: {
1855                synchronized (ActivityManagerService.this) {
1856                    final int appId = msg.arg1;
1857                    final int userId = msg.arg2;
1858                    Bundle bundle = (Bundle)msg.obj;
1859                    String pkg = bundle.getString("pkg");
1860                    String reason = bundle.getString("reason");
1861                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1862                            false, userId, reason);
1863                }
1864            } break;
1865            case FINALIZE_PENDING_INTENT_MSG: {
1866                ((PendingIntentRecord)msg.obj).completeFinalize();
1867            } break;
1868            case POST_HEAVY_NOTIFICATION_MSG: {
1869                INotificationManager inm = NotificationManager.getService();
1870                if (inm == null) {
1871                    return;
1872                }
1873
1874                ActivityRecord root = (ActivityRecord)msg.obj;
1875                ProcessRecord process = root.app;
1876                if (process == null) {
1877                    return;
1878                }
1879
1880                try {
1881                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1882                    String text = mContext.getString(R.string.heavy_weight_notification,
1883                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1884                    Notification notification = new Notification.Builder(context)
1885                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1886                            .setWhen(0)
1887                            .setOngoing(true)
1888                            .setTicker(text)
1889                            .setColor(mContext.getColor(
1890                                    com.android.internal.R.color.system_notification_accent_color))
1891                            .setContentTitle(text)
1892                            .setContentText(
1893                                    mContext.getText(R.string.heavy_weight_notification_detail))
1894                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1895                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1896                                    new UserHandle(root.userId)))
1897                            .build();
1898                    try {
1899                        int[] outId = new int[1];
1900                        inm.enqueueNotificationWithTag("android", "android", null,
1901                                R.string.heavy_weight_notification,
1902                                notification, outId, root.userId);
1903                    } catch (RuntimeException e) {
1904                        Slog.w(ActivityManagerService.TAG,
1905                                "Error showing notification for heavy-weight app", e);
1906                    } catch (RemoteException e) {
1907                    }
1908                } catch (NameNotFoundException e) {
1909                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1910                }
1911            } break;
1912            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1913                INotificationManager inm = NotificationManager.getService();
1914                if (inm == null) {
1915                    return;
1916                }
1917                try {
1918                    inm.cancelNotificationWithTag("android", null,
1919                            R.string.heavy_weight_notification,  msg.arg1);
1920                } catch (RuntimeException e) {
1921                    Slog.w(ActivityManagerService.TAG,
1922                            "Error canceling notification for service", e);
1923                } catch (RemoteException e) {
1924                }
1925            } break;
1926            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1927                synchronized (ActivityManagerService.this) {
1928                    checkExcessivePowerUsageLocked(true);
1929                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1930                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1931                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1932                }
1933            } break;
1934            case REPORT_MEM_USAGE_MSG: {
1935                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1936                Thread thread = new Thread() {
1937                    @Override public void run() {
1938                        reportMemUsage(memInfos);
1939                    }
1940                };
1941                thread.start();
1942                break;
1943            }
1944            case REPORT_USER_SWITCH_MSG: {
1945                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1946                break;
1947            }
1948            case CONTINUE_USER_SWITCH_MSG: {
1949                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1950                break;
1951            }
1952            case USER_SWITCH_TIMEOUT_MSG: {
1953                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1954                break;
1955            }
1956            case IMMERSIVE_MODE_LOCK_MSG: {
1957                final boolean nextState = (msg.arg1 != 0);
1958                if (mUpdateLock.isHeld() != nextState) {
1959                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1960                            "Applying new update lock state '" + nextState
1961                            + "' for " + (ActivityRecord)msg.obj);
1962                    if (nextState) {
1963                        mUpdateLock.acquire();
1964                    } else {
1965                        mUpdateLock.release();
1966                    }
1967                }
1968                break;
1969            }
1970            case PERSIST_URI_GRANTS_MSG: {
1971                writeGrantedUriPermissions();
1972                break;
1973            }
1974            case REQUEST_ALL_PSS_MSG: {
1975                synchronized (ActivityManagerService.this) {
1976                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1977                }
1978                break;
1979            }
1980            case START_PROFILES_MSG: {
1981                synchronized (ActivityManagerService.this) {
1982                    mUserController.startProfilesLocked();
1983                }
1984                break;
1985            }
1986            case UPDATE_TIME: {
1987                synchronized (ActivityManagerService.this) {
1988                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1989                        ProcessRecord r = mLruProcesses.get(i);
1990                        if (r.thread != null) {
1991                            try {
1992                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1993                            } catch (RemoteException ex) {
1994                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1995                            }
1996                        }
1997                    }
1998                }
1999                break;
2000            }
2001            case SYSTEM_USER_START_MSG: {
2002                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2003                        Integer.toString(msg.arg1), msg.arg1);
2004                mSystemServiceManager.startUser(msg.arg1);
2005                break;
2006            }
2007            case SYSTEM_USER_UNLOCK_MSG: {
2008                final int userId = msg.arg1;
2009                mSystemServiceManager.unlockUser(userId);
2010                synchronized (ActivityManagerService.this) {
2011                    mRecentTasks.loadUserRecentsLocked(userId);
2012                }
2013                if (userId == UserHandle.USER_SYSTEM) {
2014                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2015                }
2016                installEncryptionUnawareProviders(userId);
2017                mUserController.finishUserUnlocked((UserState) msg.obj);
2018                break;
2019            }
2020            case SYSTEM_USER_CURRENT_MSG: {
2021                mBatteryStatsService.noteEvent(
2022                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2023                        Integer.toString(msg.arg2), msg.arg2);
2024                mBatteryStatsService.noteEvent(
2025                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2026                        Integer.toString(msg.arg1), msg.arg1);
2027                mSystemServiceManager.switchUser(msg.arg1);
2028                break;
2029            }
2030            case ENTER_ANIMATION_COMPLETE_MSG: {
2031                synchronized (ActivityManagerService.this) {
2032                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2033                    if (r != null && r.app != null && r.app.thread != null) {
2034                        try {
2035                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2036                        } catch (RemoteException e) {
2037                        }
2038                    }
2039                }
2040                break;
2041            }
2042            case FINISH_BOOTING_MSG: {
2043                if (msg.arg1 != 0) {
2044                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2045                    finishBooting();
2046                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2047                }
2048                if (msg.arg2 != 0) {
2049                    enableScreenAfterBoot();
2050                }
2051                break;
2052            }
2053            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2054                try {
2055                    Locale l = (Locale) msg.obj;
2056                    IBinder service = ServiceManager.getService("mount");
2057                    IMountService mountService = IMountService.Stub.asInterface(service);
2058                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2059                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2060                } catch (RemoteException e) {
2061                    Log.e(TAG, "Error storing locale for decryption UI", e);
2062                }
2063                break;
2064            }
2065            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2066                synchronized (ActivityManagerService.this) {
2067                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2068                        try {
2069                            // Make a one-way callback to the listener
2070                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2071                        } catch (RemoteException e){
2072                            // Handled by the RemoteCallbackList
2073                        }
2074                    }
2075                    mTaskStackListeners.finishBroadcast();
2076                }
2077                break;
2078            }
2079            case NOTIFY_ACTIVITY_PINNED_LISTENERS_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).onActivityPinned();
2085                        } catch (RemoteException e){
2086                            // Handled by the RemoteCallbackList
2087                        }
2088                    }
2089                    mTaskStackListeners.finishBroadcast();
2090                }
2091                break;
2092            }
2093            case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2094                synchronized (ActivityManagerService.this) {
2095                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2096                        try {
2097                            // Make a one-way callback to the listener
2098                            mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2099                        } catch (RemoteException e){
2100                            // Handled by the RemoteCallbackList
2101                        }
2102                    }
2103                    mTaskStackListeners.finishBroadcast();
2104                }
2105                break;
2106            }
2107            case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2108                synchronized (ActivityManagerService.this) {
2109                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2110                        try {
2111                            // Make a one-way callback to the listener
2112                            mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2113                        } catch (RemoteException e){
2114                            // Handled by the RemoteCallbackList
2115                        }
2116                    }
2117                    mTaskStackListeners.finishBroadcast();
2118                }
2119                break;
2120            }
2121            case NOTIFY_FORCED_RESIZABLE_MSG: {
2122                synchronized (ActivityManagerService.this) {
2123                    for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2124                        try {
2125                            // Make a one-way callback to the listener
2126                            mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2127                                    (String) msg.obj, msg.arg1);
2128                        } catch (RemoteException e){
2129                            // Handled by the RemoteCallbackList
2130                        }
2131                    }
2132                    mTaskStackListeners.finishBroadcast();
2133                }
2134                break;
2135            }
2136                case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2137                    synchronized (ActivityManagerService.this) {
2138                        for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2139                            try {
2140                                // Make a one-way callback to the listener
2141                                mTaskStackListeners.getBroadcastItem(i)
2142                                        .onActivityDismissingDockedStack();
2143                            } catch (RemoteException e){
2144                                // Handled by the RemoteCallbackList
2145                            }
2146                        }
2147                        mTaskStackListeners.finishBroadcast();
2148                    }
2149                    break;
2150                }
2151            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2152                final int uid = msg.arg1;
2153                final byte[] firstPacket = (byte[]) msg.obj;
2154
2155                synchronized (mPidsSelfLocked) {
2156                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2157                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2158                        if (p.uid == uid) {
2159                            try {
2160                                p.thread.notifyCleartextNetwork(firstPacket);
2161                            } catch (RemoteException ignored) {
2162                            }
2163                        }
2164                    }
2165                }
2166                break;
2167            }
2168            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2169                final String procName;
2170                final int uid;
2171                final long memLimit;
2172                final String reportPackage;
2173                synchronized (ActivityManagerService.this) {
2174                    procName = mMemWatchDumpProcName;
2175                    uid = mMemWatchDumpUid;
2176                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2177                    if (val == null) {
2178                        val = mMemWatchProcesses.get(procName, 0);
2179                    }
2180                    if (val != null) {
2181                        memLimit = val.first;
2182                        reportPackage = val.second;
2183                    } else {
2184                        memLimit = 0;
2185                        reportPackage = null;
2186                    }
2187                }
2188                if (procName == null) {
2189                    return;
2190                }
2191
2192                if (DEBUG_PSS) Slog.d(TAG_PSS,
2193                        "Showing dump heap notification from " + procName + "/" + uid);
2194
2195                INotificationManager inm = NotificationManager.getService();
2196                if (inm == null) {
2197                    return;
2198                }
2199
2200                String text = mContext.getString(R.string.dump_heap_notification, procName);
2201
2202
2203                Intent deleteIntent = new Intent();
2204                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2205                Intent intent = new Intent();
2206                intent.setClassName("android", DumpHeapActivity.class.getName());
2207                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2208                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2209                if (reportPackage != null) {
2210                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2211                }
2212                int userId = UserHandle.getUserId(uid);
2213                Notification notification = new Notification.Builder(mContext)
2214                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2215                        .setWhen(0)
2216                        .setOngoing(true)
2217                        .setAutoCancel(true)
2218                        .setTicker(text)
2219                        .setColor(mContext.getColor(
2220                                com.android.internal.R.color.system_notification_accent_color))
2221                        .setContentTitle(text)
2222                        .setContentText(
2223                                mContext.getText(R.string.dump_heap_notification_detail))
2224                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2225                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2226                                new UserHandle(userId)))
2227                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2228                                deleteIntent, 0, UserHandle.SYSTEM))
2229                        .build();
2230
2231                try {
2232                    int[] outId = new int[1];
2233                    inm.enqueueNotificationWithTag("android", "android", null,
2234                            R.string.dump_heap_notification,
2235                            notification, outId, userId);
2236                } catch (RuntimeException e) {
2237                    Slog.w(ActivityManagerService.TAG,
2238                            "Error showing notification for dump heap", e);
2239                } catch (RemoteException e) {
2240                }
2241            } break;
2242            case DELETE_DUMPHEAP_MSG: {
2243                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2244                        DumpHeapActivity.JAVA_URI,
2245                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2246                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2247                        UserHandle.myUserId());
2248                synchronized (ActivityManagerService.this) {
2249                    mMemWatchDumpFile = null;
2250                    mMemWatchDumpProcName = null;
2251                    mMemWatchDumpPid = -1;
2252                    mMemWatchDumpUid = -1;
2253                }
2254            } break;
2255            case FOREGROUND_PROFILE_CHANGED_MSG: {
2256                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2257            } break;
2258            case REPORT_TIME_TRACKER_MSG: {
2259                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2260                tracker.deliverResult(mContext);
2261            } break;
2262            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2263                mUserController.dispatchUserSwitchComplete(msg.arg1);
2264            } break;
2265            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2266                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2267                try {
2268                    connection.shutdown();
2269                } catch (RemoteException e) {
2270                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2271                }
2272                // Only a UiAutomation can set this flag and now that
2273                // it is finished we make sure it is reset to its default.
2274                mUserIsMonkey = false;
2275            } break;
2276            case APP_BOOST_DEACTIVATE_MSG: {
2277                synchronized(ActivityManagerService.this) {
2278                    if (mIsBoosted) {
2279                        if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2280                            nativeMigrateFromBoost();
2281                            mIsBoosted = false;
2282                            mBoostStartTime = 0;
2283                        } else {
2284                            Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2285                            mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2286                        }
2287                    }
2288                }
2289            } break;
2290            case IDLE_UIDS_MSG: {
2291                idleUids();
2292            } break;
2293            case LOG_STACK_STATE: {
2294                synchronized (ActivityManagerService.this) {
2295                    mStackSupervisor.logStackState();
2296                }
2297            } break;
2298            case VR_MODE_CHANGE_MSG: {
2299                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2300                final ActivityRecord r = (ActivityRecord) msg.obj;
2301                boolean vrMode;
2302                ComponentName requestedPackage;
2303                ComponentName callingPackage;
2304                int userId;
2305                synchronized (ActivityManagerService.this) {
2306                    vrMode = r.requestedVrComponent != null;
2307                    requestedPackage = r.requestedVrComponent;
2308                    userId = r.userId;
2309                    callingPackage = r.info.getComponentName();
2310                    if (mInVrMode != vrMode) {
2311                        mInVrMode = vrMode;
2312                        mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2313                    }
2314                }
2315                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2316            } break;
2317            case VR_MODE_APPLY_IF_NEEDED_MSG: {
2318                final ActivityRecord r = (ActivityRecord) msg.obj;
2319                final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2320                if (needsVrMode) {
2321                    applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2322                            r.info.getComponentName(), false);
2323                }
2324            } break;
2325            }
2326        }
2327    };
2328
2329    static final int COLLECT_PSS_BG_MSG = 1;
2330
2331    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2332        @Override
2333        public void handleMessage(Message msg) {
2334            switch (msg.what) {
2335            case COLLECT_PSS_BG_MSG: {
2336                long start = SystemClock.uptimeMillis();
2337                MemInfoReader memInfo = null;
2338                synchronized (ActivityManagerService.this) {
2339                    if (mFullPssPending) {
2340                        mFullPssPending = false;
2341                        memInfo = new MemInfoReader();
2342                    }
2343                }
2344                if (memInfo != null) {
2345                    updateCpuStatsNow();
2346                    long nativeTotalPss = 0;
2347                    synchronized (mProcessCpuTracker) {
2348                        final int N = mProcessCpuTracker.countStats();
2349                        for (int j=0; j<N; j++) {
2350                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2351                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2352                                // This is definitely an application process; skip it.
2353                                continue;
2354                            }
2355                            synchronized (mPidsSelfLocked) {
2356                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2357                                    // This is one of our own processes; skip it.
2358                                    continue;
2359                                }
2360                            }
2361                            nativeTotalPss += Debug.getPss(st.pid, null, null);
2362                        }
2363                    }
2364                    memInfo.readMemInfo();
2365                    synchronized (ActivityManagerService.this) {
2366                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2367                                + (SystemClock.uptimeMillis()-start) + "ms");
2368                        final long cachedKb = memInfo.getCachedSizeKb();
2369                        final long freeKb = memInfo.getFreeSizeKb();
2370                        final long zramKb = memInfo.getZramTotalSizeKb();
2371                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2372                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2373                                kernelKb*1024, nativeTotalPss*1024);
2374                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2375                                nativeTotalPss);
2376                    }
2377                }
2378
2379                int num = 0;
2380                long[] tmp = new long[2];
2381                do {
2382                    ProcessRecord proc;
2383                    int procState;
2384                    int pid;
2385                    long lastPssTime;
2386                    synchronized (ActivityManagerService.this) {
2387                        if (mPendingPssProcesses.size() <= 0) {
2388                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2389                                    "Collected PSS of " + num + " processes in "
2390                                    + (SystemClock.uptimeMillis() - start) + "ms");
2391                            mPendingPssProcesses.clear();
2392                            return;
2393                        }
2394                        proc = mPendingPssProcesses.remove(0);
2395                        procState = proc.pssProcState;
2396                        lastPssTime = proc.lastPssTime;
2397                        if (proc.thread != null && procState == proc.setProcState
2398                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2399                                        < SystemClock.uptimeMillis()) {
2400                            pid = proc.pid;
2401                        } else {
2402                            proc = null;
2403                            pid = 0;
2404                        }
2405                    }
2406                    if (proc != null) {
2407                        long pss = Debug.getPss(pid, tmp, null);
2408                        synchronized (ActivityManagerService.this) {
2409                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2410                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2411                                num++;
2412                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2413                                        SystemClock.uptimeMillis());
2414                            }
2415                        }
2416                    }
2417                } while (true);
2418            }
2419            }
2420        }
2421    };
2422
2423    public void setSystemProcess() {
2424        try {
2425            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2426            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2427            ServiceManager.addService("meminfo", new MemBinder(this));
2428            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2429            ServiceManager.addService("dbinfo", new DbBinder(this));
2430            if (MONITOR_CPU_USAGE) {
2431                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2432            }
2433            ServiceManager.addService("permission", new PermissionController(this));
2434            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2435
2436            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2437                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2438            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2439
2440            synchronized (this) {
2441                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2442                app.persistent = true;
2443                app.pid = MY_PID;
2444                app.maxAdj = ProcessList.SYSTEM_ADJ;
2445                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2446                synchronized (mPidsSelfLocked) {
2447                    mPidsSelfLocked.put(app.pid, app);
2448                }
2449                updateLruProcessLocked(app, false, null);
2450                updateOomAdjLocked();
2451            }
2452        } catch (PackageManager.NameNotFoundException e) {
2453            throw new RuntimeException(
2454                    "Unable to find android system package", e);
2455        }
2456    }
2457
2458    public void setWindowManager(WindowManagerService wm) {
2459        mWindowManager = wm;
2460        mStackSupervisor.setWindowManager(wm);
2461        mActivityStarter.setWindowManager(wm);
2462    }
2463
2464    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2465        mUsageStatsService = usageStatsManager;
2466    }
2467
2468    public void startObservingNativeCrashes() {
2469        final NativeCrashListener ncl = new NativeCrashListener(this);
2470        ncl.start();
2471    }
2472
2473    public IAppOpsService getAppOpsService() {
2474        return mAppOpsService;
2475    }
2476
2477    static class MemBinder extends Binder {
2478        ActivityManagerService mActivityManagerService;
2479        MemBinder(ActivityManagerService activityManagerService) {
2480            mActivityManagerService = activityManagerService;
2481        }
2482
2483        @Override
2484        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2485            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2486                    != PackageManager.PERMISSION_GRANTED) {
2487                pw.println("Permission Denial: can't dump meminfo from from pid="
2488                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2489                        + " without permission " + android.Manifest.permission.DUMP);
2490                return;
2491            }
2492
2493            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2494        }
2495    }
2496
2497    static class GraphicsBinder extends Binder {
2498        ActivityManagerService mActivityManagerService;
2499        GraphicsBinder(ActivityManagerService activityManagerService) {
2500            mActivityManagerService = activityManagerService;
2501        }
2502
2503        @Override
2504        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2505            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2506                    != PackageManager.PERMISSION_GRANTED) {
2507                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2508                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2509                        + " without permission " + android.Manifest.permission.DUMP);
2510                return;
2511            }
2512
2513            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2514        }
2515    }
2516
2517    static class DbBinder extends Binder {
2518        ActivityManagerService mActivityManagerService;
2519        DbBinder(ActivityManagerService activityManagerService) {
2520            mActivityManagerService = activityManagerService;
2521        }
2522
2523        @Override
2524        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2525            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2526                    != PackageManager.PERMISSION_GRANTED) {
2527                pw.println("Permission Denial: can't dump dbinfo from from pid="
2528                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2529                        + " without permission " + android.Manifest.permission.DUMP);
2530                return;
2531            }
2532
2533            mActivityManagerService.dumpDbInfo(fd, pw, args);
2534        }
2535    }
2536
2537    static class CpuBinder extends Binder {
2538        ActivityManagerService mActivityManagerService;
2539        CpuBinder(ActivityManagerService activityManagerService) {
2540            mActivityManagerService = activityManagerService;
2541        }
2542
2543        @Override
2544        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2545            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2546                    != PackageManager.PERMISSION_GRANTED) {
2547                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2548                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2549                        + " without permission " + android.Manifest.permission.DUMP);
2550                return;
2551            }
2552
2553            synchronized (mActivityManagerService.mProcessCpuTracker) {
2554                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2555                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2556                        SystemClock.uptimeMillis()));
2557            }
2558        }
2559    }
2560
2561    public static final class Lifecycle extends SystemService {
2562        private final ActivityManagerService mService;
2563
2564        public Lifecycle(Context context) {
2565            super(context);
2566            mService = new ActivityManagerService(context);
2567        }
2568
2569        @Override
2570        public void onStart() {
2571            mService.start();
2572        }
2573
2574        public ActivityManagerService getService() {
2575            return mService;
2576        }
2577    }
2578
2579    // Note: This method is invoked on the main thread but may need to attach various
2580    // handlers to other threads.  So take care to be explicit about the looper.
2581    public ActivityManagerService(Context systemContext) {
2582        mContext = systemContext;
2583        mFactoryTest = FactoryTest.getMode();
2584        mSystemThread = ActivityThread.currentActivityThread();
2585
2586        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2587
2588        mHandlerThread = new ServiceThread(TAG,
2589                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2590        mHandlerThread.start();
2591        mHandler = new MainHandler(mHandlerThread.getLooper());
2592        mUiHandler = new UiHandler();
2593
2594        /* static; one-time init here */
2595        if (sKillHandler == null) {
2596            sKillThread = new ServiceThread(TAG + ":kill",
2597                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2598            sKillThread.start();
2599            sKillHandler = new KillHandler(sKillThread.getLooper());
2600        }
2601
2602        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2603                "foreground", BROADCAST_FG_TIMEOUT, false);
2604        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2605                "background", BROADCAST_BG_TIMEOUT, true);
2606        mBroadcastQueues[0] = mFgBroadcastQueue;
2607        mBroadcastQueues[1] = mBgBroadcastQueue;
2608
2609        mServices = new ActiveServices(this);
2610        mProviderMap = new ProviderMap(this);
2611        mAppErrors = new AppErrors(mContext, this);
2612
2613        // TODO: Move creation of battery stats service outside of activity manager service.
2614        File dataDir = Environment.getDataDirectory();
2615        File systemDir = new File(dataDir, "system");
2616        systemDir.mkdirs();
2617        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2618        mBatteryStatsService.getActiveStatistics().readLocked();
2619        mBatteryStatsService.scheduleWriteToDisk();
2620        mOnBattery = DEBUG_POWER ? true
2621                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2622        mBatteryStatsService.getActiveStatistics().setCallback(this);
2623
2624        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2625
2626        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2627        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2628                new IAppOpsCallback.Stub() {
2629                    @Override public void opChanged(int op, int uid, String packageName) {
2630                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2631                            if (mAppOpsService.checkOperation(op, uid, packageName)
2632                                    != AppOpsManager.MODE_ALLOWED) {
2633                                runInBackgroundDisabled(uid);
2634                            }
2635                        }
2636                    }
2637                });
2638
2639        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2640
2641        mUserController = new UserController(this);
2642
2643        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2644            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2645
2646        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2647
2648        mConfiguration.setToDefaults();
2649        mConfiguration.setLocales(LocaleList.getDefault());
2650
2651        mConfigurationSeq = mConfiguration.seq = 1;
2652        mProcessCpuTracker.init();
2653
2654        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2655        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2656        mStackSupervisor = new ActivityStackSupervisor(this);
2657        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2658        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2659
2660        mProcessCpuThread = new Thread("CpuTracker") {
2661            @Override
2662            public void run() {
2663                while (true) {
2664                    try {
2665                        try {
2666                            synchronized(this) {
2667                                final long now = SystemClock.uptimeMillis();
2668                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2669                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2670                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2671                                //        + ", write delay=" + nextWriteDelay);
2672                                if (nextWriteDelay < nextCpuDelay) {
2673                                    nextCpuDelay = nextWriteDelay;
2674                                }
2675                                if (nextCpuDelay > 0) {
2676                                    mProcessCpuMutexFree.set(true);
2677                                    this.wait(nextCpuDelay);
2678                                }
2679                            }
2680                        } catch (InterruptedException e) {
2681                        }
2682                        updateCpuStatsNow();
2683                    } catch (Exception e) {
2684                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2685                    }
2686                }
2687            }
2688        };
2689
2690        Watchdog.getInstance().addMonitor(this);
2691        Watchdog.getInstance().addThread(mHandler);
2692    }
2693
2694    public void setSystemServiceManager(SystemServiceManager mgr) {
2695        mSystemServiceManager = mgr;
2696    }
2697
2698    public void setInstaller(Installer installer) {
2699        mInstaller = installer;
2700    }
2701
2702    private void start() {
2703        Process.removeAllProcessGroups();
2704        mProcessCpuThread.start();
2705
2706        mBatteryStatsService.publish(mContext);
2707        mAppOpsService.publish(mContext);
2708        Slog.d("AppOps", "AppOpsService published");
2709        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2710    }
2711
2712    void onUserStoppedLocked(int userId) {
2713        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2714    }
2715
2716    public void initPowerManagement() {
2717        mStackSupervisor.initPowerManagement();
2718        mBatteryStatsService.initPowerManagement();
2719        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2720        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2721        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2722        mVoiceWakeLock.setReferenceCounted(false);
2723    }
2724
2725    @Override
2726    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2727            throws RemoteException {
2728        if (code == SYSPROPS_TRANSACTION) {
2729            // We need to tell all apps about the system property change.
2730            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2731            synchronized(this) {
2732                final int NP = mProcessNames.getMap().size();
2733                for (int ip=0; ip<NP; ip++) {
2734                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2735                    final int NA = apps.size();
2736                    for (int ia=0; ia<NA; ia++) {
2737                        ProcessRecord app = apps.valueAt(ia);
2738                        if (app.thread != null) {
2739                            procs.add(app.thread.asBinder());
2740                        }
2741                    }
2742                }
2743            }
2744
2745            int N = procs.size();
2746            for (int i=0; i<N; i++) {
2747                Parcel data2 = Parcel.obtain();
2748                try {
2749                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2750                } catch (RemoteException e) {
2751                }
2752                data2.recycle();
2753            }
2754        }
2755        try {
2756            return super.onTransact(code, data, reply, flags);
2757        } catch (RuntimeException e) {
2758            // The activity manager only throws security exceptions, so let's
2759            // log all others.
2760            if (!(e instanceof SecurityException)) {
2761                Slog.wtf(TAG, "Activity Manager Crash", e);
2762            }
2763            throw e;
2764        }
2765    }
2766
2767    void updateCpuStats() {
2768        final long now = SystemClock.uptimeMillis();
2769        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2770            return;
2771        }
2772        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2773            synchronized (mProcessCpuThread) {
2774                mProcessCpuThread.notify();
2775            }
2776        }
2777    }
2778
2779    void updateCpuStatsNow() {
2780        synchronized (mProcessCpuTracker) {
2781            mProcessCpuMutexFree.set(false);
2782            final long now = SystemClock.uptimeMillis();
2783            boolean haveNewCpuStats = false;
2784
2785            if (MONITOR_CPU_USAGE &&
2786                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2787                mLastCpuTime.set(now);
2788                mProcessCpuTracker.update();
2789                if (mProcessCpuTracker.hasGoodLastStats()) {
2790                    haveNewCpuStats = true;
2791                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2792                    //Slog.i(TAG, "Total CPU usage: "
2793                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2794
2795                    // Slog the cpu usage if the property is set.
2796                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2797                        int user = mProcessCpuTracker.getLastUserTime();
2798                        int system = mProcessCpuTracker.getLastSystemTime();
2799                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2800                        int irq = mProcessCpuTracker.getLastIrqTime();
2801                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2802                        int idle = mProcessCpuTracker.getLastIdleTime();
2803
2804                        int total = user + system + iowait + irq + softIrq + idle;
2805                        if (total == 0) total = 1;
2806
2807                        EventLog.writeEvent(EventLogTags.CPU,
2808                                ((user+system+iowait+irq+softIrq) * 100) / total,
2809                                (user * 100) / total,
2810                                (system * 100) / total,
2811                                (iowait * 100) / total,
2812                                (irq * 100) / total,
2813                                (softIrq * 100) / total);
2814                    }
2815                }
2816            }
2817
2818            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2819            synchronized(bstats) {
2820                synchronized(mPidsSelfLocked) {
2821                    if (haveNewCpuStats) {
2822                        if (bstats.startAddingCpuLocked()) {
2823                            int totalUTime = 0;
2824                            int totalSTime = 0;
2825                            final int N = mProcessCpuTracker.countStats();
2826                            for (int i=0; i<N; i++) {
2827                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2828                                if (!st.working) {
2829                                    continue;
2830                                }
2831                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2832                                totalUTime += st.rel_utime;
2833                                totalSTime += st.rel_stime;
2834                                if (pr != null) {
2835                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2836                                    if (ps == null || !ps.isActive()) {
2837                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2838                                                pr.info.uid, pr.processName);
2839                                    }
2840                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2841                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2842                                } else {
2843                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2844                                    if (ps == null || !ps.isActive()) {
2845                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2846                                                bstats.mapUid(st.uid), st.name);
2847                                    }
2848                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2849                                }
2850                            }
2851                            final int userTime = mProcessCpuTracker.getLastUserTime();
2852                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2853                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2854                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2855                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2856                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2857                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2858                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2859                        }
2860                    }
2861                }
2862
2863                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2864                    mLastWriteTime = now;
2865                    mBatteryStatsService.scheduleWriteToDisk();
2866                }
2867            }
2868        }
2869    }
2870
2871    @Override
2872    public void batteryNeedsCpuUpdate() {
2873        updateCpuStatsNow();
2874    }
2875
2876    @Override
2877    public void batteryPowerChanged(boolean onBattery) {
2878        // When plugging in, update the CPU stats first before changing
2879        // the plug state.
2880        updateCpuStatsNow();
2881        synchronized (this) {
2882            synchronized(mPidsSelfLocked) {
2883                mOnBattery = DEBUG_POWER ? true : onBattery;
2884            }
2885        }
2886    }
2887
2888    @Override
2889    public void batterySendBroadcast(Intent intent) {
2890        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2891                AppOpsManager.OP_NONE, null, false, false,
2892                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2893    }
2894
2895    /**
2896     * Initialize the application bind args. These are passed to each
2897     * process when the bindApplication() IPC is sent to the process. They're
2898     * lazily setup to make sure the services are running when they're asked for.
2899     */
2900    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2901        if (mAppBindArgs == null) {
2902            mAppBindArgs = new HashMap<>();
2903
2904            // Isolated processes won't get this optimization, so that we don't
2905            // violate the rules about which services they have access to.
2906            if (!isolated) {
2907                // Setup the application init args
2908                mAppBindArgs.put("package", ServiceManager.getService("package"));
2909                mAppBindArgs.put("window", ServiceManager.getService("window"));
2910                mAppBindArgs.put(Context.ALARM_SERVICE,
2911                        ServiceManager.getService(Context.ALARM_SERVICE));
2912            }
2913        }
2914        return mAppBindArgs;
2915    }
2916
2917    boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2918        if (r == null || mFocusedActivity == r) {
2919            return false;
2920        }
2921
2922        if (!r.isFocusable()) {
2923            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2924            return false;
2925        }
2926
2927        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2928
2929        final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2930        if (wasDoingSetFocusedActivity) Slog.w(TAG,
2931                "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2932        mDoingSetFocusedActivity = true;
2933
2934        final ActivityRecord last = mFocusedActivity;
2935        mFocusedActivity = r;
2936        if (r.task.isApplicationTask()) {
2937            if (mCurAppTimeTracker != r.appTimeTracker) {
2938                // We are switching app tracking.  Complete the current one.
2939                if (mCurAppTimeTracker != null) {
2940                    mCurAppTimeTracker.stop();
2941                    mHandler.obtainMessage(
2942                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2943                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2944                    mCurAppTimeTracker = null;
2945                }
2946                if (r.appTimeTracker != null) {
2947                    mCurAppTimeTracker = r.appTimeTracker;
2948                    startTimeTrackingFocusedActivityLocked();
2949                }
2950            } else {
2951                startTimeTrackingFocusedActivityLocked();
2952            }
2953        } else {
2954            r.appTimeTracker = null;
2955        }
2956        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2957        // TODO: Probably not, because we don't want to resume voice on switching
2958        // back to this activity
2959        if (r.task.voiceInteractor != null) {
2960            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2961        } else {
2962            finishRunningVoiceLocked();
2963            IVoiceInteractionSession session;
2964            if (last != null && ((session = last.task.voiceSession) != null
2965                    || (session = last.voiceSession) != null)) {
2966                // We had been in a voice interaction session, but now focused has
2967                // move to something different.  Just finish the session, we can't
2968                // return to it and retain the proper state and synchronization with
2969                // the voice interaction service.
2970                finishVoiceTask(session);
2971            }
2972        }
2973        if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2974            mWindowManager.setFocusedApp(r.appToken, true);
2975        }
2976        applyUpdateLockStateLocked(r);
2977        applyUpdateVrModeLocked(r);
2978        if (mFocusedActivity.userId != mLastFocusedUserId) {
2979            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2980            mHandler.obtainMessage(
2981                    FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2982            mLastFocusedUserId = mFocusedActivity.userId;
2983        }
2984
2985        // Log a warning if the focused app is changed during the process. This could
2986        // indicate a problem of the focus setting logic!
2987        if (mFocusedActivity != r) Slog.w(TAG,
2988                "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2989        mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2990
2991        EventLogTags.writeAmFocusedActivity(
2992                mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2993                mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2994                reason);
2995        return true;
2996    }
2997
2998    final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2999        if (mFocusedActivity != goingAway) {
3000            return;
3001        }
3002
3003        final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3004        if (focusedStack != null) {
3005            final ActivityRecord top = focusedStack.topActivity();
3006            if (top != null && top.userId != mLastFocusedUserId) {
3007                mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3008                mHandler.sendMessage(
3009                        mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3010                mLastFocusedUserId = top.userId;
3011            }
3012        }
3013
3014        // Try to move focus to another activity if possible.
3015        if (setFocusedActivityLocked(
3016                focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3017            return;
3018        }
3019
3020        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3021                + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3022        mFocusedActivity = null;
3023        EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3024    }
3025
3026    @Override
3027    public void setFocusedStack(int stackId) {
3028        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3029        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3030        final long callingId = Binder.clearCallingIdentity();
3031        try {
3032            synchronized (this) {
3033                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3034                if (stack == null) {
3035                    return;
3036                }
3037                final ActivityRecord r = stack.topRunningActivityLocked();
3038                if (setFocusedActivityLocked(r, "setFocusedStack")) {
3039                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3040                }
3041            }
3042        } finally {
3043            Binder.restoreCallingIdentity(callingId);
3044        }
3045    }
3046
3047    @Override
3048    public void setFocusedTask(int taskId) {
3049        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3050        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3051        final long callingId = Binder.clearCallingIdentity();
3052        try {
3053            synchronized (this) {
3054                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3055                if (task == null) {
3056                    return;
3057                }
3058                final ActivityRecord r = task.topRunningActivityLocked();
3059                if (setFocusedActivityLocked(r, "setFocusedTask")) {
3060                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3061                }
3062            }
3063        } finally {
3064            Binder.restoreCallingIdentity(callingId);
3065        }
3066    }
3067
3068    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3069    @Override
3070    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3071        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3072        synchronized (this) {
3073            if (listener != null) {
3074                mTaskStackListeners.register(listener);
3075            }
3076        }
3077    }
3078
3079    @Override
3080    public void notifyActivityDrawn(IBinder token) {
3081        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3082        synchronized (this) {
3083            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3084            if (r != null) {
3085                r.task.stack.notifyActivityDrawnLocked(r);
3086            }
3087        }
3088    }
3089
3090    final void applyUpdateLockStateLocked(ActivityRecord r) {
3091        // Modifications to the UpdateLock state are done on our handler, outside
3092        // the activity manager's locks.  The new state is determined based on the
3093        // state *now* of the relevant activity record.  The object is passed to
3094        // the handler solely for logging detail, not to be consulted/modified.
3095        final boolean nextState = r != null && r.immersive;
3096        mHandler.sendMessage(
3097                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3098    }
3099
3100    final void applyUpdateVrModeLocked(ActivityRecord r) {
3101        mHandler.sendMessage(
3102                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3103    }
3104
3105    private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3106        mHandler.sendMessage(
3107                mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3108    }
3109
3110    private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3111            ComponentName callingPackage, boolean immediate) {
3112        VrManagerInternal vrService =
3113                LocalServices.getService(VrManagerInternal.class);
3114        if (immediate) {
3115            vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3116        } else {
3117            vrService.setVrMode(enabled, packageName, userId, callingPackage);
3118        }
3119    }
3120
3121    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3122        Message msg = Message.obtain();
3123        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3124        msg.obj = r.task.askedCompatMode ? null : r;
3125        mUiHandler.sendMessage(msg);
3126    }
3127
3128    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3129        if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3130                && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3131            final Message msg = Message.obtain();
3132            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3133            msg.obj = r;
3134            mUiHandler.sendMessage(msg);
3135        }
3136    }
3137
3138    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3139            String what, Object obj, ProcessRecord srcApp) {
3140        app.lastActivityTime = now;
3141
3142        if (app.activities.size() > 0) {
3143            // Don't want to touch dependent processes that are hosting activities.
3144            return index;
3145        }
3146
3147        int lrui = mLruProcesses.lastIndexOf(app);
3148        if (lrui < 0) {
3149            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3150                    + what + " " + obj + " from " + srcApp);
3151            return index;
3152        }
3153
3154        if (lrui >= index) {
3155            // Don't want to cause this to move dependent processes *back* in the
3156            // list as if they were less frequently used.
3157            return index;
3158        }
3159
3160        if (lrui >= mLruProcessActivityStart) {
3161            // Don't want to touch dependent processes that are hosting activities.
3162            return index;
3163        }
3164
3165        mLruProcesses.remove(lrui);
3166        if (index > 0) {
3167            index--;
3168        }
3169        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3170                + " in LRU list: " + app);
3171        mLruProcesses.add(index, app);
3172        return index;
3173    }
3174
3175    static void killProcessGroup(int uid, int pid) {
3176        if (sKillHandler != null) {
3177            sKillHandler.sendMessage(
3178                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3179        } else {
3180            Slog.w(TAG, "Asked to kill process group before system bringup!");
3181            Process.killProcessGroup(uid, pid);
3182        }
3183    }
3184
3185    final void removeLruProcessLocked(ProcessRecord app) {
3186        int lrui = mLruProcesses.lastIndexOf(app);
3187        if (lrui >= 0) {
3188            if (!app.killed) {
3189                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3190                Process.killProcessQuiet(app.pid);
3191                killProcessGroup(app.uid, app.pid);
3192            }
3193            if (lrui <= mLruProcessActivityStart) {
3194                mLruProcessActivityStart--;
3195            }
3196            if (lrui <= mLruProcessServiceStart) {
3197                mLruProcessServiceStart--;
3198            }
3199            mLruProcesses.remove(lrui);
3200        }
3201    }
3202
3203    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3204            ProcessRecord client) {
3205        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3206                || app.treatLikeActivity;
3207        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3208        if (!activityChange && hasActivity) {
3209            // The process has activities, so we are only allowing activity-based adjustments
3210            // to move it.  It should be kept in the front of the list with other
3211            // processes that have activities, and we don't want those to change their
3212            // order except due to activity operations.
3213            return;
3214        }
3215
3216        mLruSeq++;
3217        final long now = SystemClock.uptimeMillis();
3218        app.lastActivityTime = now;
3219
3220        // First a quick reject: if the app is already at the position we will
3221        // put it, then there is nothing to do.
3222        if (hasActivity) {
3223            final int N = mLruProcesses.size();
3224            if (N > 0 && mLruProcesses.get(N-1) == app) {
3225                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3226                return;
3227            }
3228        } else {
3229            if (mLruProcessServiceStart > 0
3230                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3231                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3232                return;
3233            }
3234        }
3235
3236        int lrui = mLruProcesses.lastIndexOf(app);
3237
3238        if (app.persistent && lrui >= 0) {
3239            // We don't care about the position of persistent processes, as long as
3240            // they are in the list.
3241            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3242            return;
3243        }
3244
3245        /* In progress: compute new position first, so we can avoid doing work
3246           if the process is not actually going to move.  Not yet working.
3247        int addIndex;
3248        int nextIndex;
3249        boolean inActivity = false, inService = false;
3250        if (hasActivity) {
3251            // Process has activities, put it at the very tipsy-top.
3252            addIndex = mLruProcesses.size();
3253            nextIndex = mLruProcessServiceStart;
3254            inActivity = true;
3255        } else if (hasService) {
3256            // Process has services, put it at the top of the service list.
3257            addIndex = mLruProcessActivityStart;
3258            nextIndex = mLruProcessServiceStart;
3259            inActivity = true;
3260            inService = true;
3261        } else  {
3262            // Process not otherwise of interest, it goes to the top of the non-service area.
3263            addIndex = mLruProcessServiceStart;
3264            if (client != null) {
3265                int clientIndex = mLruProcesses.lastIndexOf(client);
3266                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3267                        + app);
3268                if (clientIndex >= 0 && addIndex > clientIndex) {
3269                    addIndex = clientIndex;
3270                }
3271            }
3272            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3273        }
3274
3275        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3276                + mLruProcessActivityStart + "): " + app);
3277        */
3278
3279        if (lrui >= 0) {
3280            if (lrui < mLruProcessActivityStart) {
3281                mLruProcessActivityStart--;
3282            }
3283            if (lrui < mLruProcessServiceStart) {
3284                mLruProcessServiceStart--;
3285            }
3286            /*
3287            if (addIndex > lrui) {
3288                addIndex--;
3289            }
3290            if (nextIndex > lrui) {
3291                nextIndex--;
3292            }
3293            */
3294            mLruProcesses.remove(lrui);
3295        }
3296
3297        /*
3298        mLruProcesses.add(addIndex, app);
3299        if (inActivity) {
3300            mLruProcessActivityStart++;
3301        }
3302        if (inService) {
3303            mLruProcessActivityStart++;
3304        }
3305        */
3306
3307        int nextIndex;
3308        if (hasActivity) {
3309            final int N = mLruProcesses.size();
3310            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3311                // Process doesn't have activities, but has clients with
3312                // activities...  move it up, but one below the top (the top
3313                // should always have a real activity).
3314                if (DEBUG_LRU) Slog.d(TAG_LRU,
3315                        "Adding to second-top of LRU activity list: " + app);
3316                mLruProcesses.add(N - 1, app);
3317                // To keep it from spamming the LRU list (by making a bunch of clients),
3318                // we will push down any other entries owned by the app.
3319                final int uid = app.info.uid;
3320                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3321                    ProcessRecord subProc = mLruProcesses.get(i);
3322                    if (subProc.info.uid == uid) {
3323                        // We want to push this one down the list.  If the process after
3324                        // it is for the same uid, however, don't do so, because we don't
3325                        // want them internally to be re-ordered.
3326                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3327                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3328                                    "Pushing uid " + uid + " swapping at " + i + ": "
3329                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3330                            ProcessRecord tmp = mLruProcesses.get(i);
3331                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3332                            mLruProcesses.set(i - 1, tmp);
3333                            i--;
3334                        }
3335                    } else {
3336                        // A gap, we can stop here.
3337                        break;
3338                    }
3339                }
3340            } else {
3341                // Process has activities, put it at the very tipsy-top.
3342                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3343                mLruProcesses.add(app);
3344            }
3345            nextIndex = mLruProcessServiceStart;
3346        } else if (hasService) {
3347            // Process has services, put it at the top of the service list.
3348            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3349            mLruProcesses.add(mLruProcessActivityStart, app);
3350            nextIndex = mLruProcessServiceStart;
3351            mLruProcessActivityStart++;
3352        } else  {
3353            // Process not otherwise of interest, it goes to the top of the non-service area.
3354            int index = mLruProcessServiceStart;
3355            if (client != null) {
3356                // If there is a client, don't allow the process to be moved up higher
3357                // in the list than that client.
3358                int clientIndex = mLruProcesses.lastIndexOf(client);
3359                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3360                        + " when updating " + app);
3361                if (clientIndex <= lrui) {
3362                    // Don't allow the client index restriction to push it down farther in the
3363                    // list than it already is.
3364                    clientIndex = lrui;
3365                }
3366                if (clientIndex >= 0 && index > clientIndex) {
3367                    index = clientIndex;
3368                }
3369            }
3370            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3371            mLruProcesses.add(index, app);
3372            nextIndex = index-1;
3373            mLruProcessActivityStart++;
3374            mLruProcessServiceStart++;
3375        }
3376
3377        // If the app is currently using a content provider or service,
3378        // bump those processes as well.
3379        for (int j=app.connections.size()-1; j>=0; j--) {
3380            ConnectionRecord cr = app.connections.valueAt(j);
3381            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3382                    && cr.binding.service.app != null
3383                    && cr.binding.service.app.lruSeq != mLruSeq
3384                    && !cr.binding.service.app.persistent) {
3385                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3386                        "service connection", cr, app);
3387            }
3388        }
3389        for (int j=app.conProviders.size()-1; j>=0; j--) {
3390            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3391            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3392                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3393                        "provider reference", cpr, app);
3394            }
3395        }
3396    }
3397
3398    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3399        if (uid == Process.SYSTEM_UID) {
3400            // The system gets to run in any process.  If there are multiple
3401            // processes with the same uid, just pick the first (this
3402            // should never happen).
3403            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3404            if (procs == null) return null;
3405            final int procCount = procs.size();
3406            for (int i = 0; i < procCount; i++) {
3407                final int procUid = procs.keyAt(i);
3408                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3409                    // Don't use an app process or different user process for system component.
3410                    continue;
3411                }
3412                return procs.valueAt(i);
3413            }
3414        }
3415        ProcessRecord proc = mProcessNames.get(processName, uid);
3416        if (false && proc != null && !keepIfLarge
3417                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3418                && proc.lastCachedPss >= 4000) {
3419            // Turn this condition on to cause killing to happen regularly, for testing.
3420            if (proc.baseProcessTracker != null) {
3421                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3422            }
3423            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3424        } else if (proc != null && !keepIfLarge
3425                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3426                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3427            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3428            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3429                if (proc.baseProcessTracker != null) {
3430                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3431                }
3432                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3433            }
3434        }
3435        return proc;
3436    }
3437
3438    void notifyPackageUse(String packageName, int reason) {
3439        IPackageManager pm = AppGlobals.getPackageManager();
3440        try {
3441            pm.notifyPackageUse(packageName, reason);
3442        } catch (RemoteException e) {
3443        }
3444    }
3445
3446    boolean isNextTransitionForward() {
3447        int transit = mWindowManager.getPendingAppTransition();
3448        return transit == TRANSIT_ACTIVITY_OPEN
3449                || transit == TRANSIT_TASK_OPEN
3450                || transit == TRANSIT_TASK_TO_FRONT;
3451    }
3452
3453    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3454            String processName, String abiOverride, int uid, Runnable crashHandler) {
3455        synchronized(this) {
3456            ApplicationInfo info = new ApplicationInfo();
3457            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3458            // For isolated processes, the former contains the parent's uid and the latter the
3459            // actual uid of the isolated process.
3460            // In the special case introduced by this method (which is, starting an isolated
3461            // process directly from the SystemServer without an actual parent app process) the
3462            // closest thing to a parent's uid is SYSTEM_UID.
3463            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3464            // the |isolated| logic in the ProcessRecord constructor.
3465            info.uid = Process.SYSTEM_UID;
3466            info.processName = processName;
3467            info.className = entryPoint;
3468            info.packageName = "android";
3469            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3470                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3471                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3472                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3473                    crashHandler);
3474            return proc != null ? proc.pid : 0;
3475        }
3476    }
3477
3478    final ProcessRecord startProcessLocked(String processName,
3479            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3480            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3481            boolean isolated, boolean keepIfLarge) {
3482        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3483                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3484                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3485                null /* crashHandler */);
3486    }
3487
3488    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3489            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3490            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3491            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3492        long startTime = SystemClock.elapsedRealtime();
3493        ProcessRecord app;
3494        if (!isolated) {
3495            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3496            checkTime(startTime, "startProcess: after getProcessRecord");
3497
3498            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3499                // If we are in the background, then check to see if this process
3500                // is bad.  If so, we will just silently fail.
3501                if (mAppErrors.isBadProcessLocked(info)) {
3502                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3503                            + "/" + info.processName);
3504                    return null;
3505                }
3506            } else {
3507                // When the user is explicitly starting a process, then clear its
3508                // crash count so that we won't make it bad until they see at
3509                // least one crash dialog again, and make the process good again
3510                // if it had been bad.
3511                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3512                        + "/" + info.processName);
3513                mAppErrors.resetProcessCrashTimeLocked(info);
3514                if (mAppErrors.isBadProcessLocked(info)) {
3515                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3516                            UserHandle.getUserId(info.uid), info.uid,
3517                            info.processName);
3518                    mAppErrors.clearBadProcessLocked(info);
3519                    if (app != null) {
3520                        app.bad = false;
3521                    }
3522                }
3523            }
3524        } else {
3525            // If this is an isolated process, it can't re-use an existing process.
3526            app = null;
3527        }
3528
3529        // app launch boost for big.little configurations
3530        // use cpusets to migrate freshly launched tasks to big cores
3531        nativeMigrateToBoost();
3532        mIsBoosted = true;
3533        mBoostStartTime = SystemClock.uptimeMillis();
3534        Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3535        mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3536
3537        // We don't have to do anything more if:
3538        // (1) There is an existing application record; and
3539        // (2) The caller doesn't think it is dead, OR there is no thread
3540        //     object attached to it so we know it couldn't have crashed; and
3541        // (3) There is a pid assigned to it, so it is either starting or
3542        //     already running.
3543        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3544                + " app=" + app + " knownToBeDead=" + knownToBeDead
3545                + " thread=" + (app != null ? app.thread : null)
3546                + " pid=" + (app != null ? app.pid : -1));
3547        if (app != null && app.pid > 0) {
3548            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3549                // We already have the app running, or are waiting for it to
3550                // come up (we have a pid but not yet its thread), so keep it.
3551                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3552                // If this is a new package in the process, add the package to the list
3553                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3554                checkTime(startTime, "startProcess: done, added package to proc");
3555                return app;
3556            }
3557
3558            // An application record is attached to a previous process,
3559            // clean it up now.
3560            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3561            checkTime(startTime, "startProcess: bad proc running, killing");
3562            killProcessGroup(app.uid, app.pid);
3563            handleAppDiedLocked(app, true, true);
3564            checkTime(startTime, "startProcess: done killing old proc");
3565        }
3566
3567        String hostingNameStr = hostingName != null
3568                ? hostingName.flattenToShortString() : null;
3569
3570        if (app == null) {
3571            checkTime(startTime, "startProcess: creating new process record");
3572            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3573            if (app == null) {
3574                Slog.w(TAG, "Failed making new process record for "
3575                        + processName + "/" + info.uid + " isolated=" + isolated);
3576                return null;
3577            }
3578            app.crashHandler = crashHandler;
3579            checkTime(startTime, "startProcess: done creating new process record");
3580        } else {
3581            // If this is a new package in the process, add the package to the list
3582            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3583            checkTime(startTime, "startProcess: added package to existing proc");
3584        }
3585
3586        // If the system is not ready yet, then hold off on starting this
3587        // process until it is.
3588        if (!mProcessesReady
3589                && !isAllowedWhileBooting(info)
3590                && !allowWhileBooting) {
3591            if (!mProcessesOnHold.contains(app)) {
3592                mProcessesOnHold.add(app);
3593            }
3594            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3595                    "System not ready, putting on hold: " + app);
3596            checkTime(startTime, "startProcess: returning with proc on hold");
3597            return app;
3598        }
3599
3600        checkTime(startTime, "startProcess: stepping in to startProcess");
3601        startProcessLocked(
3602                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3603        checkTime(startTime, "startProcess: done starting proc!");
3604        return (app.pid != 0) ? app : null;
3605    }
3606
3607    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3608        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3609    }
3610
3611    private final void startProcessLocked(ProcessRecord app,
3612            String hostingType, String hostingNameStr) {
3613        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3614                null /* entryPoint */, null /* entryPointArgs */);
3615    }
3616
3617    private final void startProcessLocked(ProcessRecord app, String hostingType,
3618            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3619        long startTime = SystemClock.elapsedRealtime();
3620        if (app.pid > 0 && app.pid != MY_PID) {
3621            checkTime(startTime, "startProcess: removing from pids map");
3622            synchronized (mPidsSelfLocked) {
3623                mPidsSelfLocked.remove(app.pid);
3624                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3625            }
3626            checkTime(startTime, "startProcess: done removing from pids map");
3627            app.setPid(0);
3628        }
3629
3630        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3631                "startProcessLocked removing on hold: " + app);
3632        mProcessesOnHold.remove(app);
3633
3634        checkTime(startTime, "startProcess: starting to update cpu stats");
3635        updateCpuStats();
3636        checkTime(startTime, "startProcess: done updating cpu stats");
3637
3638        try {
3639            try {
3640                final int userId = UserHandle.getUserId(app.uid);
3641                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3642            } catch (RemoteException e) {
3643                throw e.rethrowAsRuntimeException();
3644            }
3645
3646            int uid = app.uid;
3647            int[] gids = null;
3648            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3649            if (!app.isolated) {
3650                int[] permGids = null;
3651                try {
3652                    checkTime(startTime, "startProcess: getting gids from package manager");
3653                    final IPackageManager pm = AppGlobals.getPackageManager();
3654                    permGids = pm.getPackageGids(app.info.packageName,
3655                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3656                    MountServiceInternal mountServiceInternal = LocalServices.getService(
3657                            MountServiceInternal.class);
3658                    mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3659                            app.info.packageName);
3660                } catch (RemoteException e) {
3661                    throw e.rethrowAsRuntimeException();
3662                }
3663
3664                /*
3665                 * Add shared application and profile GIDs so applications can share some
3666                 * resources like shared libraries and access user-wide resources
3667                 */
3668                if (ArrayUtils.isEmpty(permGids)) {
3669                    gids = new int[2];
3670                } else {
3671                    gids = new int[permGids.length + 2];
3672                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3673                }
3674                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3675                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3676            }
3677            checkTime(startTime, "startProcess: building args");
3678            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3679                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3680                        && mTopComponent != null
3681                        && app.processName.equals(mTopComponent.getPackageName())) {
3682                    uid = 0;
3683                }
3684                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3685                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3686                    uid = 0;
3687                }
3688            }
3689            int debugFlags = 0;
3690            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3691                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3692                // Also turn on CheckJNI for debuggable apps. It's quite
3693                // awkward to turn on otherwise.
3694                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3695            }
3696            // Run the app in safe mode if its manifest requests so or the
3697            // system is booted in safe mode.
3698            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3699                mSafeMode == true) {
3700                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3701            }
3702            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3703                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3704            }
3705            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3706            if ("true".equals(genDebugInfoProperty)) {
3707                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3708            }
3709            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3710                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3711            }
3712            if ("1".equals(SystemProperties.get("debug.assert"))) {
3713                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3714            }
3715            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3716                // Enable all debug flags required by the native debugger.
3717                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3718                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3719                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3720                mNativeDebuggingApp = null;
3721            }
3722
3723            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3724            if (requiredAbi == null) {
3725                requiredAbi = Build.SUPPORTED_ABIS[0];
3726            }
3727
3728            String instructionSet = null;
3729            if (app.info.primaryCpuAbi != null) {
3730                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3731            }
3732
3733            app.gids = gids;
3734            app.requiredAbi = requiredAbi;
3735            app.instructionSet = instructionSet;
3736
3737            // Start the process.  It will either succeed and return a result containing
3738            // the PID of the new process, or else throw a RuntimeException.
3739            boolean isActivityProcess = (entryPoint == null);
3740            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3741            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3742                    app.processName);
3743            checkTime(startTime, "startProcess: asking zygote to start proc");
3744            Process.ProcessStartResult startResult = Process.start(entryPoint,
3745                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3746                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3747                    app.info.dataDir, entryPointArgs);
3748            checkTime(startTime, "startProcess: returned from zygote!");
3749            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3750
3751            if (app.isolated) {
3752                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3753            }
3754            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3755            checkTime(startTime, "startProcess: done updating battery stats");
3756
3757            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3758                    UserHandle.getUserId(uid), startResult.pid, uid,
3759                    app.processName, hostingType,
3760                    hostingNameStr != null ? hostingNameStr : "");
3761
3762            try {
3763                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3764                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3765            } catch (RemoteException ex) {
3766                // Ignore
3767            }
3768
3769            if (app.persistent) {
3770                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3771            }
3772
3773            checkTime(startTime, "startProcess: building log message");
3774            StringBuilder buf = mStringBuilder;
3775            buf.setLength(0);
3776            buf.append("Start proc ");
3777            buf.append(startResult.pid);
3778            buf.append(':');
3779            buf.append(app.processName);
3780            buf.append('/');
3781            UserHandle.formatUid(buf, uid);
3782            if (!isActivityProcess) {
3783                buf.append(" [");
3784                buf.append(entryPoint);
3785                buf.append("]");
3786            }
3787            buf.append(" for ");
3788            buf.append(hostingType);
3789            if (hostingNameStr != null) {
3790                buf.append(" ");
3791                buf.append(hostingNameStr);
3792            }
3793            Slog.i(TAG, buf.toString());
3794            app.setPid(startResult.pid);
3795            app.usingWrapper = startResult.usingWrapper;
3796            app.removed = false;
3797            app.killed = false;
3798            app.killedByAm = false;
3799            checkTime(startTime, "startProcess: starting to update pids map");
3800            synchronized (mPidsSelfLocked) {
3801                this.mPidsSelfLocked.put(startResult.pid, app);
3802                if (isActivityProcess) {
3803                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3804                    msg.obj = app;
3805                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3806                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3807                }
3808            }
3809            checkTime(startTime, "startProcess: done updating pids map");
3810        } catch (RuntimeException e) {
3811            Slog.e(TAG, "Failure starting process " + app.processName, e);
3812
3813            // Something went very wrong while trying to start this process; one
3814            // common case is when the package is frozen due to an active
3815            // upgrade. To recover, clean up any active bookkeeping related to
3816            // starting this process. (We already invoked this method once when
3817            // the package was initially frozen through KILL_APPLICATION_MSG, so
3818            // it doesn't hurt to use it again.)
3819            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3820                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3821        }
3822    }
3823
3824    void updateUsageStats(ActivityRecord component, boolean resumed) {
3825        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3826                "updateUsageStats: comp=" + component + "res=" + resumed);
3827        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3828        if (resumed) {
3829            if (mUsageStatsService != null) {
3830                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3831                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3832            }
3833            synchronized (stats) {
3834                stats.noteActivityResumedLocked(component.app.uid);
3835            }
3836        } else {
3837            if (mUsageStatsService != null) {
3838                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3839                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3840            }
3841            synchronized (stats) {
3842                stats.noteActivityPausedLocked(component.app.uid);
3843            }
3844        }
3845    }
3846
3847    Intent getHomeIntent() {
3848        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3849        intent.setComponent(mTopComponent);
3850        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3851        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3852            intent.addCategory(Intent.CATEGORY_HOME);
3853        }
3854        return intent;
3855    }
3856
3857    boolean startHomeActivityLocked(int userId, String reason) {
3858        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3859                && mTopAction == null) {
3860            // We are running in factory test mode, but unable to find
3861            // the factory test app, so just sit around displaying the
3862            // error message and don't try to start anything.
3863            return false;
3864        }
3865        Intent intent = getHomeIntent();
3866        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3867        if (aInfo != null) {
3868            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3869            // Don't do this if the home app is currently being
3870            // instrumented.
3871            aInfo = new ActivityInfo(aInfo);
3872            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3873            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3874                    aInfo.applicationInfo.uid, true);
3875            if (app == null || app.instrumentationClass == null) {
3876                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3877                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3878            }
3879        } else {
3880            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3881        }
3882
3883        return true;
3884    }
3885
3886    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3887        ActivityInfo ai = null;
3888        ComponentName comp = intent.getComponent();
3889        try {
3890            if (comp != null) {
3891                // Factory test.
3892                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3893            } else {
3894                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3895                        intent,
3896                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3897                        flags, userId);
3898
3899                if (info != null) {
3900                    ai = info.activityInfo;
3901                }
3902            }
3903        } catch (RemoteException e) {
3904            // ignore
3905        }
3906
3907        return ai;
3908    }
3909
3910    /**
3911     * Starts the "new version setup screen" if appropriate.
3912     */
3913    void startSetupActivityLocked() {
3914        // Only do this once per boot.
3915        if (mCheckedForSetup) {
3916            return;
3917        }
3918
3919        // We will show this screen if the current one is a different
3920        // version than the last one shown, and we are not running in
3921        // low-level factory test mode.
3922        final ContentResolver resolver = mContext.getContentResolver();
3923        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3924                Settings.Global.getInt(resolver,
3925                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3926            mCheckedForSetup = true;
3927
3928            // See if we should be showing the platform update setup UI.
3929            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3930            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3931                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3932            if (!ris.isEmpty()) {
3933                final ResolveInfo ri = ris.get(0);
3934                String vers = ri.activityInfo.metaData != null
3935                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3936                        : null;
3937                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3938                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3939                            Intent.METADATA_SETUP_VERSION);
3940                }
3941                String lastVers = Settings.Secure.getString(
3942                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3943                if (vers != null && !vers.equals(lastVers)) {
3944                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3945                    intent.setComponent(new ComponentName(
3946                            ri.activityInfo.packageName, ri.activityInfo.name));
3947                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3948                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3949                            null, 0, 0, 0, null, false, false, null, null, null);
3950                }
3951            }
3952        }
3953    }
3954
3955    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3956        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3957    }
3958
3959    void enforceNotIsolatedCaller(String caller) {
3960        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3961            throw new SecurityException("Isolated process not allowed to call " + caller);
3962        }
3963    }
3964
3965    void enforceShellRestriction(String restriction, int userHandle) {
3966        if (Binder.getCallingUid() == Process.SHELL_UID) {
3967            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3968                throw new SecurityException("Shell does not have permission to access user "
3969                        + userHandle);
3970            }
3971        }
3972    }
3973
3974    @Override
3975    public int getFrontActivityScreenCompatMode() {
3976        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3977        synchronized (this) {
3978            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3979        }
3980    }
3981
3982    @Override
3983    public void setFrontActivityScreenCompatMode(int mode) {
3984        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3985                "setFrontActivityScreenCompatMode");
3986        synchronized (this) {
3987            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3988        }
3989    }
3990
3991    @Override
3992    public int getPackageScreenCompatMode(String packageName) {
3993        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3994        synchronized (this) {
3995            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3996        }
3997    }
3998
3999    @Override
4000    public void setPackageScreenCompatMode(String packageName, int mode) {
4001        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4002                "setPackageScreenCompatMode");
4003        synchronized (this) {
4004            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4005        }
4006    }
4007
4008    @Override
4009    public boolean getPackageAskScreenCompat(String packageName) {
4010        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4011        synchronized (this) {
4012            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4013        }
4014    }
4015
4016    @Override
4017    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4018        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4019                "setPackageAskScreenCompat");
4020        synchronized (this) {
4021            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4022        }
4023    }
4024
4025    private boolean hasUsageStatsPermission(String callingPackage) {
4026        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4027                Binder.getCallingUid(), callingPackage);
4028        if (mode == AppOpsManager.MODE_DEFAULT) {
4029            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4030                    == PackageManager.PERMISSION_GRANTED;
4031        }
4032        return mode == AppOpsManager.MODE_ALLOWED;
4033    }
4034
4035    @Override
4036    public int getPackageProcessState(String packageName, String callingPackage) {
4037        if (!hasUsageStatsPermission(callingPackage)) {
4038            enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4039                    "getPackageProcessState");
4040        }
4041
4042        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4043        synchronized (this) {
4044            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4045                final ProcessRecord proc = mLruProcesses.get(i);
4046                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4047                        || procState > proc.setProcState) {
4048                    boolean found = false;
4049                    for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4050                        if (proc.pkgList.keyAt(j).equals(packageName)) {
4051                            procState = proc.setProcState;
4052                            found = true;
4053                        }
4054                    }
4055                    if (proc.pkgDeps != null && !found) {
4056                        for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4057                            if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4058                                procState = proc.setProcState;
4059                                break;
4060                            }
4061                        }
4062                    }
4063                }
4064            }
4065        }
4066        return procState;
4067    }
4068
4069    @Override
4070    public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4071        synchronized (this) {
4072            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4073            if (app == null) {
4074                return false;
4075            }
4076            if (app.trimMemoryLevel < level && app.thread != null &&
4077                    (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4078                            app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4079                try {
4080                    app.thread.scheduleTrimMemory(level);
4081                    app.trimMemoryLevel = level;
4082                    return true;
4083                } catch (RemoteException e) {
4084                    // Fallthrough to failure case.
4085                }
4086            }
4087        }
4088        return false;
4089    }
4090
4091    private void dispatchProcessesChanged() {
4092        int N;
4093        synchronized (this) {
4094            N = mPendingProcessChanges.size();
4095            if (mActiveProcessChanges.length < N) {
4096                mActiveProcessChanges = new ProcessChangeItem[N];
4097            }
4098            mPendingProcessChanges.toArray(mActiveProcessChanges);
4099            mPendingProcessChanges.clear();
4100            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4101                    "*** Delivering " + N + " process changes");
4102        }
4103
4104        int i = mProcessObservers.beginBroadcast();
4105        while (i > 0) {
4106            i--;
4107            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4108            if (observer != null) {
4109                try {
4110                    for (int j=0; j<N; j++) {
4111                        ProcessChangeItem item = mActiveProcessChanges[j];
4112                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4113                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4114                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4115                                    + item.uid + ": " + item.foregroundActivities);
4116                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4117                                    item.foregroundActivities);
4118                        }
4119                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4120                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4121                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4122                                    + ": " + item.processState);
4123                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4124                        }
4125                    }
4126                } catch (RemoteException e) {
4127                }
4128            }
4129        }
4130        mProcessObservers.finishBroadcast();
4131
4132        synchronized (this) {
4133            for (int j=0; j<N; j++) {
4134                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4135            }
4136        }
4137    }
4138
4139    private void dispatchProcessDied(int pid, int uid) {
4140        int i = mProcessObservers.beginBroadcast();
4141        while (i > 0) {
4142            i--;
4143            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4144            if (observer != null) {
4145                try {
4146                    observer.onProcessDied(pid, uid);
4147                } catch (RemoteException e) {
4148                }
4149            }
4150        }
4151        mProcessObservers.finishBroadcast();
4152    }
4153
4154    private void dispatchUidsChanged() {
4155        int N;
4156        synchronized (this) {
4157            N = mPendingUidChanges.size();
4158            if (mActiveUidChanges.length < N) {
4159                mActiveUidChanges = new UidRecord.ChangeItem[N];
4160            }
4161            for (int i=0; i<N; i++) {
4162                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4163                mActiveUidChanges[i] = change;
4164                if (change.uidRecord != null) {
4165                    change.uidRecord.pendingChange = null;
4166                    change.uidRecord = null;
4167                }
4168            }
4169            mPendingUidChanges.clear();
4170            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4171                    "*** Delivering " + N + " uid changes");
4172        }
4173
4174        if (mLocalPowerManager != null) {
4175            for (int j=0; j<N; j++) {
4176                UidRecord.ChangeItem item = mActiveUidChanges[j];
4177                if (item.change == UidRecord.CHANGE_GONE
4178                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4179                    mLocalPowerManager.uidGone(item.uid);
4180                } else {
4181                    mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4182                }
4183            }
4184        }
4185
4186        int i = mUidObservers.beginBroadcast();
4187        while (i > 0) {
4188            i--;
4189            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4190            final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4191            if (observer != null) {
4192                try {
4193                    for (int j=0; j<N; j++) {
4194                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4195                        final int change = item.change;
4196                        UidRecord validateUid = null;
4197                        if (VALIDATE_UID_STATES && i == 0) {
4198                            validateUid = mValidateUids.get(item.uid);
4199                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4200                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4201                                validateUid = new UidRecord(item.uid);
4202                                mValidateUids.put(item.uid, validateUid);
4203                            }
4204                        }
4205                        if (change == UidRecord.CHANGE_IDLE
4206                                || change == UidRecord.CHANGE_GONE_IDLE) {
4207                            if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4208                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4209                                        "UID idle uid=" + item.uid);
4210                                observer.onUidIdle(item.uid);
4211                            }
4212                            if (VALIDATE_UID_STATES && i == 0) {
4213                                if (validateUid != null) {
4214                                    validateUid.idle = true;
4215                                }
4216                            }
4217                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4218                            if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4219                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4220                                        "UID active uid=" + item.uid);
4221                                observer.onUidActive(item.uid);
4222                            }
4223                            if (VALIDATE_UID_STATES && i == 0) {
4224                                validateUid.idle = false;
4225                            }
4226                        }
4227                        if (change == UidRecord.CHANGE_GONE
4228                                || change == UidRecord.CHANGE_GONE_IDLE) {
4229                            if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4230                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4231                                        "UID gone uid=" + item.uid);
4232                                observer.onUidGone(item.uid);
4233                            }
4234                            if (VALIDATE_UID_STATES && i == 0) {
4235                                if (validateUid != null) {
4236                                    mValidateUids.remove(item.uid);
4237                                }
4238                            }
4239                        } else {
4240                            if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4241                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4242                                        "UID CHANGED uid=" + item.uid
4243                                                + ": " + item.processState);
4244                                observer.onUidStateChanged(item.uid, item.processState);
4245                            }
4246                            if (VALIDATE_UID_STATES && i == 0) {
4247                                validateUid.curProcState = validateUid.setProcState
4248                                        = item.processState;
4249                            }
4250                        }
4251                    }
4252                } catch (RemoteException e) {
4253                }
4254            }
4255        }
4256        mUidObservers.finishBroadcast();
4257
4258        synchronized (this) {
4259            for (int j=0; j<N; j++) {
4260                mAvailUidChanges.add(mActiveUidChanges[j]);
4261            }
4262        }
4263    }
4264
4265    @Override
4266    public final int startActivity(IApplicationThread caller, String callingPackage,
4267            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4268            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4269        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4270                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4271                UserHandle.getCallingUserId());
4272    }
4273
4274    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4275        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4276        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4277                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4278                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4279
4280        // TODO: Switch to user app stacks here.
4281        String mimeType = intent.getType();
4282        final Uri data = intent.getData();
4283        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4284            mimeType = getProviderMimeType(data, userId);
4285        }
4286        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4287
4288        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4289        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4290                null, 0, 0, null, null, null, null, false, userId, container, null);
4291    }
4292
4293    @Override
4294    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4295            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4296            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4297        enforceNotIsolatedCaller("startActivity");
4298        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4299                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4300        // TODO: Switch to user app stacks here.
4301        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4302                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4303                profilerInfo, null, null, bOptions, false, userId, null, null);
4304    }
4305
4306    @Override
4307    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4308            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4309            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4310            int userId) {
4311
4312        // This is very dangerous -- it allows you to perform a start activity (including
4313        // permission grants) as any app that may launch one of your own activities.  So
4314        // we will only allow this to be done from activities that are part of the core framework,
4315        // and then only when they are running as the system.
4316        final ActivityRecord sourceRecord;
4317        final int targetUid;
4318        final String targetPackage;
4319        synchronized (this) {
4320            if (resultTo == null) {
4321                throw new SecurityException("Must be called from an activity");
4322            }
4323            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4324            if (sourceRecord == null) {
4325                throw new SecurityException("Called with bad activity token: " + resultTo);
4326            }
4327            if (!sourceRecord.info.packageName.equals("android")) {
4328                throw new SecurityException(
4329                        "Must be called from an activity that is declared in the android package");
4330            }
4331            if (sourceRecord.app == null) {
4332                throw new SecurityException("Called without a process attached to activity");
4333            }
4334            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4335                // This is still okay, as long as this activity is running under the
4336                // uid of the original calling activity.
4337                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4338                    throw new SecurityException(
4339                            "Calling activity in uid " + sourceRecord.app.uid
4340                                    + " must be system uid or original calling uid "
4341                                    + sourceRecord.launchedFromUid);
4342                }
4343            }
4344            if (ignoreTargetSecurity) {
4345                if (intent.getComponent() == null) {
4346                    throw new SecurityException(
4347                            "Component must be specified with ignoreTargetSecurity");
4348                }
4349                if (intent.getSelector() != null) {
4350                    throw new SecurityException(
4351                            "Selector not allowed with ignoreTargetSecurity");
4352                }
4353            }
4354            targetUid = sourceRecord.launchedFromUid;
4355            targetPackage = sourceRecord.launchedFromPackage;
4356        }
4357
4358        if (userId == UserHandle.USER_NULL) {
4359            userId = UserHandle.getUserId(sourceRecord.app.uid);
4360        }
4361
4362        // TODO: Switch to user app stacks here.
4363        try {
4364            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4365                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4366                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4367            return ret;
4368        } catch (SecurityException e) {
4369            // XXX need to figure out how to propagate to original app.
4370            // A SecurityException here is generally actually a fault of the original
4371            // calling activity (such as a fairly granting permissions), so propagate it
4372            // back to them.
4373            /*
4374            StringBuilder msg = new StringBuilder();
4375            msg.append("While launching");
4376            msg.append(intent.toString());
4377            msg.append(": ");
4378            msg.append(e.getMessage());
4379            */
4380            throw e;
4381        }
4382    }
4383
4384    @Override
4385    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4386            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4387            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4388        enforceNotIsolatedCaller("startActivityAndWait");
4389        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4390                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4391        WaitResult res = new WaitResult();
4392        // TODO: Switch to user app stacks here.
4393        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4394                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4395                bOptions, false, userId, null, null);
4396        return res;
4397    }
4398
4399    @Override
4400    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4401            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4402            int startFlags, Configuration config, Bundle bOptions, int userId) {
4403        enforceNotIsolatedCaller("startActivityWithConfig");
4404        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4405                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4406        // TODO: Switch to user app stacks here.
4407        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4408                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4409                null, null, config, bOptions, false, userId, null, null);
4410        return ret;
4411    }
4412
4413    @Override
4414    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4415            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4416            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4417            throws TransactionTooLargeException {
4418        enforceNotIsolatedCaller("startActivityIntentSender");
4419        // Refuse possible leaked file descriptors
4420        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4421            throw new IllegalArgumentException("File descriptors passed in Intent");
4422        }
4423
4424        IIntentSender sender = intent.getTarget();
4425        if (!(sender instanceof PendingIntentRecord)) {
4426            throw new IllegalArgumentException("Bad PendingIntent object");
4427        }
4428
4429        PendingIntentRecord pir = (PendingIntentRecord)sender;
4430
4431        synchronized (this) {
4432            // If this is coming from the currently resumed activity, it is
4433            // effectively saying that app switches are allowed at this point.
4434            final ActivityStack stack = getFocusedStack();
4435            if (stack.mResumedActivity != null &&
4436                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4437                mAppSwitchesAllowedTime = 0;
4438            }
4439        }
4440        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4441                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4442        return ret;
4443    }
4444
4445    @Override
4446    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4447            Intent intent, String resolvedType, IVoiceInteractionSession session,
4448            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4449            Bundle bOptions, int userId) {
4450        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4451                != PackageManager.PERMISSION_GRANTED) {
4452            String msg = "Permission Denial: startVoiceActivity() from pid="
4453                    + Binder.getCallingPid()
4454                    + ", uid=" + Binder.getCallingUid()
4455                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4456            Slog.w(TAG, msg);
4457            throw new SecurityException(msg);
4458        }
4459        if (session == null || interactor == null) {
4460            throw new NullPointerException("null session or interactor");
4461        }
4462        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4463                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4464        // TODO: Switch to user app stacks here.
4465        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4466                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4467                null, bOptions, false, userId, null, null);
4468    }
4469
4470    @Override
4471    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4472            throws RemoteException {
4473        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4474        synchronized (this) {
4475            ActivityRecord activity = getFocusedStack().topActivity();
4476            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4477                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4478            }
4479            if (mRunningVoice != null || activity.task.voiceSession != null
4480                    || activity.voiceSession != null) {
4481                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4482                return;
4483            }
4484            if (activity.pendingVoiceInteractionStart) {
4485                Slog.w(TAG, "Pending start of voice interaction already.");
4486                return;
4487            }
4488            activity.pendingVoiceInteractionStart = true;
4489        }
4490        LocalServices.getService(VoiceInteractionManagerInternal.class)
4491                .startLocalVoiceInteraction(callingActivity, options);
4492    }
4493
4494    @Override
4495    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4496        LocalServices.getService(VoiceInteractionManagerInternal.class)
4497                .stopLocalVoiceInteraction(callingActivity);
4498    }
4499
4500    @Override
4501    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4502        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4503                .supportsLocalVoiceInteraction();
4504    }
4505
4506    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4507            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4508        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4509        if (activityToCallback == null) return;
4510        activityToCallback.setVoiceSessionLocked(voiceSession);
4511
4512        // Inform the activity
4513        try {
4514            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4515                    voiceInteractor);
4516            long token = Binder.clearCallingIdentity();
4517            try {
4518                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4519            } finally {
4520                Binder.restoreCallingIdentity(token);
4521            }
4522            // TODO: VI Should we cache the activity so that it's easier to find later
4523            // rather than scan through all the stacks and activities?
4524        } catch (RemoteException re) {
4525            activityToCallback.clearVoiceSessionLocked();
4526            // TODO: VI Should this terminate the voice session?
4527        }
4528    }
4529
4530    @Override
4531    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4532        synchronized (this) {
4533            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4534                if (keepAwake) {
4535                    mVoiceWakeLock.acquire();
4536                } else {
4537                    mVoiceWakeLock.release();
4538                }
4539            }
4540        }
4541    }
4542
4543    @Override
4544    public boolean startNextMatchingActivity(IBinder callingActivity,
4545            Intent intent, Bundle bOptions) {
4546        // Refuse possible leaked file descriptors
4547        if (intent != null && intent.hasFileDescriptors() == true) {
4548            throw new IllegalArgumentException("File descriptors passed in Intent");
4549        }
4550        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4551
4552        synchronized (this) {
4553            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4554            if (r == null) {
4555                ActivityOptions.abort(options);
4556                return false;
4557            }
4558            if (r.app == null || r.app.thread == null) {
4559                // The caller is not running...  d'oh!
4560                ActivityOptions.abort(options);
4561                return false;
4562            }
4563            intent = new Intent(intent);
4564            // The caller is not allowed to change the data.
4565            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4566            // And we are resetting to find the next component...
4567            intent.setComponent(null);
4568
4569            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4570
4571            ActivityInfo aInfo = null;
4572            try {
4573                List<ResolveInfo> resolves =
4574                    AppGlobals.getPackageManager().queryIntentActivities(
4575                            intent, r.resolvedType,
4576                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4577                            UserHandle.getCallingUserId()).getList();
4578
4579                // Look for the original activity in the list...
4580                final int N = resolves != null ? resolves.size() : 0;
4581                for (int i=0; i<N; i++) {
4582                    ResolveInfo rInfo = resolves.get(i);
4583                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4584                            && rInfo.activityInfo.name.equals(r.info.name)) {
4585                        // We found the current one...  the next matching is
4586                        // after it.
4587                        i++;
4588                        if (i<N) {
4589                            aInfo = resolves.get(i).activityInfo;
4590                        }
4591                        if (debug) {
4592                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4593                                    + "/" + r.info.name);
4594                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4595                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4596                        }
4597                        break;
4598                    }
4599                }
4600            } catch (RemoteException e) {
4601            }
4602
4603            if (aInfo == null) {
4604                // Nobody who is next!
4605                ActivityOptions.abort(options);
4606                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4607                return false;
4608            }
4609
4610            intent.setComponent(new ComponentName(
4611                    aInfo.applicationInfo.packageName, aInfo.name));
4612            intent.setFlags(intent.getFlags()&~(
4613                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4614                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4615                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4616                    Intent.FLAG_ACTIVITY_NEW_TASK));
4617
4618            // Okay now we need to start the new activity, replacing the
4619            // currently running activity.  This is a little tricky because
4620            // we want to start the new one as if the current one is finished,
4621            // but not finish the current one first so that there is no flicker.
4622            // And thus...
4623            final boolean wasFinishing = r.finishing;
4624            r.finishing = true;
4625
4626            // Propagate reply information over to the new activity.
4627            final ActivityRecord resultTo = r.resultTo;
4628            final String resultWho = r.resultWho;
4629            final int requestCode = r.requestCode;
4630            r.resultTo = null;
4631            if (resultTo != null) {
4632                resultTo.removeResultsLocked(r, resultWho, requestCode);
4633            }
4634
4635            final long origId = Binder.clearCallingIdentity();
4636            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4637                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4638                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4639                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4640                    false, false, null, null, null);
4641            Binder.restoreCallingIdentity(origId);
4642
4643            r.finishing = wasFinishing;
4644            if (res != ActivityManager.START_SUCCESS) {
4645                return false;
4646            }
4647            return true;
4648        }
4649    }
4650
4651    @Override
4652    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4653        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4654            String msg = "Permission Denial: startActivityFromRecents called without " +
4655                    START_TASKS_FROM_RECENTS;
4656            Slog.w(TAG, msg);
4657            throw new SecurityException(msg);
4658        }
4659        final long origId = Binder.clearCallingIdentity();
4660        try {
4661            synchronized (this) {
4662                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4663            }
4664        } finally {
4665            Binder.restoreCallingIdentity(origId);
4666        }
4667    }
4668
4669    final int startActivityInPackage(int uid, String callingPackage,
4670            Intent intent, String resolvedType, IBinder resultTo,
4671            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4672            IActivityContainer container, TaskRecord inTask) {
4673
4674        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4675                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4676
4677        // TODO: Switch to user app stacks here.
4678        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4679                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4680                null, null, null, bOptions, false, userId, container, inTask);
4681        return ret;
4682    }
4683
4684    @Override
4685    public final int startActivities(IApplicationThread caller, String callingPackage,
4686            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4687            int userId) {
4688        enforceNotIsolatedCaller("startActivities");
4689        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4690                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4691        // TODO: Switch to user app stacks here.
4692        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4693                resolvedTypes, resultTo, bOptions, userId);
4694        return ret;
4695    }
4696
4697    final int startActivitiesInPackage(int uid, String callingPackage,
4698            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4699            Bundle bOptions, int userId) {
4700
4701        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4702                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4703        // TODO: Switch to user app stacks here.
4704        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4705                resultTo, bOptions, userId);
4706        return ret;
4707    }
4708
4709    @Override
4710    public void reportActivityFullyDrawn(IBinder token) {
4711        synchronized (this) {
4712            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4713            if (r == null) {
4714                return;
4715            }
4716            r.reportFullyDrawnLocked();
4717        }
4718    }
4719
4720    @Override
4721    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4722        synchronized (this) {
4723            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4724            if (r == null) {
4725                return;
4726            }
4727            TaskRecord task = r.task;
4728            if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4729                // Fixed screen orientation isn't supported when activities aren't in full screen
4730                // mode.
4731                return;
4732            }
4733            final long origId = Binder.clearCallingIdentity();
4734            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4735            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4736                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4737            if (config != null) {
4738                r.frozenBeforeDestroy = true;
4739                if (!updateConfigurationLocked(config, r, false)) {
4740                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
4741                }
4742            }
4743            Binder.restoreCallingIdentity(origId);
4744        }
4745    }
4746
4747    @Override
4748    public int getRequestedOrientation(IBinder token) {
4749        synchronized (this) {
4750            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4751            if (r == null) {
4752                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4753            }
4754            return mWindowManager.getAppOrientation(r.appToken);
4755        }
4756    }
4757
4758    /**
4759     * This is the internal entry point for handling Activity.finish().
4760     *
4761     * @param token The Binder token referencing the Activity we want to finish.
4762     * @param resultCode Result code, if any, from this Activity.
4763     * @param resultData Result data (Intent), if any, from this Activity.
4764     * @param finishTask Whether to finish the task associated with this Activity.
4765     *
4766     * @return Returns true if the activity successfully finished, or false if it is still running.
4767     */
4768    @Override
4769    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4770            int finishTask) {
4771        // Refuse possible leaked file descriptors
4772        if (resultData != null && resultData.hasFileDescriptors() == true) {
4773            throw new IllegalArgumentException("File descriptors passed in Intent");
4774        }
4775
4776        synchronized(this) {
4777            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4778            if (r == null) {
4779                return true;
4780            }
4781            // Keep track of the root activity of the task before we finish it
4782            TaskRecord tr = r.task;
4783            ActivityRecord rootR = tr.getRootActivity();
4784            if (rootR == null) {
4785                Slog.w(TAG, "Finishing task with all activities already finished");
4786            }
4787            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4788            // finish.
4789            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4790                    mStackSupervisor.isLastLockedTask(tr)) {
4791                Slog.i(TAG, "Not finishing task in lock task mode");
4792                mStackSupervisor.showLockTaskToast();
4793                return false;
4794            }
4795            if (mController != null) {
4796                // Find the first activity that is not finishing.
4797                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4798                if (next != null) {
4799                    // ask watcher if this is allowed
4800                    boolean resumeOK = true;
4801                    try {
4802                        resumeOK = mController.activityResuming(next.packageName);
4803                    } catch (RemoteException e) {
4804                        mController = null;
4805                        Watchdog.getInstance().setActivityController(null);
4806                    }
4807
4808                    if (!resumeOK) {
4809                        Slog.i(TAG, "Not finishing activity because controller resumed");
4810                        return false;
4811                    }
4812                }
4813            }
4814            final long origId = Binder.clearCallingIdentity();
4815            try {
4816                boolean res;
4817                final boolean finishWithRootActivity =
4818                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4819                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4820                        || (finishWithRootActivity && r == rootR)) {
4821                    // If requested, remove the task that is associated to this activity only if it
4822                    // was the root activity in the task. The result code and data is ignored
4823                    // because we don't support returning them across task boundaries. Also, to
4824                    // keep backwards compatibility we remove the task from recents when finishing
4825                    // task with root activity.
4826                    res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4827                    if (!res) {
4828                        Slog.i(TAG, "Removing task failed to finish activity");
4829                    }
4830                } else {
4831                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4832                            resultData, "app-request", true);
4833                    if (!res) {
4834                        Slog.i(TAG, "Failed to finish by app-request");
4835                    }
4836                }
4837                return res;
4838            } finally {
4839                Binder.restoreCallingIdentity(origId);
4840            }
4841        }
4842    }
4843
4844    @Override
4845    public final void finishHeavyWeightApp() {
4846        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4847                != PackageManager.PERMISSION_GRANTED) {
4848            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4849                    + Binder.getCallingPid()
4850                    + ", uid=" + Binder.getCallingUid()
4851                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4852            Slog.w(TAG, msg);
4853            throw new SecurityException(msg);
4854        }
4855
4856        synchronized(this) {
4857            if (mHeavyWeightProcess == null) {
4858                return;
4859            }
4860
4861            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4862            for (int i = 0; i < activities.size(); i++) {
4863                ActivityRecord r = activities.get(i);
4864                if (!r.finishing && r.isInStackLocked()) {
4865                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4866                            null, "finish-heavy", true);
4867                }
4868            }
4869
4870            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4871                    mHeavyWeightProcess.userId, 0));
4872            mHeavyWeightProcess = null;
4873        }
4874    }
4875
4876    @Override
4877    public void crashApplication(int uid, int initialPid, String packageName,
4878            String message) {
4879        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4880                != PackageManager.PERMISSION_GRANTED) {
4881            String msg = "Permission Denial: crashApplication() from pid="
4882                    + Binder.getCallingPid()
4883                    + ", uid=" + Binder.getCallingUid()
4884                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4885            Slog.w(TAG, msg);
4886            throw new SecurityException(msg);
4887        }
4888
4889        synchronized(this) {
4890            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4891        }
4892    }
4893
4894    @Override
4895    public final void finishSubActivity(IBinder token, String resultWho,
4896            int requestCode) {
4897        synchronized(this) {
4898            final long origId = Binder.clearCallingIdentity();
4899            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4900            if (r != null) {
4901                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4902            }
4903            Binder.restoreCallingIdentity(origId);
4904        }
4905    }
4906
4907    @Override
4908    public boolean finishActivityAffinity(IBinder token) {
4909        synchronized(this) {
4910            final long origId = Binder.clearCallingIdentity();
4911            try {
4912                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4913                if (r == null) {
4914                    return false;
4915                }
4916
4917                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4918                // can finish.
4919                final TaskRecord task = r.task;
4920                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4921                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4922                    mStackSupervisor.showLockTaskToast();
4923                    return false;
4924                }
4925                return task.stack.finishActivityAffinityLocked(r);
4926            } finally {
4927                Binder.restoreCallingIdentity(origId);
4928            }
4929        }
4930    }
4931
4932    @Override
4933    public void finishVoiceTask(IVoiceInteractionSession session) {
4934        synchronized (this) {
4935            final long origId = Binder.clearCallingIdentity();
4936            try {
4937                // TODO: VI Consider treating local voice interactions and voice tasks
4938                // differently here
4939                mStackSupervisor.finishVoiceTask(session);
4940            } finally {
4941                Binder.restoreCallingIdentity(origId);
4942            }
4943        }
4944
4945    }
4946
4947    @Override
4948    public boolean releaseActivityInstance(IBinder token) {
4949        synchronized(this) {
4950            final long origId = Binder.clearCallingIdentity();
4951            try {
4952                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4953                if (r == null) {
4954                    return false;
4955                }
4956                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4957            } finally {
4958                Binder.restoreCallingIdentity(origId);
4959            }
4960        }
4961    }
4962
4963    @Override
4964    public void releaseSomeActivities(IApplicationThread appInt) {
4965        synchronized(this) {
4966            final long origId = Binder.clearCallingIdentity();
4967            try {
4968                ProcessRecord app = getRecordForAppLocked(appInt);
4969                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4970            } finally {
4971                Binder.restoreCallingIdentity(origId);
4972            }
4973        }
4974    }
4975
4976    @Override
4977    public boolean willActivityBeVisible(IBinder token) {
4978        synchronized(this) {
4979            ActivityStack stack = ActivityRecord.getStackLocked(token);
4980            if (stack != null) {
4981                return stack.willActivityBeVisibleLocked(token);
4982            }
4983            return false;
4984        }
4985    }
4986
4987    @Override
4988    public void overridePendingTransition(IBinder token, String packageName,
4989            int enterAnim, int exitAnim) {
4990        synchronized(this) {
4991            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4992            if (self == null) {
4993                return;
4994            }
4995
4996            final long origId = Binder.clearCallingIdentity();
4997
4998            if (self.state == ActivityState.RESUMED
4999                    || self.state == ActivityState.PAUSING) {
5000                mWindowManager.overridePendingAppTransition(packageName,
5001                        enterAnim, exitAnim, null);
5002            }
5003
5004            Binder.restoreCallingIdentity(origId);
5005        }
5006    }
5007
5008    /**
5009     * Main function for removing an existing process from the activity manager
5010     * as a result of that process going away.  Clears out all connections
5011     * to the process.
5012     */
5013    private final void handleAppDiedLocked(ProcessRecord app,
5014            boolean restarting, boolean allowRestart) {
5015        int pid = app.pid;
5016        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
5017        if (!kept && !restarting) {
5018            removeLruProcessLocked(app);
5019            if (pid > 0) {
5020                ProcessList.remove(pid);
5021            }
5022        }
5023
5024        if (mProfileProc == app) {
5025            clearProfilerLocked();
5026        }
5027
5028        // Remove this application's activities from active lists.
5029        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5030
5031        app.activities.clear();
5032
5033        if (app.instrumentationClass != null) {
5034            Slog.w(TAG, "Crash of app " + app.processName
5035                  + " running instrumentation " + app.instrumentationClass);
5036            Bundle info = new Bundle();
5037            info.putString("shortMsg", "Process crashed.");
5038            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5039        }
5040
5041        if (!restarting && hasVisibleActivities
5042                && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5043            // If there was nothing to resume, and we are not already restarting this process, but
5044            // there is a visible activity that is hosted by the process...  then make sure all
5045            // visible activities are running, taking care of restarting this process.
5046            mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5047        }
5048    }
5049
5050    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5051        IBinder threadBinder = thread.asBinder();
5052        // Find the application record.
5053        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5054            ProcessRecord rec = mLruProcesses.get(i);
5055            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5056                return i;
5057            }
5058        }
5059        return -1;
5060    }
5061
5062    final ProcessRecord getRecordForAppLocked(
5063            IApplicationThread thread) {
5064        if (thread == null) {
5065            return null;
5066        }
5067
5068        int appIndex = getLRURecordIndexForAppLocked(thread);
5069        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5070    }
5071
5072    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5073        // If there are no longer any background processes running,
5074        // and the app that died was not running instrumentation,
5075        // then tell everyone we are now low on memory.
5076        boolean haveBg = false;
5077        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5078            ProcessRecord rec = mLruProcesses.get(i);
5079            if (rec.thread != null
5080                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5081                haveBg = true;
5082                break;
5083            }
5084        }
5085
5086        if (!haveBg) {
5087            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5088            if (doReport) {
5089                long now = SystemClock.uptimeMillis();
5090                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5091                    doReport = false;
5092                } else {
5093                    mLastMemUsageReportTime = now;
5094                }
5095            }
5096            final ArrayList<ProcessMemInfo> memInfos
5097                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5098            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5099            long now = SystemClock.uptimeMillis();
5100            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5101                ProcessRecord rec = mLruProcesses.get(i);
5102                if (rec == dyingProc || rec.thread == null) {
5103                    continue;
5104                }
5105                if (doReport) {
5106                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5107                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5108                }
5109                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5110                    // The low memory report is overriding any current
5111                    // state for a GC request.  Make sure to do
5112                    // heavy/important/visible/foreground processes first.
5113                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5114                        rec.lastRequestedGc = 0;
5115                    } else {
5116                        rec.lastRequestedGc = rec.lastLowMemory;
5117                    }
5118                    rec.reportLowMemory = true;
5119                    rec.lastLowMemory = now;
5120                    mProcessesToGc.remove(rec);
5121                    addProcessToGcListLocked(rec);
5122                }
5123            }
5124            if (doReport) {
5125                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5126                mHandler.sendMessage(msg);
5127            }
5128            scheduleAppGcsLocked();
5129        }
5130    }
5131
5132    final void appDiedLocked(ProcessRecord app) {
5133       appDiedLocked(app, app.pid, app.thread, false);
5134    }
5135
5136    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5137            boolean fromBinderDied) {
5138        // First check if this ProcessRecord is actually active for the pid.
5139        synchronized (mPidsSelfLocked) {
5140            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5141            if (curProc != app) {
5142                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5143                return;
5144            }
5145        }
5146
5147        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5148        synchronized (stats) {
5149            stats.noteProcessDiedLocked(app.info.uid, pid);
5150        }
5151
5152        if (!app.killed) {
5153            if (!fromBinderDied) {
5154                Process.killProcessQuiet(pid);
5155            }
5156            killProcessGroup(app.uid, pid);
5157            app.killed = true;
5158        }
5159
5160        // Clean up already done if the process has been re-started.
5161        if (app.pid == pid && app.thread != null &&
5162                app.thread.asBinder() == thread.asBinder()) {
5163            boolean doLowMem = app.instrumentationClass == null;
5164            boolean doOomAdj = doLowMem;
5165            if (!app.killedByAm) {
5166                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5167                        + ") has died");
5168                mAllowLowerMemLevel = true;
5169            } else {
5170                // Note that we always want to do oom adj to update our state with the
5171                // new number of procs.
5172                mAllowLowerMemLevel = false;
5173                doLowMem = false;
5174            }
5175            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5176            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5177                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5178            handleAppDiedLocked(app, false, true);
5179
5180            if (doOomAdj) {
5181                updateOomAdjLocked();
5182            }
5183            if (doLowMem) {
5184                doLowMemReportIfNeededLocked(app);
5185            }
5186        } else if (app.pid != pid) {
5187            // A new process has already been started.
5188            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5189                    + ") has died and restarted (pid " + app.pid + ").");
5190            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5191        } else if (DEBUG_PROCESSES) {
5192            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5193                    + thread.asBinder());
5194        }
5195    }
5196
5197    /**
5198     * If a stack trace dump file is configured, dump process stack traces.
5199     * @param clearTraces causes the dump file to be erased prior to the new
5200     *    traces being written, if true; when false, the new traces will be
5201     *    appended to any existing file content.
5202     * @param firstPids of dalvik VM processes to dump stack traces for first
5203     * @param lastPids of dalvik VM processes to dump stack traces for last
5204     * @param nativeProcs optional list of native process names to dump stack crawls
5205     * @return file containing stack traces, or null if no dump file is configured
5206     */
5207    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5208            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5209        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5210        if (tracesPath == null || tracesPath.length() == 0) {
5211            return null;
5212        }
5213
5214        File tracesFile = new File(tracesPath);
5215        try {
5216            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5217            tracesFile.createNewFile();
5218            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5219        } catch (IOException e) {
5220            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5221            return null;
5222        }
5223
5224        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5225        return tracesFile;
5226    }
5227
5228    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5229            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5230        // Use a FileObserver to detect when traces finish writing.
5231        // The order of traces is considered important to maintain for legibility.
5232        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5233            @Override
5234            public synchronized void onEvent(int event, String path) { notify(); }
5235        };
5236
5237        try {
5238            observer.startWatching();
5239
5240            // First collect all of the stacks of the most important pids.
5241            if (firstPids != null) {
5242                try {
5243                    int num = firstPids.size();
5244                    for (int i = 0; i < num; i++) {
5245                        synchronized (observer) {
5246                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5247                                    + firstPids.get(i));
5248                            final long sime = SystemClock.elapsedRealtime();
5249                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5250                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5251                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5252                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5253                        }
5254                    }
5255                } catch (InterruptedException e) {
5256                    Slog.wtf(TAG, e);
5257                }
5258            }
5259
5260            // Next collect the stacks of the native pids
5261            if (nativeProcs != null) {
5262                int[] pids = Process.getPidsForCommands(nativeProcs);
5263                if (pids != null) {
5264                    for (int pid : pids) {
5265                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5266                        final long sime = SystemClock.elapsedRealtime();
5267                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5268                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5269                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5270                    }
5271                }
5272            }
5273
5274            // Lastly, measure CPU usage.
5275            if (processCpuTracker != null) {
5276                processCpuTracker.init();
5277                System.gc();
5278                processCpuTracker.update();
5279                try {
5280                    synchronized (processCpuTracker) {
5281                        processCpuTracker.wait(500); // measure over 1/2 second.
5282                    }
5283                } catch (InterruptedException e) {
5284                }
5285                processCpuTracker.update();
5286
5287                // We'll take the stack crawls of just the top apps using CPU.
5288                final int N = processCpuTracker.countWorkingStats();
5289                int numProcs = 0;
5290                for (int i=0; i<N && numProcs<5; i++) {
5291                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5292                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5293                        numProcs++;
5294                        try {
5295                            synchronized (observer) {
5296                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5297                                        + stats.pid);
5298                                final long stime = SystemClock.elapsedRealtime();
5299                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5300                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5301                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5302                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5303                            }
5304                        } catch (InterruptedException e) {
5305                            Slog.wtf(TAG, e);
5306                        }
5307                    } else if (DEBUG_ANR) {
5308                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5309                                + stats.pid);
5310                    }
5311                }
5312            }
5313        } finally {
5314            observer.stopWatching();
5315        }
5316    }
5317
5318    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5319        if (true || IS_USER_BUILD) {
5320            return;
5321        }
5322        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5323        if (tracesPath == null || tracesPath.length() == 0) {
5324            return;
5325        }
5326
5327        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5328        StrictMode.allowThreadDiskWrites();
5329        try {
5330            final File tracesFile = new File(tracesPath);
5331            final File tracesDir = tracesFile.getParentFile();
5332            final File tracesTmp = new File(tracesDir, "__tmp__");
5333            try {
5334                if (tracesFile.exists()) {
5335                    tracesTmp.delete();
5336                    tracesFile.renameTo(tracesTmp);
5337                }
5338                StringBuilder sb = new StringBuilder();
5339                Time tobj = new Time();
5340                tobj.set(System.currentTimeMillis());
5341                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5342                sb.append(": ");
5343                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5344                sb.append(" since ");
5345                sb.append(msg);
5346                FileOutputStream fos = new FileOutputStream(tracesFile);
5347                fos.write(sb.toString().getBytes());
5348                if (app == null) {
5349                    fos.write("\n*** No application process!".getBytes());
5350                }
5351                fos.close();
5352                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5353            } catch (IOException e) {
5354                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5355                return;
5356            }
5357
5358            if (app != null) {
5359                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5360                firstPids.add(app.pid);
5361                dumpStackTraces(tracesPath, firstPids, null, null, null);
5362            }
5363
5364            File lastTracesFile = null;
5365            File curTracesFile = null;
5366            for (int i=9; i>=0; i--) {
5367                String name = String.format(Locale.US, "slow%02d.txt", i);
5368                curTracesFile = new File(tracesDir, name);
5369                if (curTracesFile.exists()) {
5370                    if (lastTracesFile != null) {
5371                        curTracesFile.renameTo(lastTracesFile);
5372                    } else {
5373                        curTracesFile.delete();
5374                    }
5375                }
5376                lastTracesFile = curTracesFile;
5377            }
5378            tracesFile.renameTo(curTracesFile);
5379            if (tracesTmp.exists()) {
5380                tracesTmp.renameTo(tracesFile);
5381            }
5382        } finally {
5383            StrictMode.setThreadPolicy(oldPolicy);
5384        }
5385    }
5386
5387    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5388        if (!mLaunchWarningShown) {
5389            mLaunchWarningShown = true;
5390            mUiHandler.post(new Runnable() {
5391                @Override
5392                public void run() {
5393                    synchronized (ActivityManagerService.this) {
5394                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5395                        d.show();
5396                        mUiHandler.postDelayed(new Runnable() {
5397                            @Override
5398                            public void run() {
5399                                synchronized (ActivityManagerService.this) {
5400                                    d.dismiss();
5401                                    mLaunchWarningShown = false;
5402                                }
5403                            }
5404                        }, 4000);
5405                    }
5406                }
5407            });
5408        }
5409    }
5410
5411    @Override
5412    public boolean clearApplicationUserData(final String packageName,
5413            final IPackageDataObserver observer, int userId) {
5414        enforceNotIsolatedCaller("clearApplicationUserData");
5415        int uid = Binder.getCallingUid();
5416        int pid = Binder.getCallingPid();
5417        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5418                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5419
5420
5421        long callingId = Binder.clearCallingIdentity();
5422        try {
5423            IPackageManager pm = AppGlobals.getPackageManager();
5424            int pkgUid = -1;
5425            synchronized(this) {
5426                if (getPackageManagerInternalLocked().isPackageDataProtected(
5427                        userId, packageName)) {
5428                    throw new SecurityException(
5429                            "Cannot clear data for a protected package: " + packageName);
5430                }
5431
5432                try {
5433                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5434                } catch (RemoteException e) {
5435                }
5436                if (pkgUid == -1) {
5437                    Slog.w(TAG, "Invalid packageName: " + packageName);
5438                    if (observer != null) {
5439                        try {
5440                            observer.onRemoveCompleted(packageName, false);
5441                        } catch (RemoteException e) {
5442                            Slog.i(TAG, "Observer no longer exists.");
5443                        }
5444                    }
5445                    return false;
5446                }
5447                if (uid == pkgUid || checkComponentPermission(
5448                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5449                        pid, uid, -1, true)
5450                        == PackageManager.PERMISSION_GRANTED) {
5451                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5452                } else {
5453                    throw new SecurityException("PID " + pid + " does not have permission "
5454                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5455                                    + " of package " + packageName);
5456                }
5457
5458                // Remove all tasks match the cleared application package and user
5459                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5460                    final TaskRecord tr = mRecentTasks.get(i);
5461                    final String taskPackageName =
5462                            tr.getBaseIntent().getComponent().getPackageName();
5463                    if (tr.userId != userId) continue;
5464                    if (!taskPackageName.equals(packageName)) continue;
5465                    removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5466                }
5467            }
5468
5469            final int pkgUidF = pkgUid;
5470            final int userIdF = userId;
5471            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5472                @Override
5473                public void onRemoveCompleted(String packageName, boolean succeeded)
5474                        throws RemoteException {
5475                    synchronized (ActivityManagerService.this) {
5476                        finishForceStopPackageLocked(packageName, pkgUidF);
5477                    }
5478
5479                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5480                            Uri.fromParts("package", packageName, null));
5481                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5482                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5483                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5484                            null, null, 0, null, null, null, null, false, false, userIdF);
5485
5486                    if (observer != null) {
5487                        observer.onRemoveCompleted(packageName, succeeded);
5488                    }
5489                }
5490            };
5491
5492            try {
5493                // Clear application user data
5494                pm.clearApplicationUserData(packageName, localObserver, userId);
5495
5496                synchronized(this) {
5497                    // Remove all permissions granted from/to this package
5498                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5499                }
5500
5501                // Remove all zen rules created by this package; revoke it's zen access.
5502                INotificationManager inm = NotificationManager.getService();
5503                inm.removeAutomaticZenRules(packageName);
5504                inm.setNotificationPolicyAccessGranted(packageName, false);
5505
5506            } catch (RemoteException e) {
5507            }
5508        } finally {
5509            Binder.restoreCallingIdentity(callingId);
5510        }
5511        return true;
5512    }
5513
5514    @Override
5515    public void killBackgroundProcesses(final String packageName, int userId) {
5516        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5517                != PackageManager.PERMISSION_GRANTED &&
5518                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5519                        != PackageManager.PERMISSION_GRANTED) {
5520            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5521                    + Binder.getCallingPid()
5522                    + ", uid=" + Binder.getCallingUid()
5523                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5524            Slog.w(TAG, msg);
5525            throw new SecurityException(msg);
5526        }
5527
5528        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5529                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5530        long callingId = Binder.clearCallingIdentity();
5531        try {
5532            IPackageManager pm = AppGlobals.getPackageManager();
5533            synchronized(this) {
5534                int appId = -1;
5535                try {
5536                    appId = UserHandle.getAppId(
5537                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5538                } catch (RemoteException e) {
5539                }
5540                if (appId == -1) {
5541                    Slog.w(TAG, "Invalid packageName: " + packageName);
5542                    return;
5543                }
5544                killPackageProcessesLocked(packageName, appId, userId,
5545                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5546            }
5547        } finally {
5548            Binder.restoreCallingIdentity(callingId);
5549        }
5550    }
5551
5552    @Override
5553    public void killAllBackgroundProcesses() {
5554        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5555                != PackageManager.PERMISSION_GRANTED) {
5556            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5557                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5558                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5559            Slog.w(TAG, msg);
5560            throw new SecurityException(msg);
5561        }
5562
5563        final long callingId = Binder.clearCallingIdentity();
5564        try {
5565            synchronized (this) {
5566                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5567                final int NP = mProcessNames.getMap().size();
5568                for (int ip = 0; ip < NP; ip++) {
5569                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5570                    final int NA = apps.size();
5571                    for (int ia = 0; ia < NA; ia++) {
5572                        final ProcessRecord app = apps.valueAt(ia);
5573                        if (app.persistent) {
5574                            // We don't kill persistent processes.
5575                            continue;
5576                        }
5577                        if (app.removed) {
5578                            procs.add(app);
5579                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5580                            app.removed = true;
5581                            procs.add(app);
5582                        }
5583                    }
5584                }
5585
5586                final int N = procs.size();
5587                for (int i = 0; i < N; i++) {
5588                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5589                }
5590
5591                mAllowLowerMemLevel = true;
5592
5593                updateOomAdjLocked();
5594                doLowMemReportIfNeededLocked(null);
5595            }
5596        } finally {
5597            Binder.restoreCallingIdentity(callingId);
5598        }
5599    }
5600
5601    /**
5602     * Kills all background processes, except those matching any of the
5603     * specified properties.
5604     *
5605     * @param minTargetSdk the target SDK version at or above which to preserve
5606     *                     processes, or {@code -1} to ignore the target SDK
5607     * @param maxProcState the process state at or below which to preserve
5608     *                     processes, or {@code -1} to ignore the process state
5609     */
5610    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5611        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5612                != PackageManager.PERMISSION_GRANTED) {
5613            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5614                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5615                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5616            Slog.w(TAG, msg);
5617            throw new SecurityException(msg);
5618        }
5619
5620        final long callingId = Binder.clearCallingIdentity();
5621        try {
5622            synchronized (this) {
5623                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5624                final int NP = mProcessNames.getMap().size();
5625                for (int ip = 0; ip < NP; ip++) {
5626                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5627                    final int NA = apps.size();
5628                    for (int ia = 0; ia < NA; ia++) {
5629                        final ProcessRecord app = apps.valueAt(ia);
5630                        if (app.removed) {
5631                            procs.add(app);
5632                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5633                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5634                            app.removed = true;
5635                            procs.add(app);
5636                        }
5637                    }
5638                }
5639
5640                final int N = procs.size();
5641                for (int i = 0; i < N; i++) {
5642                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5643                }
5644            }
5645        } finally {
5646            Binder.restoreCallingIdentity(callingId);
5647        }
5648    }
5649
5650    @Override
5651    public void forceStopPackage(final String packageName, int userId) {
5652        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5653                != PackageManager.PERMISSION_GRANTED) {
5654            String msg = "Permission Denial: forceStopPackage() from pid="
5655                    + Binder.getCallingPid()
5656                    + ", uid=" + Binder.getCallingUid()
5657                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5658            Slog.w(TAG, msg);
5659            throw new SecurityException(msg);
5660        }
5661        final int callingPid = Binder.getCallingPid();
5662        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5663                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5664        long callingId = Binder.clearCallingIdentity();
5665        try {
5666            IPackageManager pm = AppGlobals.getPackageManager();
5667            synchronized(this) {
5668                int[] users = userId == UserHandle.USER_ALL
5669                        ? mUserController.getUsers() : new int[] { userId };
5670                for (int user : users) {
5671                    int pkgUid = -1;
5672                    try {
5673                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5674                                user);
5675                    } catch (RemoteException e) {
5676                    }
5677                    if (pkgUid == -1) {
5678                        Slog.w(TAG, "Invalid packageName: " + packageName);
5679                        continue;
5680                    }
5681                    try {
5682                        pm.setPackageStoppedState(packageName, true, user);
5683                    } catch (RemoteException e) {
5684                    } catch (IllegalArgumentException e) {
5685                        Slog.w(TAG, "Failed trying to unstop package "
5686                                + packageName + ": " + e);
5687                    }
5688                    if (mUserController.isUserRunningLocked(user, 0)) {
5689                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5690                        finishForceStopPackageLocked(packageName, pkgUid);
5691                    }
5692                }
5693            }
5694        } finally {
5695            Binder.restoreCallingIdentity(callingId);
5696        }
5697    }
5698
5699    @Override
5700    public void addPackageDependency(String packageName) {
5701        synchronized (this) {
5702            int callingPid = Binder.getCallingPid();
5703            if (callingPid == Process.myPid()) {
5704                //  Yeah, um, no.
5705                return;
5706            }
5707            ProcessRecord proc;
5708            synchronized (mPidsSelfLocked) {
5709                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5710            }
5711            if (proc != null) {
5712                if (proc.pkgDeps == null) {
5713                    proc.pkgDeps = new ArraySet<String>(1);
5714                }
5715                proc.pkgDeps.add(packageName);
5716            }
5717        }
5718    }
5719
5720    /*
5721     * The pkg name and app id have to be specified.
5722     */
5723    @Override
5724    public void killApplication(String pkg, int appId, int userId, String reason) {
5725        if (pkg == null) {
5726            return;
5727        }
5728        // Make sure the uid is valid.
5729        if (appId < 0) {
5730            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5731            return;
5732        }
5733        int callerUid = Binder.getCallingUid();
5734        // Only the system server can kill an application
5735        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5736            // Post an aysnc message to kill the application
5737            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5738            msg.arg1 = appId;
5739            msg.arg2 = userId;
5740            Bundle bundle = new Bundle();
5741            bundle.putString("pkg", pkg);
5742            bundle.putString("reason", reason);
5743            msg.obj = bundle;
5744            mHandler.sendMessage(msg);
5745        } else {
5746            throw new SecurityException(callerUid + " cannot kill pkg: " +
5747                    pkg);
5748        }
5749    }
5750
5751    @Override
5752    public void closeSystemDialogs(String reason) {
5753        enforceNotIsolatedCaller("closeSystemDialogs");
5754
5755        final int pid = Binder.getCallingPid();
5756        final int uid = Binder.getCallingUid();
5757        final long origId = Binder.clearCallingIdentity();
5758        try {
5759            synchronized (this) {
5760                // Only allow this from foreground processes, so that background
5761                // applications can't abuse it to prevent system UI from being shown.
5762                if (uid >= Process.FIRST_APPLICATION_UID) {
5763                    ProcessRecord proc;
5764                    synchronized (mPidsSelfLocked) {
5765                        proc = mPidsSelfLocked.get(pid);
5766                    }
5767                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5768                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5769                                + " from background process " + proc);
5770                        return;
5771                    }
5772                }
5773                closeSystemDialogsLocked(reason);
5774            }
5775        } finally {
5776            Binder.restoreCallingIdentity(origId);
5777        }
5778    }
5779
5780    void closeSystemDialogsLocked(String reason) {
5781        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5782        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5783                | Intent.FLAG_RECEIVER_FOREGROUND);
5784        if (reason != null) {
5785            intent.putExtra("reason", reason);
5786        }
5787        mWindowManager.closeSystemDialogs(reason);
5788
5789        mStackSupervisor.closeSystemDialogsLocked();
5790
5791        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5792                AppOpsManager.OP_NONE, null, false, false,
5793                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5794    }
5795
5796    @Override
5797    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5798        enforceNotIsolatedCaller("getProcessMemoryInfo");
5799        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5800        for (int i=pids.length-1; i>=0; i--) {
5801            ProcessRecord proc;
5802            int oomAdj;
5803            synchronized (this) {
5804                synchronized (mPidsSelfLocked) {
5805                    proc = mPidsSelfLocked.get(pids[i]);
5806                    oomAdj = proc != null ? proc.setAdj : 0;
5807                }
5808            }
5809            infos[i] = new Debug.MemoryInfo();
5810            Debug.getMemoryInfo(pids[i], infos[i]);
5811            if (proc != null) {
5812                synchronized (this) {
5813                    if (proc.thread != null && proc.setAdj == oomAdj) {
5814                        // Record this for posterity if the process has been stable.
5815                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5816                                infos[i].getTotalUss(), false, proc.pkgList);
5817                    }
5818                }
5819            }
5820        }
5821        return infos;
5822    }
5823
5824    @Override
5825    public long[] getProcessPss(int[] pids) {
5826        enforceNotIsolatedCaller("getProcessPss");
5827        long[] pss = new long[pids.length];
5828        for (int i=pids.length-1; i>=0; i--) {
5829            ProcessRecord proc;
5830            int oomAdj;
5831            synchronized (this) {
5832                synchronized (mPidsSelfLocked) {
5833                    proc = mPidsSelfLocked.get(pids[i]);
5834                    oomAdj = proc != null ? proc.setAdj : 0;
5835                }
5836            }
5837            long[] tmpUss = new long[1];
5838            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5839            if (proc != null) {
5840                synchronized (this) {
5841                    if (proc.thread != null && proc.setAdj == oomAdj) {
5842                        // Record this for posterity if the process has been stable.
5843                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5844                    }
5845                }
5846            }
5847        }
5848        return pss;
5849    }
5850
5851    @Override
5852    public void killApplicationProcess(String processName, int uid) {
5853        if (processName == null) {
5854            return;
5855        }
5856
5857        int callerUid = Binder.getCallingUid();
5858        // Only the system server can kill an application
5859        if (callerUid == Process.SYSTEM_UID) {
5860            synchronized (this) {
5861                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5862                if (app != null && app.thread != null) {
5863                    try {
5864                        app.thread.scheduleSuicide();
5865                    } catch (RemoteException e) {
5866                        // If the other end already died, then our work here is done.
5867                    }
5868                } else {
5869                    Slog.w(TAG, "Process/uid not found attempting kill of "
5870                            + processName + " / " + uid);
5871                }
5872            }
5873        } else {
5874            throw new SecurityException(callerUid + " cannot kill app process: " +
5875                    processName);
5876        }
5877    }
5878
5879    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5880        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5881                false, true, false, false, UserHandle.getUserId(uid), reason);
5882    }
5883
5884    private void finishForceStopPackageLocked(final String packageName, int uid) {
5885        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5886                Uri.fromParts("package", packageName, null));
5887        if (!mProcessesReady) {
5888            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5889                    | Intent.FLAG_RECEIVER_FOREGROUND);
5890        }
5891        intent.putExtra(Intent.EXTRA_UID, uid);
5892        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5893        broadcastIntentLocked(null, null, intent,
5894                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5895                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5896    }
5897
5898
5899    private final boolean killPackageProcessesLocked(String packageName, int appId,
5900            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5901            boolean doit, boolean evenPersistent, String reason) {
5902        ArrayList<ProcessRecord> procs = new ArrayList<>();
5903
5904        // Remove all processes this package may have touched: all with the
5905        // same UID (except for the system or root user), and all whose name
5906        // matches the package name.
5907        final int NP = mProcessNames.getMap().size();
5908        for (int ip=0; ip<NP; ip++) {
5909            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5910            final int NA = apps.size();
5911            for (int ia=0; ia<NA; ia++) {
5912                ProcessRecord app = apps.valueAt(ia);
5913                if (app.persistent && !evenPersistent) {
5914                    // we don't kill persistent processes
5915                    continue;
5916                }
5917                if (app.removed) {
5918                    if (doit) {
5919                        procs.add(app);
5920                    }
5921                    continue;
5922                }
5923
5924                // Skip process if it doesn't meet our oom adj requirement.
5925                if (app.setAdj < minOomAdj) {
5926                    continue;
5927                }
5928
5929                // If no package is specified, we call all processes under the
5930                // give user id.
5931                if (packageName == null) {
5932                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5933                        continue;
5934                    }
5935                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5936                        continue;
5937                    }
5938                // Package has been specified, we want to hit all processes
5939                // that match it.  We need to qualify this by the processes
5940                // that are running under the specified app and user ID.
5941                } else {
5942                    final boolean isDep = app.pkgDeps != null
5943                            && app.pkgDeps.contains(packageName);
5944                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5945                        continue;
5946                    }
5947                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5948                        continue;
5949                    }
5950                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5951                        continue;
5952                    }
5953                }
5954
5955                // Process has passed all conditions, kill it!
5956                if (!doit) {
5957                    return true;
5958                }
5959                app.removed = true;
5960                procs.add(app);
5961            }
5962        }
5963
5964        int N = procs.size();
5965        for (int i=0; i<N; i++) {
5966            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5967        }
5968        updateOomAdjLocked();
5969        return N > 0;
5970    }
5971
5972    private void cleanupDisabledPackageComponentsLocked(
5973            String packageName, int userId, boolean killProcess, String[] changedClasses) {
5974
5975        Set<String> disabledClasses = null;
5976        boolean packageDisabled = false;
5977        IPackageManager pm = AppGlobals.getPackageManager();
5978
5979        if (changedClasses == null) {
5980            // Nothing changed...
5981            return;
5982        }
5983
5984        // Determine enable/disable state of the package and its components.
5985        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5986        for (int i = changedClasses.length - 1; i >= 0; i--) {
5987            final String changedClass = changedClasses[i];
5988
5989            if (changedClass.equals(packageName)) {
5990                try {
5991                    // Entire package setting changed
5992                    enabled = pm.getApplicationEnabledSetting(packageName,
5993                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5994                } catch (Exception e) {
5995                    // No such package/component; probably racing with uninstall.  In any
5996                    // event it means we have nothing further to do here.
5997                    return;
5998                }
5999                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6000                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6001                if (packageDisabled) {
6002                    // Entire package is disabled.
6003                    // No need to continue to check component states.
6004                    disabledClasses = null;
6005                    break;
6006                }
6007            } else {
6008                try {
6009                    enabled = pm.getComponentEnabledSetting(
6010                            new ComponentName(packageName, changedClass),
6011                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6012                } catch (Exception e) {
6013                    // As above, probably racing with uninstall.
6014                    return;
6015                }
6016                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6017                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6018                    if (disabledClasses == null) {
6019                        disabledClasses = new ArraySet<>(changedClasses.length);
6020                    }
6021                    disabledClasses.add(changedClass);
6022                }
6023            }
6024        }
6025
6026        if (!packageDisabled && disabledClasses == null) {
6027            // Nothing to do here...
6028            return;
6029        }
6030
6031        // Clean-up disabled activities.
6032        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6033                packageName, disabledClasses, true, false, userId) && mBooted) {
6034            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6035            mStackSupervisor.scheduleIdleLocked();
6036        }
6037
6038        // Clean-up disabled tasks
6039        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6040
6041        // Clean-up disabled services.
6042        mServices.bringDownDisabledPackageServicesLocked(
6043                packageName, disabledClasses, userId, false, killProcess, true);
6044
6045        // Clean-up disabled providers.
6046        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6047        mProviderMap.collectPackageProvidersLocked(
6048                packageName, disabledClasses, true, false, userId, providers);
6049        for (int i = providers.size() - 1; i >= 0; i--) {
6050            removeDyingProviderLocked(null, providers.get(i), true);
6051        }
6052
6053        // Clean-up disabled broadcast receivers.
6054        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6055            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6056                    packageName, disabledClasses, userId, true);
6057        }
6058
6059    }
6060
6061    final boolean clearBroadcastQueueForUserLocked(int userId) {
6062        boolean didSomething = false;
6063        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6064            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6065                    null, null, userId, true);
6066        }
6067        return didSomething;
6068    }
6069
6070    final boolean forceStopPackageLocked(String packageName, int appId,
6071            boolean callerWillRestart, boolean purgeCache, boolean doit,
6072            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6073        int i;
6074
6075        if (userId == UserHandle.USER_ALL && packageName == null) {
6076            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6077        }
6078
6079        if (appId < 0 && packageName != null) {
6080            try {
6081                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6082                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6083            } catch (RemoteException e) {
6084            }
6085        }
6086
6087        if (doit) {
6088            if (packageName != null) {
6089                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6090                        + " user=" + userId + ": " + reason);
6091            } else {
6092                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6093            }
6094
6095            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6096        }
6097
6098        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6099                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6100                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6101
6102        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6103                packageName, null, doit, evenPersistent, userId)) {
6104            if (!doit) {
6105                return true;
6106            }
6107            didSomething = true;
6108        }
6109
6110        if (mServices.bringDownDisabledPackageServicesLocked(
6111                packageName, null, userId, evenPersistent, true, doit)) {
6112            if (!doit) {
6113                return true;
6114            }
6115            didSomething = true;
6116        }
6117
6118        if (packageName == null) {
6119            // Remove all sticky broadcasts from this user.
6120            mStickyBroadcasts.remove(userId);
6121        }
6122
6123        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6124        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6125                userId, providers)) {
6126            if (!doit) {
6127                return true;
6128            }
6129            didSomething = true;
6130        }
6131        for (i = providers.size() - 1; i >= 0; i--) {
6132            removeDyingProviderLocked(null, providers.get(i), true);
6133        }
6134
6135        // Remove transient permissions granted from/to this package/user
6136        removeUriPermissionsForPackageLocked(packageName, userId, false);
6137
6138        if (doit) {
6139            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6140                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6141                        packageName, null, userId, doit);
6142            }
6143        }
6144
6145        if (packageName == null || uninstalling) {
6146            // Remove pending intents.  For now we only do this when force
6147            // stopping users, because we have some problems when doing this
6148            // for packages -- app widgets are not currently cleaned up for
6149            // such packages, so they can be left with bad pending intents.
6150            if (mIntentSenderRecords.size() > 0) {
6151                Iterator<WeakReference<PendingIntentRecord>> it
6152                        = mIntentSenderRecords.values().iterator();
6153                while (it.hasNext()) {
6154                    WeakReference<PendingIntentRecord> wpir = it.next();
6155                    if (wpir == null) {
6156                        it.remove();
6157                        continue;
6158                    }
6159                    PendingIntentRecord pir = wpir.get();
6160                    if (pir == null) {
6161                        it.remove();
6162                        continue;
6163                    }
6164                    if (packageName == null) {
6165                        // Stopping user, remove all objects for the user.
6166                        if (pir.key.userId != userId) {
6167                            // Not the same user, skip it.
6168                            continue;
6169                        }
6170                    } else {
6171                        if (UserHandle.getAppId(pir.uid) != appId) {
6172                            // Different app id, skip it.
6173                            continue;
6174                        }
6175                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6176                            // Different user, skip it.
6177                            continue;
6178                        }
6179                        if (!pir.key.packageName.equals(packageName)) {
6180                            // Different package, skip it.
6181                            continue;
6182                        }
6183                    }
6184                    if (!doit) {
6185                        return true;
6186                    }
6187                    didSomething = true;
6188                    it.remove();
6189                    pir.canceled = true;
6190                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6191                        pir.key.activity.pendingResults.remove(pir.ref);
6192                    }
6193                }
6194            }
6195        }
6196
6197        if (doit) {
6198            if (purgeCache && packageName != null) {
6199                AttributeCache ac = AttributeCache.instance();
6200                if (ac != null) {
6201                    ac.removePackage(packageName);
6202                }
6203            }
6204            if (mBooted) {
6205                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6206                mStackSupervisor.scheduleIdleLocked();
6207            }
6208        }
6209
6210        return didSomething;
6211    }
6212
6213    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6214        ProcessRecord old = mProcessNames.remove(name, uid);
6215        if (old != null) {
6216            old.uidRecord.numProcs--;
6217            if (old.uidRecord.numProcs == 0) {
6218                // No more processes using this uid, tell clients it is gone.
6219                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6220                        "No more processes in " + old.uidRecord);
6221                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6222                mActiveUids.remove(uid);
6223                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6224            }
6225            old.uidRecord = null;
6226        }
6227        mIsolatedProcesses.remove(uid);
6228        return old;
6229    }
6230
6231    private final void addProcessNameLocked(ProcessRecord proc) {
6232        // We shouldn't already have a process under this name, but just in case we
6233        // need to clean up whatever may be there now.
6234        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6235        if (old == proc && proc.persistent) {
6236            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6237            Slog.w(TAG, "Re-adding persistent process " + proc);
6238        } else if (old != null) {
6239            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6240        }
6241        UidRecord uidRec = mActiveUids.get(proc.uid);
6242        if (uidRec == null) {
6243            uidRec = new UidRecord(proc.uid);
6244            // This is the first appearance of the uid, report it now!
6245            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6246                    "Creating new process uid: " + uidRec);
6247            mActiveUids.put(proc.uid, uidRec);
6248            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6249            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6250        }
6251        proc.uidRecord = uidRec;
6252        uidRec.numProcs++;
6253        mProcessNames.put(proc.processName, proc.uid, proc);
6254        if (proc.isolated) {
6255            mIsolatedProcesses.put(proc.uid, proc);
6256        }
6257    }
6258
6259    boolean removeProcessLocked(ProcessRecord app,
6260            boolean callerWillRestart, boolean allowRestart, String reason) {
6261        final String name = app.processName;
6262        final int uid = app.uid;
6263        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6264            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6265
6266        ProcessRecord old = mProcessNames.get(name, uid);
6267        if (old != app) {
6268            // This process is no longer active, so nothing to do.
6269            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6270            return false;
6271        }
6272        removeProcessNameLocked(name, uid);
6273        if (mHeavyWeightProcess == app) {
6274            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6275                    mHeavyWeightProcess.userId, 0));
6276            mHeavyWeightProcess = null;
6277        }
6278        boolean needRestart = false;
6279        if (app.pid > 0 && app.pid != MY_PID) {
6280            int pid = app.pid;
6281            synchronized (mPidsSelfLocked) {
6282                mPidsSelfLocked.remove(pid);
6283                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6284            }
6285            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6286            if (app.isolated) {
6287                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6288            }
6289            boolean willRestart = false;
6290            if (app.persistent && !app.isolated) {
6291                if (!callerWillRestart) {
6292                    willRestart = true;
6293                } else {
6294                    needRestart = true;
6295                }
6296            }
6297            app.kill(reason, true);
6298            handleAppDiedLocked(app, willRestart, allowRestart);
6299            if (willRestart) {
6300                removeLruProcessLocked(app);
6301                addAppLocked(app.info, false, null /* ABI override */);
6302            }
6303        } else {
6304            mRemovedProcesses.add(app);
6305        }
6306
6307        return needRestart;
6308    }
6309
6310    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6311        cleanupAppInLaunchingProvidersLocked(app, true);
6312        removeProcessLocked(app, false, true, "timeout publishing content providers");
6313    }
6314
6315    private final void processStartTimedOutLocked(ProcessRecord app) {
6316        final int pid = app.pid;
6317        boolean gone = false;
6318        synchronized (mPidsSelfLocked) {
6319            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6320            if (knownApp != null && knownApp.thread == null) {
6321                mPidsSelfLocked.remove(pid);
6322                gone = true;
6323            }
6324        }
6325
6326        if (gone) {
6327            Slog.w(TAG, "Process " + app + " failed to attach");
6328            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6329                    pid, app.uid, app.processName);
6330            removeProcessNameLocked(app.processName, app.uid);
6331            if (mHeavyWeightProcess == app) {
6332                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6333                        mHeavyWeightProcess.userId, 0));
6334                mHeavyWeightProcess = null;
6335            }
6336            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6337            if (app.isolated) {
6338                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6339            }
6340            // Take care of any launching providers waiting for this process.
6341            cleanupAppInLaunchingProvidersLocked(app, true);
6342            // Take care of any services that are waiting for the process.
6343            mServices.processStartTimedOutLocked(app);
6344            app.kill("start timeout", true);
6345            removeLruProcessLocked(app);
6346            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6347                Slog.w(TAG, "Unattached app died before backup, skipping");
6348                try {
6349                    IBackupManager bm = IBackupManager.Stub.asInterface(
6350                            ServiceManager.getService(Context.BACKUP_SERVICE));
6351                    bm.agentDisconnected(app.info.packageName);
6352                } catch (RemoteException e) {
6353                    // Can't happen; the backup manager is local
6354                }
6355            }
6356            if (isPendingBroadcastProcessLocked(pid)) {
6357                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6358                skipPendingBroadcastLocked(pid);
6359            }
6360        } else {
6361            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6362        }
6363    }
6364
6365    private final boolean attachApplicationLocked(IApplicationThread thread,
6366            int pid) {
6367
6368        // Find the application record that is being attached...  either via
6369        // the pid if we are running in multiple processes, or just pull the
6370        // next app record if we are emulating process with anonymous threads.
6371        ProcessRecord app;
6372        if (pid != MY_PID && pid >= 0) {
6373            synchronized (mPidsSelfLocked) {
6374                app = mPidsSelfLocked.get(pid);
6375            }
6376        } else {
6377            app = null;
6378        }
6379
6380        if (app == null) {
6381            Slog.w(TAG, "No pending application record for pid " + pid
6382                    + " (IApplicationThread " + thread + "); dropping process");
6383            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6384            if (pid > 0 && pid != MY_PID) {
6385                Process.killProcessQuiet(pid);
6386                //TODO: killProcessGroup(app.info.uid, pid);
6387            } else {
6388                try {
6389                    thread.scheduleExit();
6390                } catch (Exception e) {
6391                    // Ignore exceptions.
6392                }
6393            }
6394            return false;
6395        }
6396
6397        // If this application record is still attached to a previous
6398        // process, clean it up now.
6399        if (app.thread != null) {
6400            handleAppDiedLocked(app, true, true);
6401        }
6402
6403        // Tell the process all about itself.
6404
6405        if (DEBUG_ALL) Slog.v(
6406                TAG, "Binding process pid " + pid + " to record " + app);
6407
6408        final String processName = app.processName;
6409        try {
6410            AppDeathRecipient adr = new AppDeathRecipient(
6411                    app, pid, thread);
6412            thread.asBinder().linkToDeath(adr, 0);
6413            app.deathRecipient = adr;
6414        } catch (RemoteException e) {
6415            app.resetPackageList(mProcessStats);
6416            startProcessLocked(app, "link fail", processName);
6417            return false;
6418        }
6419
6420        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6421
6422        app.makeActive(thread, mProcessStats);
6423        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6424        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6425        app.forcingToForeground = null;
6426        updateProcessForegroundLocked(app, false, false);
6427        app.hasShownUi = false;
6428        app.debugging = false;
6429        app.cached = false;
6430        app.killedByAm = false;
6431
6432        // We carefully use the same state that PackageManager uses for
6433        // filtering, since we use this flag to decide if we need to install
6434        // providers when user is unlocked later
6435        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6436
6437        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6438
6439        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6440        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6441
6442        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6443            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6444            msg.obj = app;
6445            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6446        }
6447
6448        if (!normalMode) {
6449            Slog.i(TAG, "Launching preboot mode app: " + app);
6450        }
6451
6452        if (DEBUG_ALL) Slog.v(
6453            TAG, "New app record " + app
6454            + " thread=" + thread.asBinder() + " pid=" + pid);
6455        try {
6456            int testMode = IApplicationThread.DEBUG_OFF;
6457            if (mDebugApp != null && mDebugApp.equals(processName)) {
6458                testMode = mWaitForDebugger
6459                    ? IApplicationThread.DEBUG_WAIT
6460                    : IApplicationThread.DEBUG_ON;
6461                app.debugging = true;
6462                if (mDebugTransient) {
6463                    mDebugApp = mOrigDebugApp;
6464                    mWaitForDebugger = mOrigWaitForDebugger;
6465                }
6466            }
6467            String profileFile = app.instrumentationProfileFile;
6468            ParcelFileDescriptor profileFd = null;
6469            int samplingInterval = 0;
6470            boolean profileAutoStop = false;
6471            if (mProfileApp != null && mProfileApp.equals(processName)) {
6472                mProfileProc = app;
6473                profileFile = mProfileFile;
6474                profileFd = mProfileFd;
6475                samplingInterval = mSamplingInterval;
6476                profileAutoStop = mAutoStopProfiler;
6477            }
6478            boolean enableTrackAllocation = false;
6479            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6480                enableTrackAllocation = true;
6481                mTrackAllocationApp = null;
6482            }
6483
6484            // If the app is being launched for restore or full backup, set it up specially
6485            boolean isRestrictedBackupMode = false;
6486            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6487                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6488                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6489                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6490                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6491            }
6492
6493            if (app.instrumentationClass != null) {
6494                notifyPackageUse(app.instrumentationClass.getPackageName(),
6495                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6496            }
6497            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6498                    + processName + " with config " + mConfiguration);
6499            ApplicationInfo appInfo = app.instrumentationInfo != null
6500                    ? app.instrumentationInfo : app.info;
6501            app.compat = compatibilityInfoForPackageLocked(appInfo);
6502            if (profileFd != null) {
6503                profileFd = profileFd.dup();
6504            }
6505            ProfilerInfo profilerInfo = profileFile == null ? null
6506                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6507            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6508                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6509                    app.instrumentationUiAutomationConnection, testMode,
6510                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6511                    isRestrictedBackupMode || !normalMode, app.persistent,
6512                    new Configuration(mConfiguration), app.compat,
6513                    getCommonServicesLocked(app.isolated),
6514                    mCoreSettingsObserver.getCoreSettingsLocked());
6515            updateLruProcessLocked(app, false, null);
6516            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6517        } catch (Exception e) {
6518            // todo: Yikes!  What should we do?  For now we will try to
6519            // start another process, but that could easily get us in
6520            // an infinite loop of restarting processes...
6521            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6522
6523            app.resetPackageList(mProcessStats);
6524            app.unlinkDeathRecipient();
6525            startProcessLocked(app, "bind fail", processName);
6526            return false;
6527        }
6528
6529        // Remove this record from the list of starting applications.
6530        mPersistentStartingProcesses.remove(app);
6531        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6532                "Attach application locked removing on hold: " + app);
6533        mProcessesOnHold.remove(app);
6534
6535        boolean badApp = false;
6536        boolean didSomething = false;
6537
6538        // See if the top visible activity is waiting to run in this process...
6539        if (normalMode) {
6540            try {
6541                if (mStackSupervisor.attachApplicationLocked(app)) {
6542                    didSomething = true;
6543                }
6544            } catch (Exception e) {
6545                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6546                badApp = true;
6547            }
6548        }
6549
6550        // Find any services that should be running in this process...
6551        if (!badApp) {
6552            try {
6553                didSomething |= mServices.attachApplicationLocked(app, processName);
6554            } catch (Exception e) {
6555                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6556                badApp = true;
6557            }
6558        }
6559
6560        // Check if a next-broadcast receiver is in this process...
6561        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6562            try {
6563                didSomething |= sendPendingBroadcastsLocked(app);
6564            } catch (Exception e) {
6565                // If the app died trying to launch the receiver we declare it 'bad'
6566                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6567                badApp = true;
6568            }
6569        }
6570
6571        // Check whether the next backup agent is in this process...
6572        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6573            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6574                    "New app is backup target, launching agent for " + app);
6575            notifyPackageUse(mBackupTarget.appInfo.packageName,
6576                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6577            try {
6578                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6579                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6580                        mBackupTarget.backupMode);
6581            } catch (Exception e) {
6582                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6583                badApp = true;
6584            }
6585        }
6586
6587        if (badApp) {
6588            app.kill("error during init", true);
6589            handleAppDiedLocked(app, false, true);
6590            return false;
6591        }
6592
6593        if (!didSomething) {
6594            updateOomAdjLocked();
6595        }
6596
6597        return true;
6598    }
6599
6600    @Override
6601    public final void attachApplication(IApplicationThread thread) {
6602        synchronized (this) {
6603            int callingPid = Binder.getCallingPid();
6604            final long origId = Binder.clearCallingIdentity();
6605            attachApplicationLocked(thread, callingPid);
6606            Binder.restoreCallingIdentity(origId);
6607        }
6608    }
6609
6610    @Override
6611    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6612        final long origId = Binder.clearCallingIdentity();
6613        synchronized (this) {
6614            ActivityStack stack = ActivityRecord.getStackLocked(token);
6615            if (stack != null) {
6616                ActivityRecord r =
6617                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6618                if (stopProfiling) {
6619                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6620                        try {
6621                            mProfileFd.close();
6622                        } catch (IOException e) {
6623                        }
6624                        clearProfilerLocked();
6625                    }
6626                }
6627            }
6628        }
6629        Binder.restoreCallingIdentity(origId);
6630    }
6631
6632    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6633        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6634                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6635    }
6636
6637    void enableScreenAfterBoot() {
6638        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6639                SystemClock.uptimeMillis());
6640        mWindowManager.enableScreenAfterBoot();
6641
6642        synchronized (this) {
6643            updateEventDispatchingLocked();
6644        }
6645    }
6646
6647    @Override
6648    public void showBootMessage(final CharSequence msg, final boolean always) {
6649        if (Binder.getCallingUid() != Process.myUid()) {
6650            // These days only the core system can call this, so apps can't get in
6651            // the way of what we show about running them.
6652        }
6653        mWindowManager.showBootMessage(msg, always);
6654    }
6655
6656    @Override
6657    public void keyguardWaitingForActivityDrawn() {
6658        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6659        final long token = Binder.clearCallingIdentity();
6660        try {
6661            synchronized (this) {
6662                if (DEBUG_LOCKSCREEN) logLockScreen("");
6663                mWindowManager.keyguardWaitingForActivityDrawn();
6664                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6665                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6666                    updateSleepIfNeededLocked();
6667                }
6668            }
6669        } finally {
6670            Binder.restoreCallingIdentity(token);
6671        }
6672    }
6673
6674    @Override
6675    public void keyguardGoingAway(int flags) {
6676        enforceNotIsolatedCaller("keyguardGoingAway");
6677        final long token = Binder.clearCallingIdentity();
6678        try {
6679            synchronized (this) {
6680                if (DEBUG_LOCKSCREEN) logLockScreen("");
6681                mWindowManager.keyguardGoingAway(flags);
6682                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6683                    mLockScreenShown = LOCK_SCREEN_HIDDEN;
6684                    updateSleepIfNeededLocked();
6685
6686                    // Some stack visibility might change (e.g. docked stack)
6687                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6688                    applyVrModeIfNeededLocked(mFocusedActivity, true);
6689                }
6690            }
6691        } finally {
6692            Binder.restoreCallingIdentity(token);
6693        }
6694    }
6695
6696    final void finishBooting() {
6697        synchronized (this) {
6698            if (!mBootAnimationComplete) {
6699                mCallFinishBooting = true;
6700                return;
6701            }
6702            mCallFinishBooting = false;
6703        }
6704
6705        ArraySet<String> completedIsas = new ArraySet<String>();
6706        for (String abi : Build.SUPPORTED_ABIS) {
6707            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6708            final String instructionSet = VMRuntime.getInstructionSet(abi);
6709            if (!completedIsas.contains(instructionSet)) {
6710                try {
6711                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6712                } catch (InstallerException e) {
6713                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6714                            e.getMessage() +")");
6715                }
6716                completedIsas.add(instructionSet);
6717            }
6718        }
6719
6720        IntentFilter pkgFilter = new IntentFilter();
6721        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6722        pkgFilter.addDataScheme("package");
6723        mContext.registerReceiver(new BroadcastReceiver() {
6724            @Override
6725            public void onReceive(Context context, Intent intent) {
6726                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6727                if (pkgs != null) {
6728                    for (String pkg : pkgs) {
6729                        synchronized (ActivityManagerService.this) {
6730                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6731                                    0, "query restart")) {
6732                                setResultCode(Activity.RESULT_OK);
6733                                return;
6734                            }
6735                        }
6736                    }
6737                }
6738            }
6739        }, pkgFilter);
6740
6741        IntentFilter dumpheapFilter = new IntentFilter();
6742        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6743        mContext.registerReceiver(new BroadcastReceiver() {
6744            @Override
6745            public void onReceive(Context context, Intent intent) {
6746                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6747                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6748                } else {
6749                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6750                }
6751            }
6752        }, dumpheapFilter);
6753
6754        // Let system services know.
6755        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6756
6757        synchronized (this) {
6758            // Ensure that any processes we had put on hold are now started
6759            // up.
6760            final int NP = mProcessesOnHold.size();
6761            if (NP > 0) {
6762                ArrayList<ProcessRecord> procs =
6763                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6764                for (int ip=0; ip<NP; ip++) {
6765                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6766                            + procs.get(ip));
6767                    startProcessLocked(procs.get(ip), "on-hold", null);
6768                }
6769            }
6770
6771            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6772                // Start looking for apps that are abusing wake locks.
6773                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6774                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6775                // Tell anyone interested that we are done booting!
6776                SystemProperties.set("sys.boot_completed", "1");
6777
6778                // And trigger dev.bootcomplete if we are not showing encryption progress
6779                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6780                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6781                    SystemProperties.set("dev.bootcomplete", "1");
6782                }
6783                mUserController.sendBootCompletedLocked(
6784                        new IIntentReceiver.Stub() {
6785                            @Override
6786                            public void performReceive(Intent intent, int resultCode,
6787                                    String data, Bundle extras, boolean ordered,
6788                                    boolean sticky, int sendingUser) {
6789                                synchronized (ActivityManagerService.this) {
6790                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6791                                            true, false);
6792                                }
6793                            }
6794                        });
6795                scheduleStartProfilesLocked();
6796            }
6797        }
6798    }
6799
6800    @Override
6801    public void bootAnimationComplete() {
6802        final boolean callFinishBooting;
6803        synchronized (this) {
6804            callFinishBooting = mCallFinishBooting;
6805            mBootAnimationComplete = true;
6806        }
6807        if (callFinishBooting) {
6808            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6809            finishBooting();
6810            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6811        }
6812    }
6813
6814    final void ensureBootCompleted() {
6815        boolean booting;
6816        boolean enableScreen;
6817        synchronized (this) {
6818            booting = mBooting;
6819            mBooting = false;
6820            enableScreen = !mBooted;
6821            mBooted = true;
6822        }
6823
6824        if (booting) {
6825            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6826            finishBooting();
6827            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6828        }
6829
6830        if (enableScreen) {
6831            enableScreenAfterBoot();
6832        }
6833    }
6834
6835    @Override
6836    public final void activityResumed(IBinder token) {
6837        final long origId = Binder.clearCallingIdentity();
6838        synchronized(this) {
6839            ActivityStack stack = ActivityRecord.getStackLocked(token);
6840            if (stack != null) {
6841                stack.activityResumedLocked(token);
6842            }
6843        }
6844        Binder.restoreCallingIdentity(origId);
6845    }
6846
6847    @Override
6848    public final void activityPaused(IBinder token) {
6849        final long origId = Binder.clearCallingIdentity();
6850        synchronized(this) {
6851            ActivityStack stack = ActivityRecord.getStackLocked(token);
6852            if (stack != null) {
6853                stack.activityPausedLocked(token, false);
6854            }
6855        }
6856        Binder.restoreCallingIdentity(origId);
6857    }
6858
6859    @Override
6860    public final void activityStopped(IBinder token, Bundle icicle,
6861            PersistableBundle persistentState, CharSequence description) {
6862        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6863
6864        // Refuse possible leaked file descriptors
6865        if (icicle != null && icicle.hasFileDescriptors()) {
6866            throw new IllegalArgumentException("File descriptors passed in Bundle");
6867        }
6868
6869        final long origId = Binder.clearCallingIdentity();
6870
6871        synchronized (this) {
6872            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6873            if (r != null) {
6874                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6875            }
6876        }
6877
6878        trimApplications();
6879
6880        Binder.restoreCallingIdentity(origId);
6881    }
6882
6883    @Override
6884    public final void activityDestroyed(IBinder token) {
6885        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6886        synchronized (this) {
6887            ActivityStack stack = ActivityRecord.getStackLocked(token);
6888            if (stack != null) {
6889                stack.activityDestroyedLocked(token, "activityDestroyed");
6890            }
6891        }
6892    }
6893
6894    @Override
6895    public final void activityRelaunched(IBinder token) {
6896        final long origId = Binder.clearCallingIdentity();
6897        synchronized (this) {
6898            mStackSupervisor.activityRelaunchedLocked(token);
6899        }
6900        Binder.restoreCallingIdentity(origId);
6901    }
6902
6903    @Override
6904    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6905            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6906        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6907                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6908        synchronized (this) {
6909            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6910            if (record == null) {
6911                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6912                        + "found for: " + token);
6913            }
6914            record.setSizeConfigurations(horizontalSizeConfiguration,
6915                    verticalSizeConfigurations, smallestSizeConfigurations);
6916        }
6917    }
6918
6919    @Override
6920    public final void backgroundResourcesReleased(IBinder token) {
6921        final long origId = Binder.clearCallingIdentity();
6922        try {
6923            synchronized (this) {
6924                ActivityStack stack = ActivityRecord.getStackLocked(token);
6925                if (stack != null) {
6926                    stack.backgroundResourcesReleased();
6927                }
6928            }
6929        } finally {
6930            Binder.restoreCallingIdentity(origId);
6931        }
6932    }
6933
6934    @Override
6935    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6936        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6937    }
6938
6939    @Override
6940    public final void notifyEnterAnimationComplete(IBinder token) {
6941        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6942    }
6943
6944    @Override
6945    public String getCallingPackage(IBinder token) {
6946        synchronized (this) {
6947            ActivityRecord r = getCallingRecordLocked(token);
6948            return r != null ? r.info.packageName : null;
6949        }
6950    }
6951
6952    @Override
6953    public ComponentName getCallingActivity(IBinder token) {
6954        synchronized (this) {
6955            ActivityRecord r = getCallingRecordLocked(token);
6956            return r != null ? r.intent.getComponent() : null;
6957        }
6958    }
6959
6960    private ActivityRecord getCallingRecordLocked(IBinder token) {
6961        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6962        if (r == null) {
6963            return null;
6964        }
6965        return r.resultTo;
6966    }
6967
6968    @Override
6969    public ComponentName getActivityClassForToken(IBinder token) {
6970        synchronized(this) {
6971            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6972            if (r == null) {
6973                return null;
6974            }
6975            return r.intent.getComponent();
6976        }
6977    }
6978
6979    @Override
6980    public String getPackageForToken(IBinder token) {
6981        synchronized(this) {
6982            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6983            if (r == null) {
6984                return null;
6985            }
6986            return r.packageName;
6987        }
6988    }
6989
6990    @Override
6991    public boolean isRootVoiceInteraction(IBinder token) {
6992        synchronized(this) {
6993            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6994            if (r == null) {
6995                return false;
6996            }
6997            return r.rootVoiceInteraction;
6998        }
6999    }
7000
7001    @Override
7002    public IIntentSender getIntentSender(int type,
7003            String packageName, IBinder token, String resultWho,
7004            int requestCode, Intent[] intents, String[] resolvedTypes,
7005            int flags, Bundle bOptions, int userId) {
7006        enforceNotIsolatedCaller("getIntentSender");
7007        // Refuse possible leaked file descriptors
7008        if (intents != null) {
7009            if (intents.length < 1) {
7010                throw new IllegalArgumentException("Intents array length must be >= 1");
7011            }
7012            for (int i=0; i<intents.length; i++) {
7013                Intent intent = intents[i];
7014                if (intent != null) {
7015                    if (intent.hasFileDescriptors()) {
7016                        throw new IllegalArgumentException("File descriptors passed in Intent");
7017                    }
7018                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7019                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7020                        throw new IllegalArgumentException(
7021                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7022                    }
7023                    intents[i] = new Intent(intent);
7024                }
7025            }
7026            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7027                throw new IllegalArgumentException(
7028                        "Intent array length does not match resolvedTypes length");
7029            }
7030        }
7031        if (bOptions != null) {
7032            if (bOptions.hasFileDescriptors()) {
7033                throw new IllegalArgumentException("File descriptors passed in options");
7034            }
7035        }
7036
7037        synchronized(this) {
7038            int callingUid = Binder.getCallingUid();
7039            int origUserId = userId;
7040            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7041                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7042                    ALLOW_NON_FULL, "getIntentSender", null);
7043            if (origUserId == UserHandle.USER_CURRENT) {
7044                // We don't want to evaluate this until the pending intent is
7045                // actually executed.  However, we do want to always do the
7046                // security checking for it above.
7047                userId = UserHandle.USER_CURRENT;
7048            }
7049            try {
7050                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7051                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7052                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7053                    if (!UserHandle.isSameApp(callingUid, uid)) {
7054                        String msg = "Permission Denial: getIntentSender() from pid="
7055                            + Binder.getCallingPid()
7056                            + ", uid=" + Binder.getCallingUid()
7057                            + ", (need uid=" + uid + ")"
7058                            + " is not allowed to send as package " + packageName;
7059                        Slog.w(TAG, msg);
7060                        throw new SecurityException(msg);
7061                    }
7062                }
7063
7064                return getIntentSenderLocked(type, packageName, callingUid, userId,
7065                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7066
7067            } catch (RemoteException e) {
7068                throw new SecurityException(e);
7069            }
7070        }
7071    }
7072
7073    IIntentSender getIntentSenderLocked(int type, String packageName,
7074            int callingUid, int userId, IBinder token, String resultWho,
7075            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7076            Bundle bOptions) {
7077        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7078        ActivityRecord activity = null;
7079        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7080            activity = ActivityRecord.isInStackLocked(token);
7081            if (activity == null) {
7082                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7083                return null;
7084            }
7085            if (activity.finishing) {
7086                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7087                return null;
7088            }
7089        }
7090
7091        // We're going to be splicing together extras before sending, so we're
7092        // okay poking into any contained extras.
7093        if (intents != null) {
7094            for (int i = 0; i < intents.length; i++) {
7095                intents[i].setDefusable(true);
7096            }
7097        }
7098        Bundle.setDefusable(bOptions, true);
7099
7100        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7101        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7102        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7103        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7104                |PendingIntent.FLAG_UPDATE_CURRENT);
7105
7106        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7107                type, packageName, activity, resultWho,
7108                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7109        WeakReference<PendingIntentRecord> ref;
7110        ref = mIntentSenderRecords.get(key);
7111        PendingIntentRecord rec = ref != null ? ref.get() : null;
7112        if (rec != null) {
7113            if (!cancelCurrent) {
7114                if (updateCurrent) {
7115                    if (rec.key.requestIntent != null) {
7116                        rec.key.requestIntent.replaceExtras(intents != null ?
7117                                intents[intents.length - 1] : null);
7118                    }
7119                    if (intents != null) {
7120                        intents[intents.length-1] = rec.key.requestIntent;
7121                        rec.key.allIntents = intents;
7122                        rec.key.allResolvedTypes = resolvedTypes;
7123                    } else {
7124                        rec.key.allIntents = null;
7125                        rec.key.allResolvedTypes = null;
7126                    }
7127                }
7128                return rec;
7129            }
7130            rec.canceled = true;
7131            mIntentSenderRecords.remove(key);
7132        }
7133        if (noCreate) {
7134            return rec;
7135        }
7136        rec = new PendingIntentRecord(this, key, callingUid);
7137        mIntentSenderRecords.put(key, rec.ref);
7138        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7139            if (activity.pendingResults == null) {
7140                activity.pendingResults
7141                        = new HashSet<WeakReference<PendingIntentRecord>>();
7142            }
7143            activity.pendingResults.add(rec.ref);
7144        }
7145        return rec;
7146    }
7147
7148    @Override
7149    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7150            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7151        if (target instanceof PendingIntentRecord) {
7152            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7153                    finishedReceiver, requiredPermission, options);
7154        } else {
7155            if (intent == null) {
7156                // Weird case: someone has given us their own custom IIntentSender, and now
7157                // they have someone else trying to send to it but of course this isn't
7158                // really a PendingIntent, so there is no base Intent, and the caller isn't
7159                // supplying an Intent... but we never want to dispatch a null Intent to
7160                // a receiver, so um...  let's make something up.
7161                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7162                intent = new Intent(Intent.ACTION_MAIN);
7163            }
7164            try {
7165                target.send(code, intent, resolvedType, null, requiredPermission, options);
7166            } catch (RemoteException e) {
7167            }
7168            // Platform code can rely on getting a result back when the send is done, but if
7169            // this intent sender is from outside of the system we can't rely on it doing that.
7170            // So instead we don't give it the result receiver, and instead just directly
7171            // report the finish immediately.
7172            if (finishedReceiver != null) {
7173                try {
7174                    finishedReceiver.performReceive(intent, 0,
7175                            null, null, false, false, UserHandle.getCallingUserId());
7176                } catch (RemoteException e) {
7177                }
7178            }
7179            return 0;
7180        }
7181    }
7182
7183    /**
7184     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7185     *
7186     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7187     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7188     */
7189    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7190        if (DEBUG_WHITELISTS) {
7191            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7192                    + targetUid + ", " + duration + ")");
7193        }
7194        synchronized (mPidsSelfLocked) {
7195            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7196            if (pr == null) {
7197                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7198                return;
7199            }
7200            if (!pr.whitelistManager) {
7201                if (DEBUG_WHITELISTS) {
7202                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7203                            + callerPid + " is not allowed");
7204                }
7205                return;
7206            }
7207        }
7208
7209        final long token = Binder.clearCallingIdentity();
7210        try {
7211            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7212                    true, "pe from uid:" + callerUid);
7213        } finally {
7214            Binder.restoreCallingIdentity(token);
7215        }
7216    }
7217
7218    @Override
7219    public void cancelIntentSender(IIntentSender sender) {
7220        if (!(sender instanceof PendingIntentRecord)) {
7221            return;
7222        }
7223        synchronized(this) {
7224            PendingIntentRecord rec = (PendingIntentRecord)sender;
7225            try {
7226                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7227                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7228                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7229                    String msg = "Permission Denial: cancelIntentSender() from pid="
7230                        + Binder.getCallingPid()
7231                        + ", uid=" + Binder.getCallingUid()
7232                        + " is not allowed to cancel packges "
7233                        + rec.key.packageName;
7234                    Slog.w(TAG, msg);
7235                    throw new SecurityException(msg);
7236                }
7237            } catch (RemoteException e) {
7238                throw new SecurityException(e);
7239            }
7240            cancelIntentSenderLocked(rec, true);
7241        }
7242    }
7243
7244    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7245        rec.canceled = true;
7246        mIntentSenderRecords.remove(rec.key);
7247        if (cleanActivity && rec.key.activity != null) {
7248            rec.key.activity.pendingResults.remove(rec.ref);
7249        }
7250    }
7251
7252    @Override
7253    public String getPackageForIntentSender(IIntentSender pendingResult) {
7254        if (!(pendingResult instanceof PendingIntentRecord)) {
7255            return null;
7256        }
7257        try {
7258            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7259            return res.key.packageName;
7260        } catch (ClassCastException e) {
7261        }
7262        return null;
7263    }
7264
7265    @Override
7266    public int getUidForIntentSender(IIntentSender sender) {
7267        if (sender instanceof PendingIntentRecord) {
7268            try {
7269                PendingIntentRecord res = (PendingIntentRecord)sender;
7270                return res.uid;
7271            } catch (ClassCastException e) {
7272            }
7273        }
7274        return -1;
7275    }
7276
7277    @Override
7278    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7279        if (!(pendingResult instanceof PendingIntentRecord)) {
7280            return false;
7281        }
7282        try {
7283            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7284            if (res.key.allIntents == null) {
7285                return false;
7286            }
7287            for (int i=0; i<res.key.allIntents.length; i++) {
7288                Intent intent = res.key.allIntents[i];
7289                if (intent.getPackage() != null && intent.getComponent() != null) {
7290                    return false;
7291                }
7292            }
7293            return true;
7294        } catch (ClassCastException e) {
7295        }
7296        return false;
7297    }
7298
7299    @Override
7300    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7301        if (!(pendingResult instanceof PendingIntentRecord)) {
7302            return false;
7303        }
7304        try {
7305            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7306            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7307                return true;
7308            }
7309            return false;
7310        } catch (ClassCastException e) {
7311        }
7312        return false;
7313    }
7314
7315    @Override
7316    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7317        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7318                "getIntentForIntentSender()");
7319        if (!(pendingResult instanceof PendingIntentRecord)) {
7320            return null;
7321        }
7322        try {
7323            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7324            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7325        } catch (ClassCastException e) {
7326        }
7327        return null;
7328    }
7329
7330    @Override
7331    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7332        if (!(pendingResult instanceof PendingIntentRecord)) {
7333            return null;
7334        }
7335        try {
7336            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7337            synchronized (this) {
7338                return getTagForIntentSenderLocked(res, prefix);
7339            }
7340        } catch (ClassCastException e) {
7341        }
7342        return null;
7343    }
7344
7345    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7346        final Intent intent = res.key.requestIntent;
7347        if (intent != null) {
7348            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7349                    || res.lastTagPrefix.equals(prefix))) {
7350                return res.lastTag;
7351            }
7352            res.lastTagPrefix = prefix;
7353            final StringBuilder sb = new StringBuilder(128);
7354            if (prefix != null) {
7355                sb.append(prefix);
7356            }
7357            if (intent.getAction() != null) {
7358                sb.append(intent.getAction());
7359            } else if (intent.getComponent() != null) {
7360                intent.getComponent().appendShortString(sb);
7361            } else {
7362                sb.append("?");
7363            }
7364            return res.lastTag = sb.toString();
7365        }
7366        return null;
7367    }
7368
7369    @Override
7370    public void setProcessLimit(int max) {
7371        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7372                "setProcessLimit()");
7373        synchronized (this) {
7374            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7375            mProcessLimitOverride = max;
7376        }
7377        trimApplications();
7378    }
7379
7380    @Override
7381    public int getProcessLimit() {
7382        synchronized (this) {
7383            return mProcessLimitOverride;
7384        }
7385    }
7386
7387    void foregroundTokenDied(ForegroundToken token) {
7388        synchronized (ActivityManagerService.this) {
7389            synchronized (mPidsSelfLocked) {
7390                ForegroundToken cur
7391                    = mForegroundProcesses.get(token.pid);
7392                if (cur != token) {
7393                    return;
7394                }
7395                mForegroundProcesses.remove(token.pid);
7396                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7397                if (pr == null) {
7398                    return;
7399                }
7400                pr.forcingToForeground = null;
7401                updateProcessForegroundLocked(pr, false, false);
7402            }
7403            updateOomAdjLocked();
7404        }
7405    }
7406
7407    @Override
7408    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7409        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7410                "setProcessForeground()");
7411        synchronized(this) {
7412            boolean changed = false;
7413
7414            synchronized (mPidsSelfLocked) {
7415                ProcessRecord pr = mPidsSelfLocked.get(pid);
7416                if (pr == null && isForeground) {
7417                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7418                    return;
7419                }
7420                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7421                if (oldToken != null) {
7422                    oldToken.token.unlinkToDeath(oldToken, 0);
7423                    mForegroundProcesses.remove(pid);
7424                    if (pr != null) {
7425                        pr.forcingToForeground = null;
7426                    }
7427                    changed = true;
7428                }
7429                if (isForeground && token != null) {
7430                    ForegroundToken newToken = new ForegroundToken() {
7431                        @Override
7432                        public void binderDied() {
7433                            foregroundTokenDied(this);
7434                        }
7435                    };
7436                    newToken.pid = pid;
7437                    newToken.token = token;
7438                    try {
7439                        token.linkToDeath(newToken, 0);
7440                        mForegroundProcesses.put(pid, newToken);
7441                        pr.forcingToForeground = token;
7442                        changed = true;
7443                    } catch (RemoteException e) {
7444                        // If the process died while doing this, we will later
7445                        // do the cleanup with the process death link.
7446                    }
7447                }
7448            }
7449
7450            if (changed) {
7451                updateOomAdjLocked();
7452            }
7453        }
7454    }
7455
7456    @Override
7457    public boolean isAppForeground(int uid) throws RemoteException {
7458        synchronized (this) {
7459            UidRecord uidRec = mActiveUids.get(uid);
7460            if (uidRec == null || uidRec.idle) {
7461                return false;
7462            }
7463            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7464        }
7465    }
7466
7467    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7468    // be guarded by permission checking.
7469    int getUidState(int uid) {
7470        synchronized (this) {
7471            UidRecord uidRec = mActiveUids.get(uid);
7472            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7473        }
7474    }
7475
7476    @Override
7477    public boolean isInMultiWindowMode(IBinder token) {
7478        final long origId = Binder.clearCallingIdentity();
7479        try {
7480            synchronized(this) {
7481                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7482                if (r == null) {
7483                    return false;
7484                }
7485                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7486                return !r.task.mFullscreen;
7487            }
7488        } finally {
7489            Binder.restoreCallingIdentity(origId);
7490        }
7491    }
7492
7493    @Override
7494    public boolean isInPictureInPictureMode(IBinder token) {
7495        final long origId = Binder.clearCallingIdentity();
7496        try {
7497            synchronized(this) {
7498                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7499                if (stack == null) {
7500                    return false;
7501                }
7502                return stack.mStackId == PINNED_STACK_ID;
7503            }
7504        } finally {
7505            Binder.restoreCallingIdentity(origId);
7506        }
7507    }
7508
7509    @Override
7510    public void enterPictureInPictureMode(IBinder token) {
7511        final long origId = Binder.clearCallingIdentity();
7512        try {
7513            synchronized(this) {
7514                if (!mSupportsPictureInPicture) {
7515                    throw new IllegalStateException("enterPictureInPictureMode: "
7516                            + "Device doesn't support picture-in-picture mode.");
7517                }
7518
7519                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7520
7521                if (r == null) {
7522                    throw new IllegalStateException("enterPictureInPictureMode: "
7523                            + "Can't find activity for token=" + token);
7524                }
7525
7526                if (!r.supportsPictureInPicture()) {
7527                    throw new IllegalArgumentException("enterPictureInPictureMode: "
7528                            + "Picture-In-Picture not supported for r=" + r);
7529                }
7530
7531                // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7532                // current bounds.
7533                final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7534                final Rect bounds = (pinnedStack != null)
7535                        ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7536
7537                mStackSupervisor.moveActivityToPinnedStackLocked(
7538                        r, "enterPictureInPictureMode", bounds);
7539            }
7540        } finally {
7541            Binder.restoreCallingIdentity(origId);
7542        }
7543    }
7544
7545    // =========================================================
7546    // PROCESS INFO
7547    // =========================================================
7548
7549    static class ProcessInfoService extends IProcessInfoService.Stub {
7550        final ActivityManagerService mActivityManagerService;
7551        ProcessInfoService(ActivityManagerService activityManagerService) {
7552            mActivityManagerService = activityManagerService;
7553        }
7554
7555        @Override
7556        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7557            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7558                    /*in*/ pids, /*out*/ states, null);
7559        }
7560
7561        @Override
7562        public void getProcessStatesAndOomScoresFromPids(
7563                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7564            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7565                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7566        }
7567    }
7568
7569    /**
7570     * For each PID in the given input array, write the current process state
7571     * for that process into the states array, or -1 to indicate that no
7572     * process with the given PID exists. If scores array is provided, write
7573     * the oom score for the process into the scores array, with INVALID_ADJ
7574     * indicating the PID doesn't exist.
7575     */
7576    public void getProcessStatesAndOomScoresForPIDs(
7577            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7578        if (scores != null) {
7579            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7580                    "getProcessStatesAndOomScoresForPIDs()");
7581        }
7582
7583        if (pids == null) {
7584            throw new NullPointerException("pids");
7585        } else if (states == null) {
7586            throw new NullPointerException("states");
7587        } else if (pids.length != states.length) {
7588            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7589        } else if (scores != null && pids.length != scores.length) {
7590            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7591        }
7592
7593        synchronized (mPidsSelfLocked) {
7594            for (int i = 0; i < pids.length; i++) {
7595                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7596                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7597                        pr.curProcState;
7598                if (scores != null) {
7599                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7600                }
7601            }
7602        }
7603    }
7604
7605    // =========================================================
7606    // PERMISSIONS
7607    // =========================================================
7608
7609    static class PermissionController extends IPermissionController.Stub {
7610        ActivityManagerService mActivityManagerService;
7611        PermissionController(ActivityManagerService activityManagerService) {
7612            mActivityManagerService = activityManagerService;
7613        }
7614
7615        @Override
7616        public boolean checkPermission(String permission, int pid, int uid) {
7617            return mActivityManagerService.checkPermission(permission, pid,
7618                    uid) == PackageManager.PERMISSION_GRANTED;
7619        }
7620
7621        @Override
7622        public String[] getPackagesForUid(int uid) {
7623            return mActivityManagerService.mContext.getPackageManager()
7624                    .getPackagesForUid(uid);
7625        }
7626
7627        @Override
7628        public boolean isRuntimePermission(String permission) {
7629            try {
7630                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7631                        .getPermissionInfo(permission, 0);
7632                return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7633            } catch (NameNotFoundException nnfe) {
7634                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7635            }
7636            return false;
7637        }
7638    }
7639
7640    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7641        @Override
7642        public int checkComponentPermission(String permission, int pid, int uid,
7643                int owningUid, boolean exported) {
7644            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7645                    owningUid, exported);
7646        }
7647
7648        @Override
7649        public Object getAMSLock() {
7650            return ActivityManagerService.this;
7651        }
7652    }
7653
7654    /**
7655     * This can be called with or without the global lock held.
7656     */
7657    int checkComponentPermission(String permission, int pid, int uid,
7658            int owningUid, boolean exported) {
7659        if (pid == MY_PID) {
7660            return PackageManager.PERMISSION_GRANTED;
7661        }
7662        return ActivityManager.checkComponentPermission(permission, uid,
7663                owningUid, exported);
7664    }
7665
7666    /**
7667     * As the only public entry point for permissions checking, this method
7668     * can enforce the semantic that requesting a check on a null global
7669     * permission is automatically denied.  (Internally a null permission
7670     * string is used when calling {@link #checkComponentPermission} in cases
7671     * when only uid-based security is needed.)
7672     *
7673     * This can be called with or without the global lock held.
7674     */
7675    @Override
7676    public int checkPermission(String permission, int pid, int uid) {
7677        if (permission == null) {
7678            return PackageManager.PERMISSION_DENIED;
7679        }
7680        return checkComponentPermission(permission, pid, uid, -1, true);
7681    }
7682
7683    @Override
7684    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7685        if (permission == null) {
7686            return PackageManager.PERMISSION_DENIED;
7687        }
7688
7689        // We might be performing an operation on behalf of an indirect binder
7690        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7691        // client identity accordingly before proceeding.
7692        Identity tlsIdentity = sCallerIdentity.get();
7693        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7694            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7695                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7696            uid = tlsIdentity.uid;
7697            pid = tlsIdentity.pid;
7698        }
7699
7700        return checkComponentPermission(permission, pid, uid, -1, true);
7701    }
7702
7703    /**
7704     * Binder IPC calls go through the public entry point.
7705     * This can be called with or without the global lock held.
7706     */
7707    int checkCallingPermission(String permission) {
7708        return checkPermission(permission,
7709                Binder.getCallingPid(),
7710                UserHandle.getAppId(Binder.getCallingUid()));
7711    }
7712
7713    /**
7714     * This can be called with or without the global lock held.
7715     */
7716    void enforceCallingPermission(String permission, String func) {
7717        if (checkCallingPermission(permission)
7718                == PackageManager.PERMISSION_GRANTED) {
7719            return;
7720        }
7721
7722        String msg = "Permission Denial: " + func + " from pid="
7723                + Binder.getCallingPid()
7724                + ", uid=" + Binder.getCallingUid()
7725                + " requires " + permission;
7726        Slog.w(TAG, msg);
7727        throw new SecurityException(msg);
7728    }
7729
7730    /**
7731     * Determine if UID is holding permissions required to access {@link Uri} in
7732     * the given {@link ProviderInfo}. Final permission checking is always done
7733     * in {@link ContentProvider}.
7734     */
7735    private final boolean checkHoldingPermissionsLocked(
7736            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7737        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7738                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7739        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7740            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7741                    != PERMISSION_GRANTED) {
7742                return false;
7743            }
7744        }
7745        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7746    }
7747
7748    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7749            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7750        if (pi.applicationInfo.uid == uid) {
7751            return true;
7752        } else if (!pi.exported) {
7753            return false;
7754        }
7755
7756        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7757        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7758        try {
7759            // check if target holds top-level <provider> permissions
7760            if (!readMet && pi.readPermission != null && considerUidPermissions
7761                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7762                readMet = true;
7763            }
7764            if (!writeMet && pi.writePermission != null && considerUidPermissions
7765                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7766                writeMet = true;
7767            }
7768
7769            // track if unprotected read/write is allowed; any denied
7770            // <path-permission> below removes this ability
7771            boolean allowDefaultRead = pi.readPermission == null;
7772            boolean allowDefaultWrite = pi.writePermission == null;
7773
7774            // check if target holds any <path-permission> that match uri
7775            final PathPermission[] pps = pi.pathPermissions;
7776            if (pps != null) {
7777                final String path = grantUri.uri.getPath();
7778                int i = pps.length;
7779                while (i > 0 && (!readMet || !writeMet)) {
7780                    i--;
7781                    PathPermission pp = pps[i];
7782                    if (pp.match(path)) {
7783                        if (!readMet) {
7784                            final String pprperm = pp.getReadPermission();
7785                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7786                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7787                                    + ": match=" + pp.match(path)
7788                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7789                            if (pprperm != null) {
7790                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7791                                        == PERMISSION_GRANTED) {
7792                                    readMet = true;
7793                                } else {
7794                                    allowDefaultRead = false;
7795                                }
7796                            }
7797                        }
7798                        if (!writeMet) {
7799                            final String ppwperm = pp.getWritePermission();
7800                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7801                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7802                                    + ": match=" + pp.match(path)
7803                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7804                            if (ppwperm != null) {
7805                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7806                                        == PERMISSION_GRANTED) {
7807                                    writeMet = true;
7808                                } else {
7809                                    allowDefaultWrite = false;
7810                                }
7811                            }
7812                        }
7813                    }
7814                }
7815            }
7816
7817            // grant unprotected <provider> read/write, if not blocked by
7818            // <path-permission> above
7819            if (allowDefaultRead) readMet = true;
7820            if (allowDefaultWrite) writeMet = true;
7821
7822        } catch (RemoteException e) {
7823            return false;
7824        }
7825
7826        return readMet && writeMet;
7827    }
7828
7829    public int getAppStartMode(int uid, String packageName) {
7830        synchronized (this) {
7831            return checkAllowBackgroundLocked(uid, packageName, -1, true);
7832        }
7833    }
7834
7835    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7836            boolean allowWhenForeground) {
7837        UidRecord uidRec = mActiveUids.get(uid);
7838        if (!mLenientBackgroundCheck) {
7839            if (!allowWhenForeground || uidRec == null
7840                    || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7841                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7842                        packageName) != AppOpsManager.MODE_ALLOWED) {
7843                    return ActivityManager.APP_START_MODE_DELAYED;
7844                }
7845            }
7846
7847        } else if (uidRec == null || uidRec.idle) {
7848            if (callingPid >= 0) {
7849                ProcessRecord proc;
7850                synchronized (mPidsSelfLocked) {
7851                    proc = mPidsSelfLocked.get(callingPid);
7852                }
7853                if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7854                    // Whoever is instigating this is in the foreground, so we will allow it
7855                    // to go through.
7856                    return ActivityManager.APP_START_MODE_NORMAL;
7857                }
7858            }
7859            if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7860                    != AppOpsManager.MODE_ALLOWED) {
7861                return ActivityManager.APP_START_MODE_DELAYED;
7862            }
7863        }
7864        return ActivityManager.APP_START_MODE_NORMAL;
7865    }
7866
7867    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7868        ProviderInfo pi = null;
7869        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7870        if (cpr != null) {
7871            pi = cpr.info;
7872        } else {
7873            try {
7874                pi = AppGlobals.getPackageManager().resolveContentProvider(
7875                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7876                        userHandle);
7877            } catch (RemoteException ex) {
7878            }
7879        }
7880        return pi;
7881    }
7882
7883    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7884        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7885        if (targetUris != null) {
7886            return targetUris.get(grantUri);
7887        }
7888        return null;
7889    }
7890
7891    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7892            String targetPkg, int targetUid, GrantUri grantUri) {
7893        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7894        if (targetUris == null) {
7895            targetUris = Maps.newArrayMap();
7896            mGrantedUriPermissions.put(targetUid, targetUris);
7897        }
7898
7899        UriPermission perm = targetUris.get(grantUri);
7900        if (perm == null) {
7901            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7902            targetUris.put(grantUri, perm);
7903        }
7904
7905        return perm;
7906    }
7907
7908    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7909            final int modeFlags) {
7910        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7911        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7912                : UriPermission.STRENGTH_OWNED;
7913
7914        // Root gets to do everything.
7915        if (uid == 0) {
7916            return true;
7917        }
7918
7919        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7920        if (perms == null) return false;
7921
7922        // First look for exact match
7923        final UriPermission exactPerm = perms.get(grantUri);
7924        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7925            return true;
7926        }
7927
7928        // No exact match, look for prefixes
7929        final int N = perms.size();
7930        for (int i = 0; i < N; i++) {
7931            final UriPermission perm = perms.valueAt(i);
7932            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7933                    && perm.getStrength(modeFlags) >= minStrength) {
7934                return true;
7935            }
7936        }
7937
7938        return false;
7939    }
7940
7941    /**
7942     * @param uri This uri must NOT contain an embedded userId.
7943     * @param userId The userId in which the uri is to be resolved.
7944     */
7945    @Override
7946    public int checkUriPermission(Uri uri, int pid, int uid,
7947            final int modeFlags, int userId, IBinder callerToken) {
7948        enforceNotIsolatedCaller("checkUriPermission");
7949
7950        // Another redirected-binder-call permissions check as in
7951        // {@link checkPermissionWithToken}.
7952        Identity tlsIdentity = sCallerIdentity.get();
7953        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7954            uid = tlsIdentity.uid;
7955            pid = tlsIdentity.pid;
7956        }
7957
7958        // Our own process gets to do everything.
7959        if (pid == MY_PID) {
7960            return PackageManager.PERMISSION_GRANTED;
7961        }
7962        synchronized (this) {
7963            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7964                    ? PackageManager.PERMISSION_GRANTED
7965                    : PackageManager.PERMISSION_DENIED;
7966        }
7967    }
7968
7969    /**
7970     * Check if the targetPkg can be granted permission to access uri by
7971     * the callingUid using the given modeFlags.  Throws a security exception
7972     * if callingUid is not allowed to do this.  Returns the uid of the target
7973     * if the URI permission grant should be performed; returns -1 if it is not
7974     * needed (for example targetPkg already has permission to access the URI).
7975     * If you already know the uid of the target, you can supply it in
7976     * lastTargetUid else set that to -1.
7977     */
7978    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7979            final int modeFlags, int lastTargetUid) {
7980        if (!Intent.isAccessUriMode(modeFlags)) {
7981            return -1;
7982        }
7983
7984        if (targetPkg != null) {
7985            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7986                    "Checking grant " + targetPkg + " permission to " + grantUri);
7987        }
7988
7989        final IPackageManager pm = AppGlobals.getPackageManager();
7990
7991        // If this is not a content: uri, we can't do anything with it.
7992        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7993            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7994                    "Can't grant URI permission for non-content URI: " + grantUri);
7995            return -1;
7996        }
7997
7998        final String authority = grantUri.uri.getAuthority();
7999        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8000                MATCH_DEBUG_TRIAGED_MISSING);
8001        if (pi == null) {
8002            Slog.w(TAG, "No content provider found for permission check: " +
8003                    grantUri.uri.toSafeString());
8004            return -1;
8005        }
8006
8007        int targetUid = lastTargetUid;
8008        if (targetUid < 0 && targetPkg != null) {
8009            try {
8010                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8011                        UserHandle.getUserId(callingUid));
8012                if (targetUid < 0) {
8013                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8014                            "Can't grant URI permission no uid for: " + targetPkg);
8015                    return -1;
8016                }
8017            } catch (RemoteException ex) {
8018                return -1;
8019            }
8020        }
8021
8022        if (targetUid >= 0) {
8023            // First...  does the target actually need this permission?
8024            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8025                // No need to grant the target this permission.
8026                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8027                        "Target " + targetPkg + " already has full permission to " + grantUri);
8028                return -1;
8029            }
8030        } else {
8031            // First...  there is no target package, so can anyone access it?
8032            boolean allowed = pi.exported;
8033            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8034                if (pi.readPermission != null) {
8035                    allowed = false;
8036                }
8037            }
8038            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8039                if (pi.writePermission != null) {
8040                    allowed = false;
8041                }
8042            }
8043            if (allowed) {
8044                return -1;
8045            }
8046        }
8047
8048        /* There is a special cross user grant if:
8049         * - The target is on another user.
8050         * - Apps on the current user can access the uri without any uid permissions.
8051         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8052         * grant uri permissions.
8053         */
8054        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8055                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8056                modeFlags, false /*without considering the uid permissions*/);
8057
8058        // Second...  is the provider allowing granting of URI permissions?
8059        if (!specialCrossUserGrant) {
8060            if (!pi.grantUriPermissions) {
8061                throw new SecurityException("Provider " + pi.packageName
8062                        + "/" + pi.name
8063                        + " does not allow granting of Uri permissions (uri "
8064                        + grantUri + ")");
8065            }
8066            if (pi.uriPermissionPatterns != null) {
8067                final int N = pi.uriPermissionPatterns.length;
8068                boolean allowed = false;
8069                for (int i=0; i<N; i++) {
8070                    if (pi.uriPermissionPatterns[i] != null
8071                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8072                        allowed = true;
8073                        break;
8074                    }
8075                }
8076                if (!allowed) {
8077                    throw new SecurityException("Provider " + pi.packageName
8078                            + "/" + pi.name
8079                            + " does not allow granting of permission to path of Uri "
8080                            + grantUri);
8081                }
8082            }
8083        }
8084
8085        // Third...  does the caller itself have permission to access
8086        // this uri?
8087        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8088            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8089                // Require they hold a strong enough Uri permission
8090                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8091                    throw new SecurityException("Uid " + callingUid
8092                            + " does not have permission to uri " + grantUri);
8093                }
8094            }
8095        }
8096        return targetUid;
8097    }
8098
8099    /**
8100     * @param uri This uri must NOT contain an embedded userId.
8101     * @param userId The userId in which the uri is to be resolved.
8102     */
8103    @Override
8104    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8105            final int modeFlags, int userId) {
8106        enforceNotIsolatedCaller("checkGrantUriPermission");
8107        synchronized(this) {
8108            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8109                    new GrantUri(userId, uri, false), modeFlags, -1);
8110        }
8111    }
8112
8113    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8114            final int modeFlags, UriPermissionOwner owner) {
8115        if (!Intent.isAccessUriMode(modeFlags)) {
8116            return;
8117        }
8118
8119        // So here we are: the caller has the assumed permission
8120        // to the uri, and the target doesn't.  Let's now give this to
8121        // the target.
8122
8123        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8124                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8125
8126        final String authority = grantUri.uri.getAuthority();
8127        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8128                MATCH_DEBUG_TRIAGED_MISSING);
8129        if (pi == null) {
8130            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8131            return;
8132        }
8133
8134        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8135            grantUri.prefix = true;
8136        }
8137        final UriPermission perm = findOrCreateUriPermissionLocked(
8138                pi.packageName, targetPkg, targetUid, grantUri);
8139        perm.grantModes(modeFlags, owner);
8140    }
8141
8142    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8143            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8144        if (targetPkg == null) {
8145            throw new NullPointerException("targetPkg");
8146        }
8147        int targetUid;
8148        final IPackageManager pm = AppGlobals.getPackageManager();
8149        try {
8150            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8151        } catch (RemoteException ex) {
8152            return;
8153        }
8154
8155        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8156                targetUid);
8157        if (targetUid < 0) {
8158            return;
8159        }
8160
8161        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8162                owner);
8163    }
8164
8165    static class NeededUriGrants extends ArrayList<GrantUri> {
8166        final String targetPkg;
8167        final int targetUid;
8168        final int flags;
8169
8170        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8171            this.targetPkg = targetPkg;
8172            this.targetUid = targetUid;
8173            this.flags = flags;
8174        }
8175    }
8176
8177    /**
8178     * Like checkGrantUriPermissionLocked, but takes an Intent.
8179     */
8180    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8181            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8182        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8183                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8184                + " clip=" + (intent != null ? intent.getClipData() : null)
8185                + " from " + intent + "; flags=0x"
8186                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8187
8188        if (targetPkg == null) {
8189            throw new NullPointerException("targetPkg");
8190        }
8191
8192        if (intent == null) {
8193            return null;
8194        }
8195        Uri data = intent.getData();
8196        ClipData clip = intent.getClipData();
8197        if (data == null && clip == null) {
8198            return null;
8199        }
8200        // Default userId for uris in the intent (if they don't specify it themselves)
8201        int contentUserHint = intent.getContentUserHint();
8202        if (contentUserHint == UserHandle.USER_CURRENT) {
8203            contentUserHint = UserHandle.getUserId(callingUid);
8204        }
8205        final IPackageManager pm = AppGlobals.getPackageManager();
8206        int targetUid;
8207        if (needed != null) {
8208            targetUid = needed.targetUid;
8209        } else {
8210            try {
8211                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8212                        targetUserId);
8213            } catch (RemoteException ex) {
8214                return null;
8215            }
8216            if (targetUid < 0) {
8217                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8218                        "Can't grant URI permission no uid for: " + targetPkg
8219                        + " on user " + targetUserId);
8220                return null;
8221            }
8222        }
8223        if (data != null) {
8224            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8225            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8226                    targetUid);
8227            if (targetUid > 0) {
8228                if (needed == null) {
8229                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8230                }
8231                needed.add(grantUri);
8232            }
8233        }
8234        if (clip != null) {
8235            for (int i=0; i<clip.getItemCount(); i++) {
8236                Uri uri = clip.getItemAt(i).getUri();
8237                if (uri != null) {
8238                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8239                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8240                            targetUid);
8241                    if (targetUid > 0) {
8242                        if (needed == null) {
8243                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8244                        }
8245                        needed.add(grantUri);
8246                    }
8247                } else {
8248                    Intent clipIntent = clip.getItemAt(i).getIntent();
8249                    if (clipIntent != null) {
8250                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8251                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8252                        if (newNeeded != null) {
8253                            needed = newNeeded;
8254                        }
8255                    }
8256                }
8257            }
8258        }
8259
8260        return needed;
8261    }
8262
8263    /**
8264     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8265     */
8266    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8267            UriPermissionOwner owner) {
8268        if (needed != null) {
8269            for (int i=0; i<needed.size(); i++) {
8270                GrantUri grantUri = needed.get(i);
8271                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8272                        grantUri, needed.flags, owner);
8273            }
8274        }
8275    }
8276
8277    void grantUriPermissionFromIntentLocked(int callingUid,
8278            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8279        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8280                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8281        if (needed == null) {
8282            return;
8283        }
8284
8285        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8286    }
8287
8288    /**
8289     * @param uri This uri must NOT contain an embedded userId.
8290     * @param userId The userId in which the uri is to be resolved.
8291     */
8292    @Override
8293    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8294            final int modeFlags, int userId) {
8295        enforceNotIsolatedCaller("grantUriPermission");
8296        GrantUri grantUri = new GrantUri(userId, uri, false);
8297        synchronized(this) {
8298            final ProcessRecord r = getRecordForAppLocked(caller);
8299            if (r == null) {
8300                throw new SecurityException("Unable to find app for caller "
8301                        + caller
8302                        + " when granting permission to uri " + grantUri);
8303            }
8304            if (targetPkg == null) {
8305                throw new IllegalArgumentException("null target");
8306            }
8307            if (grantUri == null) {
8308                throw new IllegalArgumentException("null uri");
8309            }
8310
8311            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8312                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8313                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8314                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8315
8316            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8317                    UserHandle.getUserId(r.uid));
8318        }
8319    }
8320
8321    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8322        if (perm.modeFlags == 0) {
8323            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8324                    perm.targetUid);
8325            if (perms != null) {
8326                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8327                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8328
8329                perms.remove(perm.uri);
8330                if (perms.isEmpty()) {
8331                    mGrantedUriPermissions.remove(perm.targetUid);
8332                }
8333            }
8334        }
8335    }
8336
8337    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8338        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8339                "Revoking all granted permissions to " + grantUri);
8340
8341        final IPackageManager pm = AppGlobals.getPackageManager();
8342        final String authority = grantUri.uri.getAuthority();
8343        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8344                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8345        if (pi == null) {
8346            Slog.w(TAG, "No content provider found for permission revoke: "
8347                    + grantUri.toSafeString());
8348            return;
8349        }
8350
8351        // Does the caller have this permission on the URI?
8352        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8353            // If they don't have direct access to the URI, then revoke any
8354            // ownerless URI permissions that have been granted to them.
8355            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8356            if (perms != null) {
8357                boolean persistChanged = false;
8358                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8359                    final UriPermission perm = it.next();
8360                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8361                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8362                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8363                                "Revoking non-owned " + perm.targetUid
8364                                + " permission to " + perm.uri);
8365                        persistChanged |= perm.revokeModes(
8366                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8367                        if (perm.modeFlags == 0) {
8368                            it.remove();
8369                        }
8370                    }
8371                }
8372                if (perms.isEmpty()) {
8373                    mGrantedUriPermissions.remove(callingUid);
8374                }
8375                if (persistChanged) {
8376                    schedulePersistUriGrants();
8377                }
8378            }
8379            return;
8380        }
8381
8382        boolean persistChanged = false;
8383
8384        // Go through all of the permissions and remove any that match.
8385        int N = mGrantedUriPermissions.size();
8386        for (int i = 0; i < N; i++) {
8387            final int targetUid = mGrantedUriPermissions.keyAt(i);
8388            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8389
8390            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8391                final UriPermission perm = it.next();
8392                if (perm.uri.sourceUserId == grantUri.sourceUserId
8393                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8394                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8395                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8396                    persistChanged |= perm.revokeModes(
8397                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8398                    if (perm.modeFlags == 0) {
8399                        it.remove();
8400                    }
8401                }
8402            }
8403
8404            if (perms.isEmpty()) {
8405                mGrantedUriPermissions.remove(targetUid);
8406                N--;
8407                i--;
8408            }
8409        }
8410
8411        if (persistChanged) {
8412            schedulePersistUriGrants();
8413        }
8414    }
8415
8416    /**
8417     * @param uri This uri must NOT contain an embedded userId.
8418     * @param userId The userId in which the uri is to be resolved.
8419     */
8420    @Override
8421    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8422            int userId) {
8423        enforceNotIsolatedCaller("revokeUriPermission");
8424        synchronized(this) {
8425            final ProcessRecord r = getRecordForAppLocked(caller);
8426            if (r == null) {
8427                throw new SecurityException("Unable to find app for caller "
8428                        + caller
8429                        + " when revoking permission to uri " + uri);
8430            }
8431            if (uri == null) {
8432                Slog.w(TAG, "revokeUriPermission: null uri");
8433                return;
8434            }
8435
8436            if (!Intent.isAccessUriMode(modeFlags)) {
8437                return;
8438            }
8439
8440            final String authority = uri.getAuthority();
8441            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8442                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8443            if (pi == null) {
8444                Slog.w(TAG, "No content provider found for permission revoke: "
8445                        + uri.toSafeString());
8446                return;
8447            }
8448
8449            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8450        }
8451    }
8452
8453    /**
8454     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8455     * given package.
8456     *
8457     * @param packageName Package name to match, or {@code null} to apply to all
8458     *            packages.
8459     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8460     *            to all users.
8461     * @param persistable If persistable grants should be removed.
8462     */
8463    private void removeUriPermissionsForPackageLocked(
8464            String packageName, int userHandle, boolean persistable) {
8465        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8466            throw new IllegalArgumentException("Must narrow by either package or user");
8467        }
8468
8469        boolean persistChanged = false;
8470
8471        int N = mGrantedUriPermissions.size();
8472        for (int i = 0; i < N; i++) {
8473            final int targetUid = mGrantedUriPermissions.keyAt(i);
8474            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8475
8476            // Only inspect grants matching user
8477            if (userHandle == UserHandle.USER_ALL
8478                    || userHandle == UserHandle.getUserId(targetUid)) {
8479                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8480                    final UriPermission perm = it.next();
8481
8482                    // Only inspect grants matching package
8483                    if (packageName == null || perm.sourcePkg.equals(packageName)
8484                            || perm.targetPkg.equals(packageName)) {
8485                        persistChanged |= perm.revokeModes(persistable
8486                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8487
8488                        // Only remove when no modes remain; any persisted grants
8489                        // will keep this alive.
8490                        if (perm.modeFlags == 0) {
8491                            it.remove();
8492                        }
8493                    }
8494                }
8495
8496                if (perms.isEmpty()) {
8497                    mGrantedUriPermissions.remove(targetUid);
8498                    N--;
8499                    i--;
8500                }
8501            }
8502        }
8503
8504        if (persistChanged) {
8505            schedulePersistUriGrants();
8506        }
8507    }
8508
8509    @Override
8510    public IBinder newUriPermissionOwner(String name) {
8511        enforceNotIsolatedCaller("newUriPermissionOwner");
8512        synchronized(this) {
8513            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8514            return owner.getExternalTokenLocked();
8515        }
8516    }
8517
8518    @Override
8519    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8520        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8521        synchronized(this) {
8522            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8523            if (r == null) {
8524                throw new IllegalArgumentException("Activity does not exist; token="
8525                        + activityToken);
8526            }
8527            return r.getUriPermissionsLocked().getExternalTokenLocked();
8528        }
8529    }
8530    /**
8531     * @param uri This uri must NOT contain an embedded userId.
8532     * @param sourceUserId The userId in which the uri is to be resolved.
8533     * @param targetUserId The userId of the app that receives the grant.
8534     */
8535    @Override
8536    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8537            final int modeFlags, int sourceUserId, int targetUserId) {
8538        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8539                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8540                "grantUriPermissionFromOwner", null);
8541        synchronized(this) {
8542            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8543            if (owner == null) {
8544                throw new IllegalArgumentException("Unknown owner: " + token);
8545            }
8546            if (fromUid != Binder.getCallingUid()) {
8547                if (Binder.getCallingUid() != Process.myUid()) {
8548                    // Only system code can grant URI permissions on behalf
8549                    // of other users.
8550                    throw new SecurityException("nice try");
8551                }
8552            }
8553            if (targetPkg == null) {
8554                throw new IllegalArgumentException("null target");
8555            }
8556            if (uri == null) {
8557                throw new IllegalArgumentException("null uri");
8558            }
8559
8560            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8561                    modeFlags, owner, targetUserId);
8562        }
8563    }
8564
8565    /**
8566     * @param uri This uri must NOT contain an embedded userId.
8567     * @param userId The userId in which the uri is to be resolved.
8568     */
8569    @Override
8570    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8571        synchronized(this) {
8572            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8573            if (owner == null) {
8574                throw new IllegalArgumentException("Unknown owner: " + token);
8575            }
8576
8577            if (uri == null) {
8578                owner.removeUriPermissionsLocked(mode);
8579            } else {
8580                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8581            }
8582        }
8583    }
8584
8585    private void schedulePersistUriGrants() {
8586        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8587            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8588                    10 * DateUtils.SECOND_IN_MILLIS);
8589        }
8590    }
8591
8592    private void writeGrantedUriPermissions() {
8593        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8594
8595        // Snapshot permissions so we can persist without lock
8596        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8597        synchronized (this) {
8598            final int size = mGrantedUriPermissions.size();
8599            for (int i = 0; i < size; i++) {
8600                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8601                for (UriPermission perm : perms.values()) {
8602                    if (perm.persistedModeFlags != 0) {
8603                        persist.add(perm.snapshot());
8604                    }
8605                }
8606            }
8607        }
8608
8609        FileOutputStream fos = null;
8610        try {
8611            fos = mGrantFile.startWrite();
8612
8613            XmlSerializer out = new FastXmlSerializer();
8614            out.setOutput(fos, StandardCharsets.UTF_8.name());
8615            out.startDocument(null, true);
8616            out.startTag(null, TAG_URI_GRANTS);
8617            for (UriPermission.Snapshot perm : persist) {
8618                out.startTag(null, TAG_URI_GRANT);
8619                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8620                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8621                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8622                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8623                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8624                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8625                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8626                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8627                out.endTag(null, TAG_URI_GRANT);
8628            }
8629            out.endTag(null, TAG_URI_GRANTS);
8630            out.endDocument();
8631
8632            mGrantFile.finishWrite(fos);
8633        } catch (IOException e) {
8634            if (fos != null) {
8635                mGrantFile.failWrite(fos);
8636            }
8637        }
8638    }
8639
8640    private void readGrantedUriPermissionsLocked() {
8641        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8642
8643        final long now = System.currentTimeMillis();
8644
8645        FileInputStream fis = null;
8646        try {
8647            fis = mGrantFile.openRead();
8648            final XmlPullParser in = Xml.newPullParser();
8649            in.setInput(fis, StandardCharsets.UTF_8.name());
8650
8651            int type;
8652            while ((type = in.next()) != END_DOCUMENT) {
8653                final String tag = in.getName();
8654                if (type == START_TAG) {
8655                    if (TAG_URI_GRANT.equals(tag)) {
8656                        final int sourceUserId;
8657                        final int targetUserId;
8658                        final int userHandle = readIntAttribute(in,
8659                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8660                        if (userHandle != UserHandle.USER_NULL) {
8661                            // For backwards compatibility.
8662                            sourceUserId = userHandle;
8663                            targetUserId = userHandle;
8664                        } else {
8665                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8666                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8667                        }
8668                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8669                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8670                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8671                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8672                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8673                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8674
8675                        // Sanity check that provider still belongs to source package
8676                        // Both direct boot aware and unaware packages are fine as we
8677                        // will do filtering at query time to avoid multiple parsing.
8678                        final ProviderInfo pi = getProviderInfoLocked(
8679                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8680                                        | MATCH_DIRECT_BOOT_UNAWARE);
8681                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8682                            int targetUid = -1;
8683                            try {
8684                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8685                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8686                            } catch (RemoteException e) {
8687                            }
8688                            if (targetUid != -1) {
8689                                final UriPermission perm = findOrCreateUriPermissionLocked(
8690                                        sourcePkg, targetPkg, targetUid,
8691                                        new GrantUri(sourceUserId, uri, prefix));
8692                                perm.initPersistedModes(modeFlags, createdTime);
8693                            }
8694                        } else {
8695                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8696                                    + " but instead found " + pi);
8697                        }
8698                    }
8699                }
8700            }
8701        } catch (FileNotFoundException e) {
8702            // Missing grants is okay
8703        } catch (IOException e) {
8704            Slog.wtf(TAG, "Failed reading Uri grants", e);
8705        } catch (XmlPullParserException e) {
8706            Slog.wtf(TAG, "Failed reading Uri grants", e);
8707        } finally {
8708            IoUtils.closeQuietly(fis);
8709        }
8710    }
8711
8712    /**
8713     * @param uri This uri must NOT contain an embedded userId.
8714     * @param userId The userId in which the uri is to be resolved.
8715     */
8716    @Override
8717    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8718        enforceNotIsolatedCaller("takePersistableUriPermission");
8719
8720        Preconditions.checkFlagsArgument(modeFlags,
8721                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8722
8723        synchronized (this) {
8724            final int callingUid = Binder.getCallingUid();
8725            boolean persistChanged = false;
8726            GrantUri grantUri = new GrantUri(userId, uri, false);
8727
8728            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8729                    new GrantUri(userId, uri, false));
8730            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8731                    new GrantUri(userId, uri, true));
8732
8733            final boolean exactValid = (exactPerm != null)
8734                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8735            final boolean prefixValid = (prefixPerm != null)
8736                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8737
8738            if (!(exactValid || prefixValid)) {
8739                throw new SecurityException("No persistable permission grants found for UID "
8740                        + callingUid + " and Uri " + grantUri.toSafeString());
8741            }
8742
8743            if (exactValid) {
8744                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8745            }
8746            if (prefixValid) {
8747                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8748            }
8749
8750            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8751
8752            if (persistChanged) {
8753                schedulePersistUriGrants();
8754            }
8755        }
8756    }
8757
8758    /**
8759     * @param uri This uri must NOT contain an embedded userId.
8760     * @param userId The userId in which the uri is to be resolved.
8761     */
8762    @Override
8763    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8764        enforceNotIsolatedCaller("releasePersistableUriPermission");
8765
8766        Preconditions.checkFlagsArgument(modeFlags,
8767                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8768
8769        synchronized (this) {
8770            final int callingUid = Binder.getCallingUid();
8771            boolean persistChanged = false;
8772
8773            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8774                    new GrantUri(userId, uri, false));
8775            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8776                    new GrantUri(userId, uri, true));
8777            if (exactPerm == null && prefixPerm == null) {
8778                throw new SecurityException("No permission grants found for UID " + callingUid
8779                        + " and Uri " + uri.toSafeString());
8780            }
8781
8782            if (exactPerm != null) {
8783                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8784                removeUriPermissionIfNeededLocked(exactPerm);
8785            }
8786            if (prefixPerm != null) {
8787                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8788                removeUriPermissionIfNeededLocked(prefixPerm);
8789            }
8790
8791            if (persistChanged) {
8792                schedulePersistUriGrants();
8793            }
8794        }
8795    }
8796
8797    /**
8798     * Prune any older {@link UriPermission} for the given UID until outstanding
8799     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8800     *
8801     * @return if any mutations occured that require persisting.
8802     */
8803    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8804        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8805        if (perms == null) return false;
8806        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8807
8808        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8809        for (UriPermission perm : perms.values()) {
8810            if (perm.persistedModeFlags != 0) {
8811                persisted.add(perm);
8812            }
8813        }
8814
8815        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8816        if (trimCount <= 0) return false;
8817
8818        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8819        for (int i = 0; i < trimCount; i++) {
8820            final UriPermission perm = persisted.get(i);
8821
8822            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8823                    "Trimming grant created at " + perm.persistedCreateTime);
8824
8825            perm.releasePersistableModes(~0);
8826            removeUriPermissionIfNeededLocked(perm);
8827        }
8828
8829        return true;
8830    }
8831
8832    @Override
8833    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8834            String packageName, boolean incoming) {
8835        enforceNotIsolatedCaller("getPersistedUriPermissions");
8836        Preconditions.checkNotNull(packageName, "packageName");
8837
8838        final int callingUid = Binder.getCallingUid();
8839        final int callingUserId = UserHandle.getUserId(callingUid);
8840        final IPackageManager pm = AppGlobals.getPackageManager();
8841        try {
8842            final int packageUid = pm.getPackageUid(packageName,
8843                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8844            if (packageUid != callingUid) {
8845                throw new SecurityException(
8846                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8847            }
8848        } catch (RemoteException e) {
8849            throw new SecurityException("Failed to verify package name ownership");
8850        }
8851
8852        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8853        synchronized (this) {
8854            if (incoming) {
8855                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8856                        callingUid);
8857                if (perms == null) {
8858                    Slog.w(TAG, "No permission grants found for " + packageName);
8859                } else {
8860                    for (UriPermission perm : perms.values()) {
8861                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8862                            result.add(perm.buildPersistedPublicApiObject());
8863                        }
8864                    }
8865                }
8866            } else {
8867                final int size = mGrantedUriPermissions.size();
8868                for (int i = 0; i < size; i++) {
8869                    final ArrayMap<GrantUri, UriPermission> perms =
8870                            mGrantedUriPermissions.valueAt(i);
8871                    for (UriPermission perm : perms.values()) {
8872                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8873                            result.add(perm.buildPersistedPublicApiObject());
8874                        }
8875                    }
8876                }
8877            }
8878        }
8879        return new ParceledListSlice<android.content.UriPermission>(result);
8880    }
8881
8882    @Override
8883    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8884            String packageName, int userId) {
8885        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8886                "getGrantedUriPermissions");
8887
8888        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8889        synchronized (this) {
8890            final int size = mGrantedUriPermissions.size();
8891            for (int i = 0; i < size; i++) {
8892                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8893                for (UriPermission perm : perms.values()) {
8894                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8895                            && perm.persistedModeFlags != 0) {
8896                        result.add(perm.buildPersistedPublicApiObject());
8897                    }
8898                }
8899            }
8900        }
8901        return new ParceledListSlice<android.content.UriPermission>(result);
8902    }
8903
8904    @Override
8905    public void clearGrantedUriPermissions(String packageName, int userId) {
8906        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8907                "clearGrantedUriPermissions");
8908        removeUriPermissionsForPackageLocked(packageName, userId, true);
8909    }
8910
8911    @Override
8912    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8913        synchronized (this) {
8914            ProcessRecord app =
8915                who != null ? getRecordForAppLocked(who) : null;
8916            if (app == null) return;
8917
8918            Message msg = Message.obtain();
8919            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8920            msg.obj = app;
8921            msg.arg1 = waiting ? 1 : 0;
8922            mUiHandler.sendMessage(msg);
8923        }
8924    }
8925
8926    @Override
8927    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8928        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8929        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8930        outInfo.availMem = Process.getFreeMemory();
8931        outInfo.totalMem = Process.getTotalMemory();
8932        outInfo.threshold = homeAppMem;
8933        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8934        outInfo.hiddenAppThreshold = cachedAppMem;
8935        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8936                ProcessList.SERVICE_ADJ);
8937        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8938                ProcessList.VISIBLE_APP_ADJ);
8939        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8940                ProcessList.FOREGROUND_APP_ADJ);
8941    }
8942
8943    // =========================================================
8944    // TASK MANAGEMENT
8945    // =========================================================
8946
8947    @Override
8948    public List<IAppTask> getAppTasks(String callingPackage) {
8949        int callingUid = Binder.getCallingUid();
8950        long ident = Binder.clearCallingIdentity();
8951
8952        synchronized(this) {
8953            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8954            try {
8955                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8956
8957                final int N = mRecentTasks.size();
8958                for (int i = 0; i < N; i++) {
8959                    TaskRecord tr = mRecentTasks.get(i);
8960                    // Skip tasks that do not match the caller.  We don't need to verify
8961                    // callingPackage, because we are also limiting to callingUid and know
8962                    // that will limit to the correct security sandbox.
8963                    if (tr.effectiveUid != callingUid) {
8964                        continue;
8965                    }
8966                    Intent intent = tr.getBaseIntent();
8967                    if (intent == null ||
8968                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8969                        continue;
8970                    }
8971                    ActivityManager.RecentTaskInfo taskInfo =
8972                            createRecentTaskInfoFromTaskRecord(tr);
8973                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8974                    list.add(taskImpl);
8975                }
8976            } finally {
8977                Binder.restoreCallingIdentity(ident);
8978            }
8979            return list;
8980        }
8981    }
8982
8983    @Override
8984    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8985        final int callingUid = Binder.getCallingUid();
8986        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8987
8988        synchronized(this) {
8989            if (DEBUG_ALL) Slog.v(
8990                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8991
8992            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8993                    callingUid);
8994
8995            // TODO: Improve with MRU list from all ActivityStacks.
8996            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8997        }
8998
8999        return list;
9000    }
9001
9002    /**
9003     * Creates a new RecentTaskInfo from a TaskRecord.
9004     */
9005    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9006        // Update the task description to reflect any changes in the task stack
9007        tr.updateTaskDescription();
9008
9009        // Compose the recent task info
9010        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9011        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9012        rti.persistentId = tr.taskId;
9013        rti.baseIntent = new Intent(tr.getBaseIntent());
9014        rti.origActivity = tr.origActivity;
9015        rti.realActivity = tr.realActivity;
9016        rti.description = tr.lastDescription;
9017        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9018        rti.userId = tr.userId;
9019        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9020        rti.firstActiveTime = tr.firstActiveTime;
9021        rti.lastActiveTime = tr.lastActiveTime;
9022        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9023        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9024        rti.numActivities = 0;
9025        if (tr.mBounds != null) {
9026            rti.bounds = new Rect(tr.mBounds);
9027        }
9028        rti.isDockable = tr.canGoInDockedStack();
9029        rti.resizeMode = tr.mResizeMode;
9030
9031        ActivityRecord base = null;
9032        ActivityRecord top = null;
9033        ActivityRecord tmp;
9034
9035        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9036            tmp = tr.mActivities.get(i);
9037            if (tmp.finishing) {
9038                continue;
9039            }
9040            base = tmp;
9041            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9042                top = base;
9043            }
9044            rti.numActivities++;
9045        }
9046
9047        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9048        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9049
9050        return rti;
9051    }
9052
9053    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9054        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9055                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9056        if (!allowed) {
9057            if (checkPermission(android.Manifest.permission.GET_TASKS,
9058                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9059                // Temporary compatibility: some existing apps on the system image may
9060                // still be requesting the old permission and not switched to the new
9061                // one; if so, we'll still allow them full access.  This means we need
9062                // to see if they are holding the old permission and are a system app.
9063                try {
9064                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9065                        allowed = true;
9066                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9067                                + " is using old GET_TASKS but privileged; allowing");
9068                    }
9069                } catch (RemoteException e) {
9070                }
9071            }
9072        }
9073        if (!allowed) {
9074            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9075                    + " does not hold REAL_GET_TASKS; limiting output");
9076        }
9077        return allowed;
9078    }
9079
9080    @Override
9081    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9082        final int callingUid = Binder.getCallingUid();
9083        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9084                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9085
9086        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9087        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9088        synchronized (this) {
9089            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9090                    callingUid);
9091            final boolean detailed = checkCallingPermission(
9092                    android.Manifest.permission.GET_DETAILED_TASKS)
9093                    == PackageManager.PERMISSION_GRANTED;
9094
9095            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9096                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9097                return Collections.emptyList();
9098            }
9099            mRecentTasks.loadUserRecentsLocked(userId);
9100
9101            final int recentsCount = mRecentTasks.size();
9102            ArrayList<ActivityManager.RecentTaskInfo> res =
9103                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9104
9105            final Set<Integer> includedUsers;
9106            if (includeProfiles) {
9107                includedUsers = mUserController.getProfileIds(userId);
9108            } else {
9109                includedUsers = new HashSet<>();
9110            }
9111            includedUsers.add(Integer.valueOf(userId));
9112
9113            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9114                TaskRecord tr = mRecentTasks.get(i);
9115                // Only add calling user or related users recent tasks
9116                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9117                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9118                    continue;
9119                }
9120
9121                if (tr.realActivitySuspended) {
9122                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9123                    continue;
9124                }
9125
9126                // Return the entry if desired by the caller.  We always return
9127                // the first entry, because callers always expect this to be the
9128                // foreground app.  We may filter others if the caller has
9129                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9130                // we should exclude the entry.
9131
9132                if (i == 0
9133                        || withExcluded
9134                        || (tr.intent == null)
9135                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9136                                == 0)) {
9137                    if (!allowed) {
9138                        // If the caller doesn't have the GET_TASKS permission, then only
9139                        // allow them to see a small subset of tasks -- their own and home.
9140                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9141                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9142                            continue;
9143                        }
9144                    }
9145                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9146                        if (tr.stack != null && tr.stack.isHomeStack()) {
9147                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9148                                    "Skipping, home stack task: " + tr);
9149                            continue;
9150                        }
9151                    }
9152                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9153                        final ActivityStack stack = tr.stack;
9154                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9155                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9156                                    "Skipping, top task in docked stack: " + tr);
9157                            continue;
9158                        }
9159                    }
9160                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9161                        if (tr.stack != null && tr.stack.isPinnedStack()) {
9162                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9163                                    "Skipping, pinned stack task: " + tr);
9164                            continue;
9165                        }
9166                    }
9167                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9168                        // Don't include auto remove tasks that are finished or finishing.
9169                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9170                                "Skipping, auto-remove without activity: " + tr);
9171                        continue;
9172                    }
9173                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9174                            && !tr.isAvailable) {
9175                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9176                                "Skipping, unavail real act: " + tr);
9177                        continue;
9178                    }
9179
9180                    if (!tr.mUserSetupComplete) {
9181                        // Don't include task launched while user is not done setting-up.
9182                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9183                                "Skipping, user setup not complete: " + tr);
9184                        continue;
9185                    }
9186
9187                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9188                    if (!detailed) {
9189                        rti.baseIntent.replaceExtras((Bundle)null);
9190                    }
9191
9192                    res.add(rti);
9193                    maxNum--;
9194                }
9195            }
9196            return res;
9197        }
9198    }
9199
9200    @Override
9201    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9202        synchronized (this) {
9203            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9204                    "getTaskThumbnail()");
9205            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9206                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9207            if (tr != null) {
9208                return tr.getTaskThumbnailLocked();
9209            }
9210        }
9211        return null;
9212    }
9213
9214    @Override
9215    public int addAppTask(IBinder activityToken, Intent intent,
9216            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9217        final int callingUid = Binder.getCallingUid();
9218        final long callingIdent = Binder.clearCallingIdentity();
9219
9220        try {
9221            synchronized (this) {
9222                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9223                if (r == null) {
9224                    throw new IllegalArgumentException("Activity does not exist; token="
9225                            + activityToken);
9226                }
9227                ComponentName comp = intent.getComponent();
9228                if (comp == null) {
9229                    throw new IllegalArgumentException("Intent " + intent
9230                            + " must specify explicit component");
9231                }
9232                if (thumbnail.getWidth() != mThumbnailWidth
9233                        || thumbnail.getHeight() != mThumbnailHeight) {
9234                    throw new IllegalArgumentException("Bad thumbnail size: got "
9235                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9236                            + mThumbnailWidth + "x" + mThumbnailHeight);
9237                }
9238                if (intent.getSelector() != null) {
9239                    intent.setSelector(null);
9240                }
9241                if (intent.getSourceBounds() != null) {
9242                    intent.setSourceBounds(null);
9243                }
9244                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9245                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9246                        // The caller has added this as an auto-remove task...  that makes no
9247                        // sense, so turn off auto-remove.
9248                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9249                    }
9250                }
9251                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9252                    mLastAddedTaskActivity = null;
9253                }
9254                ActivityInfo ainfo = mLastAddedTaskActivity;
9255                if (ainfo == null) {
9256                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9257                            comp, 0, UserHandle.getUserId(callingUid));
9258                    if (ainfo.applicationInfo.uid != callingUid) {
9259                        throw new SecurityException(
9260                                "Can't add task for another application: target uid="
9261                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9262                    }
9263                }
9264
9265                // Use the full screen as the context for the task thumbnail
9266                final Point displaySize = new Point();
9267                final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9268                r.task.stack.getDisplaySize(displaySize);
9269                thumbnailInfo.taskWidth = displaySize.x;
9270                thumbnailInfo.taskHeight = displaySize.y;
9271                thumbnailInfo.screenOrientation = mConfiguration.orientation;
9272
9273                TaskRecord task = new TaskRecord(this,
9274                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9275                        ainfo, intent, description, thumbnailInfo);
9276
9277                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9278                if (trimIdx >= 0) {
9279                    // If this would have caused a trim, then we'll abort because that
9280                    // means it would be added at the end of the list but then just removed.
9281                    return INVALID_TASK_ID;
9282                }
9283
9284                final int N = mRecentTasks.size();
9285                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9286                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9287                    tr.removedFromRecents();
9288                }
9289
9290                task.inRecents = true;
9291                mRecentTasks.add(task);
9292                r.task.stack.addTask(task, false, "addAppTask");
9293
9294                task.setLastThumbnailLocked(thumbnail);
9295                task.freeLastThumbnail();
9296
9297                return task.taskId;
9298            }
9299        } finally {
9300            Binder.restoreCallingIdentity(callingIdent);
9301        }
9302    }
9303
9304    @Override
9305    public Point getAppTaskThumbnailSize() {
9306        synchronized (this) {
9307            return new Point(mThumbnailWidth,  mThumbnailHeight);
9308        }
9309    }
9310
9311    @Override
9312    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9313        synchronized (this) {
9314            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9315            if (r != null) {
9316                r.setTaskDescription(td);
9317                r.task.updateTaskDescription();
9318            }
9319        }
9320    }
9321
9322    @Override
9323    public void setTaskResizeable(int taskId, int resizeableMode) {
9324        synchronized (this) {
9325            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9326                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9327            if (task == null) {
9328                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9329                return;
9330            }
9331            if (task.mResizeMode != resizeableMode) {
9332                task.mResizeMode = resizeableMode;
9333                mWindowManager.setTaskResizeable(taskId, resizeableMode);
9334                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9335                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9336            }
9337        }
9338    }
9339
9340    @Override
9341    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9342        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9343        long ident = Binder.clearCallingIdentity();
9344        try {
9345            synchronized (this) {
9346                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9347                if (task == null) {
9348                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9349                    return;
9350                }
9351                int stackId = task.stack.mStackId;
9352                // We allow the task to scroll instead of resizing if this is a non-resizeable task
9353                // in crop windows resize mode or if the task size is affected by the docked stack
9354                // changing size. No need to update configuration.
9355                if (bounds != null && task.inCropWindowsResizeMode()
9356                        && mStackSupervisor.isStackDockedInEffect(stackId)) {
9357                    mWindowManager.scrollTask(task.taskId, bounds);
9358                    return;
9359                }
9360
9361                // Place the task in the right stack if it isn't there already based on
9362                // the requested bounds.
9363                // The stack transition logic is:
9364                // - a null bounds on a freeform task moves that task to fullscreen
9365                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9366                //   that task to freeform
9367                // - otherwise the task is not moved
9368                if (!StackId.isTaskResizeAllowed(stackId)) {
9369                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9370                }
9371                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9372                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9373                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9374                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9375                }
9376                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9377                if (stackId != task.stack.mStackId) {
9378                    mStackSupervisor.moveTaskToStackUncheckedLocked(
9379                            task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9380                    preserveWindow = false;
9381                }
9382
9383                mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9384                        false /* deferResume */);
9385            }
9386        } finally {
9387            Binder.restoreCallingIdentity(ident);
9388        }
9389    }
9390
9391    @Override
9392    public Rect getTaskBounds(int taskId) {
9393        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9394        long ident = Binder.clearCallingIdentity();
9395        Rect rect = new Rect();
9396        try {
9397            synchronized (this) {
9398                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9399                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9400                if (task == null) {
9401                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9402                    return rect;
9403                }
9404                if (task.stack != null) {
9405                    // Return the bounds from window manager since it will be adjusted for various
9406                    // things like the presense of a docked stack for tasks that aren't resizeable.
9407                    mWindowManager.getTaskBounds(task.taskId, rect);
9408                } else {
9409                    // Task isn't in window manager yet since it isn't associated with a stack.
9410                    // Return the persist value from activity manager
9411                    if (task.mBounds != null) {
9412                        rect.set(task.mBounds);
9413                    } else if (task.mLastNonFullscreenBounds != null) {
9414                        rect.set(task.mLastNonFullscreenBounds);
9415                    }
9416                }
9417            }
9418        } finally {
9419            Binder.restoreCallingIdentity(ident);
9420        }
9421        return rect;
9422    }
9423
9424    @Override
9425    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9426        if (userId != UserHandle.getCallingUserId()) {
9427            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9428                    "getTaskDescriptionIcon");
9429        }
9430        final File passedIconFile = new File(filePath);
9431        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9432                passedIconFile.getName());
9433        if (!legitIconFile.getPath().equals(filePath)
9434                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9435            throw new IllegalArgumentException("Bad file path: " + filePath
9436                    + " passed for userId " + userId);
9437        }
9438        return mRecentTasks.getTaskDescriptionIcon(filePath);
9439    }
9440
9441    @Override
9442    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9443            throws RemoteException {
9444        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9445                opts.getCustomInPlaceResId() == 0) {
9446            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9447                    "with valid animation");
9448        }
9449        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9450        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9451                opts.getCustomInPlaceResId());
9452        mWindowManager.executeAppTransition();
9453    }
9454
9455    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9456            boolean removeFromRecents) {
9457        if (removeFromRecents) {
9458            mRecentTasks.remove(tr);
9459            tr.removedFromRecents();
9460        }
9461        ComponentName component = tr.getBaseIntent().getComponent();
9462        if (component == null) {
9463            Slog.w(TAG, "No component for base intent of task: " + tr);
9464            return;
9465        }
9466
9467        // Find any running services associated with this app and stop if needed.
9468        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9469
9470        if (!killProcess) {
9471            return;
9472        }
9473
9474        // Determine if the process(es) for this task should be killed.
9475        final String pkg = component.getPackageName();
9476        ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9477        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9478        for (int i = 0; i < pmap.size(); i++) {
9479
9480            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9481            for (int j = 0; j < uids.size(); j++) {
9482                ProcessRecord proc = uids.valueAt(j);
9483                if (proc.userId != tr.userId) {
9484                    // Don't kill process for a different user.
9485                    continue;
9486                }
9487                if (proc == mHomeProcess) {
9488                    // Don't kill the home process along with tasks from the same package.
9489                    continue;
9490                }
9491                if (!proc.pkgList.containsKey(pkg)) {
9492                    // Don't kill process that is not associated with this task.
9493                    continue;
9494                }
9495
9496                for (int k = 0; k < proc.activities.size(); k++) {
9497                    TaskRecord otherTask = proc.activities.get(k).task;
9498                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9499                        // Don't kill process(es) that has an activity in a different task that is
9500                        // also in recents.
9501                        return;
9502                    }
9503                }
9504
9505                if (proc.foregroundServices) {
9506                    // Don't kill process(es) with foreground service.
9507                    return;
9508                }
9509
9510                // Add process to kill list.
9511                procsToKill.add(proc);
9512            }
9513        }
9514
9515        // Kill the running processes.
9516        for (int i = 0; i < procsToKill.size(); i++) {
9517            ProcessRecord pr = procsToKill.get(i);
9518            if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9519                    && pr.curReceiver == null) {
9520                pr.kill("remove task", true);
9521            } else {
9522                // We delay killing processes that are not in the background or running a receiver.
9523                pr.waitingToKill = "remove task";
9524            }
9525        }
9526    }
9527
9528    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9529        // Remove all tasks with activities in the specified package from the list of recent tasks
9530        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9531            TaskRecord tr = mRecentTasks.get(i);
9532            if (tr.userId != userId) continue;
9533
9534            ComponentName cn = tr.intent.getComponent();
9535            if (cn != null && cn.getPackageName().equals(packageName)) {
9536                // If the package name matches, remove the task.
9537                removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9538            }
9539        }
9540    }
9541
9542    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9543            int userId) {
9544
9545        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9546            TaskRecord tr = mRecentTasks.get(i);
9547            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9548                continue;
9549            }
9550
9551            ComponentName cn = tr.intent.getComponent();
9552            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9553                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9554            if (sameComponent) {
9555                removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9556            }
9557        }
9558    }
9559
9560    /**
9561     * Removes the task with the specified task id.
9562     *
9563     * @param taskId Identifier of the task to be removed.
9564     * @param killProcess Kill any process associated with the task if possible.
9565     * @param removeFromRecents Whether to also remove the task from recents.
9566     * @return Returns true if the given task was found and removed.
9567     */
9568    private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9569            boolean removeFromRecents) {
9570        final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9571                taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9572        if (tr != null) {
9573            tr.removeTaskActivitiesLocked();
9574            cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9575            if (tr.isPersistable) {
9576                notifyTaskPersisterLocked(null, true);
9577            }
9578            return true;
9579        }
9580        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9581        return false;
9582    }
9583
9584    @Override
9585    public void removeStack(int stackId) {
9586        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9587        if (stackId == HOME_STACK_ID) {
9588            throw new IllegalArgumentException("Removing home stack is not allowed.");
9589        }
9590
9591        synchronized (this) {
9592            final long ident = Binder.clearCallingIdentity();
9593            try {
9594                final ActivityStack stack = mStackSupervisor.getStack(stackId);
9595                if (stack == null) {
9596                    return;
9597                }
9598                final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9599                for (int i = tasks.size() - 1; i >= 0; i--) {
9600                    removeTaskByIdLocked(
9601                            tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9602                }
9603            } finally {
9604                Binder.restoreCallingIdentity(ident);
9605            }
9606        }
9607    }
9608
9609    @Override
9610    public boolean removeTask(int taskId) {
9611        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9612        synchronized (this) {
9613            final long ident = Binder.clearCallingIdentity();
9614            try {
9615                return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9616            } finally {
9617                Binder.restoreCallingIdentity(ident);
9618            }
9619        }
9620    }
9621
9622    /**
9623     * TODO: Add mController hook
9624     */
9625    @Override
9626    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9627        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9628
9629        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9630        synchronized(this) {
9631            moveTaskToFrontLocked(taskId, flags, bOptions);
9632        }
9633    }
9634
9635    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9636        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9637
9638        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9639                Binder.getCallingUid(), -1, -1, "Task to front")) {
9640            ActivityOptions.abort(options);
9641            return;
9642        }
9643        final long origId = Binder.clearCallingIdentity();
9644        try {
9645            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9646            if (task == null) {
9647                Slog.d(TAG, "Could not find task for id: "+ taskId);
9648                return;
9649            }
9650            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9651                mStackSupervisor.showLockTaskToast();
9652                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9653                return;
9654            }
9655            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9656            if (prev != null && prev.isRecentsActivity()) {
9657                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9658            }
9659            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9660                    false /* forceNonResizable */);
9661        } finally {
9662            Binder.restoreCallingIdentity(origId);
9663        }
9664        ActivityOptions.abort(options);
9665    }
9666
9667    /**
9668     * Moves an activity, and all of the other activities within the same task, to the bottom
9669     * of the history stack.  The activity's order within the task is unchanged.
9670     *
9671     * @param token A reference to the activity we wish to move
9672     * @param nonRoot If false then this only works if the activity is the root
9673     *                of a task; if true it will work for any activity in a task.
9674     * @return Returns true if the move completed, false if not.
9675     */
9676    @Override
9677    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9678        enforceNotIsolatedCaller("moveActivityTaskToBack");
9679        synchronized(this) {
9680            final long origId = Binder.clearCallingIdentity();
9681            try {
9682                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9683                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9684                if (task != null) {
9685                    if (mStackSupervisor.isLockedTask(task)) {
9686                        mStackSupervisor.showLockTaskToast();
9687                        return false;
9688                    }
9689                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9690                }
9691            } finally {
9692                Binder.restoreCallingIdentity(origId);
9693            }
9694        }
9695        return false;
9696    }
9697
9698    @Override
9699    public void moveTaskBackwards(int task) {
9700        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9701                "moveTaskBackwards()");
9702
9703        synchronized(this) {
9704            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9705                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9706                return;
9707            }
9708            final long origId = Binder.clearCallingIdentity();
9709            moveTaskBackwardsLocked(task);
9710            Binder.restoreCallingIdentity(origId);
9711        }
9712    }
9713
9714    private final void moveTaskBackwardsLocked(int task) {
9715        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9716    }
9717
9718    @Override
9719    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9720            IActivityContainerCallback callback) throws RemoteException {
9721        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9722        synchronized (this) {
9723            if (parentActivityToken == null) {
9724                throw new IllegalArgumentException("parent token must not be null");
9725            }
9726            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9727            if (r == null) {
9728                return null;
9729            }
9730            if (callback == null) {
9731                throw new IllegalArgumentException("callback must not be null");
9732            }
9733            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9734        }
9735    }
9736
9737    @Override
9738    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9739        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9740        synchronized (this) {
9741            mStackSupervisor.deleteActivityContainer(container);
9742        }
9743    }
9744
9745    @Override
9746    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9747        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9748        synchronized (this) {
9749            final int stackId = mStackSupervisor.getNextStackId();
9750            final ActivityStack stack =
9751                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9752            if (stack == null) {
9753                return null;
9754            }
9755            return stack.mActivityContainer;
9756        }
9757    }
9758
9759    @Override
9760    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9761        synchronized (this) {
9762            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9763            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9764                return stack.mActivityContainer.getDisplayId();
9765            }
9766            return Display.DEFAULT_DISPLAY;
9767        }
9768    }
9769
9770    @Override
9771    public int getActivityStackId(IBinder token) throws RemoteException {
9772        synchronized (this) {
9773            ActivityStack stack = ActivityRecord.getStackLocked(token);
9774            if (stack == null) {
9775                return INVALID_STACK_ID;
9776            }
9777            return stack.mStackId;
9778        }
9779    }
9780
9781    @Override
9782    public void exitFreeformMode(IBinder token) throws RemoteException {
9783        synchronized (this) {
9784            long ident = Binder.clearCallingIdentity();
9785            try {
9786                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9787                if (r == null) {
9788                    throw new IllegalArgumentException(
9789                            "exitFreeformMode: No activity record matching token=" + token);
9790                }
9791                final ActivityStack stack = r.getStackLocked(token);
9792                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9793                    throw new IllegalStateException(
9794                            "exitFreeformMode: You can only go fullscreen from freeform.");
9795                }
9796                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9797                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9798                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9799            } finally {
9800                Binder.restoreCallingIdentity(ident);
9801            }
9802        }
9803    }
9804
9805    @Override
9806    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9807        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9808        if (stackId == HOME_STACK_ID) {
9809            throw new IllegalArgumentException(
9810                    "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9811        }
9812        synchronized (this) {
9813            long ident = Binder.clearCallingIdentity();
9814            try {
9815                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9816                        + " to stackId=" + stackId + " toTop=" + toTop);
9817                if (stackId == DOCKED_STACK_ID) {
9818                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9819                            null /* initialBounds */);
9820                }
9821                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9822                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9823                if (result && stackId == DOCKED_STACK_ID) {
9824                    // If task moved to docked stack - show recents if needed.
9825                    mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9826                            "moveTaskToDockedStack");
9827                }
9828            } finally {
9829                Binder.restoreCallingIdentity(ident);
9830            }
9831        }
9832    }
9833
9834    @Override
9835    public void swapDockedAndFullscreenStack() throws RemoteException {
9836        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9837        synchronized (this) {
9838            long ident = Binder.clearCallingIdentity();
9839            try {
9840                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9841                        FULLSCREEN_WORKSPACE_STACK_ID);
9842                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9843                        : null;
9844                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9845                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9846                        : null;
9847                if (topTask == null || tasks == null || tasks.size() == 0) {
9848                    Slog.w(TAG,
9849                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
9850                    return;
9851                }
9852
9853                // TODO: App transition
9854                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9855
9856                // Defer the resume so resume/pausing while moving stacks is dangerous.
9857                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9858                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9859                        ANIMATE, true /* deferResume */);
9860                final int size = tasks.size();
9861                for (int i = 0; i < size; i++) {
9862                    final int id = tasks.get(i).taskId;
9863                    if (id == topTask.taskId) {
9864                        continue;
9865                    }
9866                    mStackSupervisor.moveTaskToStackLocked(id,
9867                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9868                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9869                }
9870
9871                // Because we deferred the resume, to avoid conflicts with stack switches while
9872                // resuming, we need to do it after all the tasks are moved.
9873                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9874                mStackSupervisor.resumeFocusedStackTopActivityLocked();
9875
9876                mWindowManager.executeAppTransition();
9877            } finally {
9878                Binder.restoreCallingIdentity(ident);
9879            }
9880        }
9881    }
9882
9883    /**
9884     * Moves the input task to the docked stack.
9885     *
9886     * @param taskId Id of task to move.
9887     * @param createMode The mode the docked stack should be created in if it doesn't exist
9888     *                   already. See
9889     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9890     *                   and
9891     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9892     * @param toTop If the task and stack should be moved to the top.
9893     * @param animate Whether we should play an animation for the moving the task
9894     * @param initialBounds If the docked stack gets created, it will use these bounds for the
9895     *                      docked stack. Pass {@code null} to use default bounds.
9896     */
9897    @Override
9898    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9899            Rect initialBounds, boolean moveHomeStackFront) {
9900        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9901        synchronized (this) {
9902            long ident = Binder.clearCallingIdentity();
9903            try {
9904                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9905                        + " to createMode=" + createMode + " toTop=" + toTop);
9906                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9907                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9908                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9909                        animate, DEFER_RESUME);
9910                if (moved) {
9911                    if (moveHomeStackFront) {
9912                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9913                    }
9914                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9915                }
9916                return moved;
9917            } finally {
9918                Binder.restoreCallingIdentity(ident);
9919            }
9920        }
9921    }
9922
9923    /**
9924     * Moves the top activity in the input stackId to the pinned stack.
9925     *
9926     * @param stackId Id of stack to move the top activity to pinned stack.
9927     * @param bounds Bounds to use for pinned stack.
9928     *
9929     * @return True if the top activity of the input stack was successfully moved to the pinned
9930     *          stack.
9931     */
9932    @Override
9933    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9934        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9935        synchronized (this) {
9936            if (!mSupportsPictureInPicture) {
9937                throw new IllegalStateException("moveTopActivityToPinnedStack:"
9938                        + "Device doesn't support picture-in-pciture mode");
9939            }
9940
9941            long ident = Binder.clearCallingIdentity();
9942            try {
9943                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9944            } finally {
9945                Binder.restoreCallingIdentity(ident);
9946            }
9947        }
9948    }
9949
9950    @Override
9951    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9952            boolean preserveWindows, boolean animate, int animationDuration) {
9953        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9954        long ident = Binder.clearCallingIdentity();
9955        try {
9956            synchronized (this) {
9957                if (animate) {
9958                    if (stackId == PINNED_STACK_ID) {
9959                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9960                    } else {
9961                        throw new IllegalArgumentException("Stack: " + stackId
9962                                + " doesn't support animated resize.");
9963                    }
9964                } else {
9965                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9966                            null /* tempTaskInsetBounds */, preserveWindows,
9967                            allowResizeInDockedMode, !DEFER_RESUME);
9968                }
9969            }
9970        } finally {
9971            Binder.restoreCallingIdentity(ident);
9972        }
9973    }
9974
9975    @Override
9976    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9977            Rect tempDockedTaskInsetBounds,
9978            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9979        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9980                "resizeDockedStack()");
9981        long ident = Binder.clearCallingIdentity();
9982        try {
9983            synchronized (this) {
9984                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9985                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9986                        PRESERVE_WINDOWS);
9987            }
9988        } finally {
9989            Binder.restoreCallingIdentity(ident);
9990        }
9991    }
9992
9993    @Override
9994    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9995        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9996                "resizePinnedStack()");
9997        final long ident = Binder.clearCallingIdentity();
9998        try {
9999            synchronized (this) {
10000                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10001            }
10002        } finally {
10003            Binder.restoreCallingIdentity(ident);
10004        }
10005    }
10006
10007    @Override
10008    public void positionTaskInStack(int taskId, int stackId, int position) {
10009        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10010        if (stackId == HOME_STACK_ID) {
10011            throw new IllegalArgumentException(
10012                    "positionTaskInStack: Attempt to change the position of task "
10013                    + taskId + " in/to home stack");
10014        }
10015        synchronized (this) {
10016            long ident = Binder.clearCallingIdentity();
10017            try {
10018                if (DEBUG_STACK) Slog.d(TAG_STACK,
10019                        "positionTaskInStack: positioning task=" + taskId
10020                        + " in stackId=" + stackId + " at position=" + position);
10021                mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10022            } finally {
10023                Binder.restoreCallingIdentity(ident);
10024            }
10025        }
10026    }
10027
10028    @Override
10029    public List<StackInfo> getAllStackInfos() {
10030        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10031        long ident = Binder.clearCallingIdentity();
10032        try {
10033            synchronized (this) {
10034                return mStackSupervisor.getAllStackInfosLocked();
10035            }
10036        } finally {
10037            Binder.restoreCallingIdentity(ident);
10038        }
10039    }
10040
10041    @Override
10042    public StackInfo getStackInfo(int stackId) {
10043        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10044        long ident = Binder.clearCallingIdentity();
10045        try {
10046            synchronized (this) {
10047                return mStackSupervisor.getStackInfoLocked(stackId);
10048            }
10049        } finally {
10050            Binder.restoreCallingIdentity(ident);
10051        }
10052    }
10053
10054    @Override
10055    public boolean isInHomeStack(int taskId) {
10056        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10057        long ident = Binder.clearCallingIdentity();
10058        try {
10059            synchronized (this) {
10060                final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10061                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10062                return tr != null && tr.stack != null && tr.stack.isHomeStack();
10063            }
10064        } finally {
10065            Binder.restoreCallingIdentity(ident);
10066        }
10067    }
10068
10069    @Override
10070    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10071        synchronized(this) {
10072            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10073        }
10074    }
10075
10076    @Override
10077    public void updateDeviceOwner(String packageName) {
10078        final int callingUid = Binder.getCallingUid();
10079        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10080            throw new SecurityException("updateDeviceOwner called from non-system process");
10081        }
10082        synchronized (this) {
10083            mDeviceOwnerName = packageName;
10084        }
10085    }
10086
10087    @Override
10088    public void updateLockTaskPackages(int userId, String[] packages) {
10089        final int callingUid = Binder.getCallingUid();
10090        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10091            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10092                    "updateLockTaskPackages()");
10093        }
10094        synchronized (this) {
10095            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10096                    Arrays.toString(packages));
10097            mLockTaskPackages.put(userId, packages);
10098            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10099        }
10100    }
10101
10102
10103    void startLockTaskModeLocked(TaskRecord task) {
10104        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10105        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10106            return;
10107        }
10108
10109        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10110        // is initiated by system after the pinning request was shown and locked mode is initiated
10111        // by an authorized app directly
10112        final int callingUid = Binder.getCallingUid();
10113        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10114        long ident = Binder.clearCallingIdentity();
10115        try {
10116            if (!isSystemInitiated) {
10117                task.mLockTaskUid = callingUid;
10118                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10119                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10120                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10121                    StatusBarManagerInternal statusBarManager =
10122                            LocalServices.getService(StatusBarManagerInternal.class);
10123                    if (statusBarManager != null) {
10124                        statusBarManager.showScreenPinningRequest(task.taskId);
10125                    }
10126                    return;
10127                }
10128
10129                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10130                if (stack == null || task != stack.topTask()) {
10131                    throw new IllegalArgumentException("Invalid task, not in foreground");
10132                }
10133            }
10134            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10135                    "Locking fully");
10136            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10137                    ActivityManager.LOCK_TASK_MODE_PINNED :
10138                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10139                    "startLockTask", true);
10140        } finally {
10141            Binder.restoreCallingIdentity(ident);
10142        }
10143    }
10144
10145    @Override
10146    public void startLockTaskMode(int taskId) {
10147        synchronized (this) {
10148            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10149            if (task != null) {
10150                startLockTaskModeLocked(task);
10151            }
10152        }
10153    }
10154
10155    @Override
10156    public void startLockTaskMode(IBinder token) {
10157        synchronized (this) {
10158            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10159            if (r == null) {
10160                return;
10161            }
10162            final TaskRecord task = r.task;
10163            if (task != null) {
10164                startLockTaskModeLocked(task);
10165            }
10166        }
10167    }
10168
10169    @Override
10170    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10171        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10172        // This makes inner call to look as if it was initiated by system.
10173        long ident = Binder.clearCallingIdentity();
10174        try {
10175            synchronized (this) {
10176                startLockTaskMode(taskId);
10177            }
10178        } finally {
10179            Binder.restoreCallingIdentity(ident);
10180        }
10181    }
10182
10183    @Override
10184    public void stopLockTaskMode() {
10185        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10186        if (lockTask == null) {
10187            // Our work here is done.
10188            return;
10189        }
10190
10191        final int callingUid = Binder.getCallingUid();
10192        final int lockTaskUid = lockTask.mLockTaskUid;
10193        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10194        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10195            // Done.
10196            return;
10197        } else {
10198            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10199            // It is possible lockTaskMode was started by the system process because
10200            // android:lockTaskMode is set to a locking value in the application manifest
10201            // instead of the app calling startLockTaskMode. In this case
10202            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10203            // {@link TaskRecord.effectiveUid} instead. Also caller with
10204            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10205            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10206                    && callingUid != lockTaskUid
10207                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10208                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10209                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10210            }
10211        }
10212        long ident = Binder.clearCallingIdentity();
10213        try {
10214            Log.d(TAG, "stopLockTaskMode");
10215            // Stop lock task
10216            synchronized (this) {
10217                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10218                        "stopLockTask", true);
10219            }
10220            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10221            if (tm != null) {
10222                tm.showInCallScreen(false);
10223            }
10224        } finally {
10225            Binder.restoreCallingIdentity(ident);
10226        }
10227    }
10228
10229    /**
10230     * This API should be called by SystemUI only when user perform certain action to dismiss
10231     * lock task mode. We should only dismiss pinned lock task mode in this case.
10232     */
10233    @Override
10234    public void stopSystemLockTaskMode() throws RemoteException {
10235        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10236            stopLockTaskMode();
10237        } else {
10238            mStackSupervisor.showLockTaskToast();
10239        }
10240    }
10241
10242    @Override
10243    public boolean isInLockTaskMode() {
10244        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10245    }
10246
10247    @Override
10248    public int getLockTaskModeState() {
10249        synchronized (this) {
10250            return mStackSupervisor.getLockTaskModeState();
10251        }
10252    }
10253
10254    @Override
10255    public void showLockTaskEscapeMessage(IBinder token) {
10256        synchronized (this) {
10257            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10258            if (r == null) {
10259                return;
10260            }
10261            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10262        }
10263    }
10264
10265    // =========================================================
10266    // CONTENT PROVIDERS
10267    // =========================================================
10268
10269    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10270        List<ProviderInfo> providers = null;
10271        try {
10272            providers = AppGlobals.getPackageManager()
10273                    .queryContentProviders(app.processName, app.uid,
10274                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10275                                    | MATCH_DEBUG_TRIAGED_MISSING)
10276                    .getList();
10277        } catch (RemoteException ex) {
10278        }
10279        if (DEBUG_MU) Slog.v(TAG_MU,
10280                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10281        int userId = app.userId;
10282        if (providers != null) {
10283            int N = providers.size();
10284            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10285            for (int i=0; i<N; i++) {
10286                // TODO: keep logic in sync with installEncryptionUnawareProviders
10287                ProviderInfo cpi =
10288                    (ProviderInfo)providers.get(i);
10289                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10290                        cpi.name, cpi.flags);
10291                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10292                    // This is a singleton provider, but a user besides the
10293                    // default user is asking to initialize a process it runs
10294                    // in...  well, no, it doesn't actually run in this process,
10295                    // it runs in the process of the default user.  Get rid of it.
10296                    providers.remove(i);
10297                    N--;
10298                    i--;
10299                    continue;
10300                }
10301
10302                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10303                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10304                if (cpr == null) {
10305                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10306                    mProviderMap.putProviderByClass(comp, cpr);
10307                }
10308                if (DEBUG_MU) Slog.v(TAG_MU,
10309                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10310                app.pubProviders.put(cpi.name, cpr);
10311                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10312                    // Don't add this if it is a platform component that is marked
10313                    // to run in multiple processes, because this is actually
10314                    // part of the framework so doesn't make sense to track as a
10315                    // separate apk in the process.
10316                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10317                            mProcessStats);
10318                }
10319                notifyPackageUse(cpi.applicationInfo.packageName,
10320                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10321            }
10322        }
10323        return providers;
10324    }
10325
10326    /**
10327     * Check if {@link ProcessRecord} has a possible chance at accessing the
10328     * given {@link ProviderInfo}. Final permission checking is always done
10329     * in {@link ContentProvider}.
10330     */
10331    private final String checkContentProviderPermissionLocked(
10332            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10333        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10334        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10335        boolean checkedGrants = false;
10336        if (checkUser) {
10337            // Looking for cross-user grants before enforcing the typical cross-users permissions
10338            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10339            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10340                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10341                    return null;
10342                }
10343                checkedGrants = true;
10344            }
10345            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10346                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10347            if (userId != tmpTargetUserId) {
10348                // When we actually went to determine the final targer user ID, this ended
10349                // up different than our initial check for the authority.  This is because
10350                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10351                // SELF.  So we need to re-check the grants again.
10352                checkedGrants = false;
10353            }
10354        }
10355        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10356                cpi.applicationInfo.uid, cpi.exported)
10357                == PackageManager.PERMISSION_GRANTED) {
10358            return null;
10359        }
10360        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10361                cpi.applicationInfo.uid, cpi.exported)
10362                == PackageManager.PERMISSION_GRANTED) {
10363            return null;
10364        }
10365
10366        PathPermission[] pps = cpi.pathPermissions;
10367        if (pps != null) {
10368            int i = pps.length;
10369            while (i > 0) {
10370                i--;
10371                PathPermission pp = pps[i];
10372                String pprperm = pp.getReadPermission();
10373                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10374                        cpi.applicationInfo.uid, cpi.exported)
10375                        == PackageManager.PERMISSION_GRANTED) {
10376                    return null;
10377                }
10378                String ppwperm = pp.getWritePermission();
10379                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10380                        cpi.applicationInfo.uid, cpi.exported)
10381                        == PackageManager.PERMISSION_GRANTED) {
10382                    return null;
10383                }
10384            }
10385        }
10386        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10387            return null;
10388        }
10389
10390        String msg;
10391        if (!cpi.exported) {
10392            msg = "Permission Denial: opening provider " + cpi.name
10393                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10394                    + ", uid=" + callingUid + ") that is not exported from uid "
10395                    + cpi.applicationInfo.uid;
10396        } else {
10397            msg = "Permission Denial: opening provider " + cpi.name
10398                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10399                    + ", uid=" + callingUid + ") requires "
10400                    + cpi.readPermission + " or " + cpi.writePermission;
10401        }
10402        Slog.w(TAG, msg);
10403        return msg;
10404    }
10405
10406    /**
10407     * Returns if the ContentProvider has granted a uri to callingUid
10408     */
10409    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10410        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10411        if (perms != null) {
10412            for (int i=perms.size()-1; i>=0; i--) {
10413                GrantUri grantUri = perms.keyAt(i);
10414                if (grantUri.sourceUserId == userId || !checkUser) {
10415                    if (matchesProvider(grantUri.uri, cpi)) {
10416                        return true;
10417                    }
10418                }
10419            }
10420        }
10421        return false;
10422    }
10423
10424    /**
10425     * Returns true if the uri authority is one of the authorities specified in the provider.
10426     */
10427    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10428        String uriAuth = uri.getAuthority();
10429        String cpiAuth = cpi.authority;
10430        if (cpiAuth.indexOf(';') == -1) {
10431            return cpiAuth.equals(uriAuth);
10432        }
10433        String[] cpiAuths = cpiAuth.split(";");
10434        int length = cpiAuths.length;
10435        for (int i = 0; i < length; i++) {
10436            if (cpiAuths[i].equals(uriAuth)) return true;
10437        }
10438        return false;
10439    }
10440
10441    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10442            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10443        if (r != null) {
10444            for (int i=0; i<r.conProviders.size(); i++) {
10445                ContentProviderConnection conn = r.conProviders.get(i);
10446                if (conn.provider == cpr) {
10447                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10448                            "Adding provider requested by "
10449                            + r.processName + " from process "
10450                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10451                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10452                    if (stable) {
10453                        conn.stableCount++;
10454                        conn.numStableIncs++;
10455                    } else {
10456                        conn.unstableCount++;
10457                        conn.numUnstableIncs++;
10458                    }
10459                    return conn;
10460                }
10461            }
10462            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10463            if (stable) {
10464                conn.stableCount = 1;
10465                conn.numStableIncs = 1;
10466            } else {
10467                conn.unstableCount = 1;
10468                conn.numUnstableIncs = 1;
10469            }
10470            cpr.connections.add(conn);
10471            r.conProviders.add(conn);
10472            startAssociationLocked(r.uid, r.processName, r.curProcState,
10473                    cpr.uid, cpr.name, cpr.info.processName);
10474            return conn;
10475        }
10476        cpr.addExternalProcessHandleLocked(externalProcessToken);
10477        return null;
10478    }
10479
10480    boolean decProviderCountLocked(ContentProviderConnection conn,
10481            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10482        if (conn != null) {
10483            cpr = conn.provider;
10484            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10485                    "Removing provider requested by "
10486                    + conn.client.processName + " from process "
10487                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10488                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10489            if (stable) {
10490                conn.stableCount--;
10491            } else {
10492                conn.unstableCount--;
10493            }
10494            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10495                cpr.connections.remove(conn);
10496                conn.client.conProviders.remove(conn);
10497                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10498                    // The client is more important than last activity -- note the time this
10499                    // is happening, so we keep the old provider process around a bit as last
10500                    // activity to avoid thrashing it.
10501                    if (cpr.proc != null) {
10502                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10503                    }
10504                }
10505                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10506                return true;
10507            }
10508            return false;
10509        }
10510        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10511        return false;
10512    }
10513
10514    private void checkTime(long startTime, String where) {
10515        long now = SystemClock.uptimeMillis();
10516        if ((now-startTime) > 50) {
10517            // If we are taking more than 50ms, log about it.
10518            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10519        }
10520    }
10521
10522    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10523            PROC_SPACE_TERM,
10524            PROC_SPACE_TERM|PROC_PARENS,
10525            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10526    };
10527
10528    private final long[] mProcessStateStatsLongs = new long[1];
10529
10530    boolean isProcessAliveLocked(ProcessRecord proc) {
10531        if (proc.procStatFile == null) {
10532            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10533        }
10534        mProcessStateStatsLongs[0] = 0;
10535        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10536                mProcessStateStatsLongs, null)) {
10537            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10538            return false;
10539        }
10540        final long state = mProcessStateStatsLongs[0];
10541        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10542                + (char)state);
10543        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10544    }
10545
10546    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10547            String name, IBinder token, boolean stable, int userId) {
10548        ContentProviderRecord cpr;
10549        ContentProviderConnection conn = null;
10550        ProviderInfo cpi = null;
10551
10552        synchronized(this) {
10553            long startTime = SystemClock.uptimeMillis();
10554
10555            ProcessRecord r = null;
10556            if (caller != null) {
10557                r = getRecordForAppLocked(caller);
10558                if (r == null) {
10559                    throw new SecurityException(
10560                            "Unable to find app for caller " + caller
10561                          + " (pid=" + Binder.getCallingPid()
10562                          + ") when getting content provider " + name);
10563                }
10564            }
10565
10566            boolean checkCrossUser = true;
10567
10568            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10569
10570            // First check if this content provider has been published...
10571            cpr = mProviderMap.getProviderByName(name, userId);
10572            // If that didn't work, check if it exists for user 0 and then
10573            // verify that it's a singleton provider before using it.
10574            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10575                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10576                if (cpr != null) {
10577                    cpi = cpr.info;
10578                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10579                            cpi.name, cpi.flags)
10580                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10581                        userId = UserHandle.USER_SYSTEM;
10582                        checkCrossUser = false;
10583                    } else {
10584                        cpr = null;
10585                        cpi = null;
10586                    }
10587                }
10588            }
10589
10590            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10591            if (providerRunning) {
10592                cpi = cpr.info;
10593                String msg;
10594                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10595                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10596                        != null) {
10597                    throw new SecurityException(msg);
10598                }
10599                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10600
10601                if (r != null && cpr.canRunHere(r)) {
10602                    // This provider has been published or is in the process
10603                    // of being published...  but it is also allowed to run
10604                    // in the caller's process, so don't make a connection
10605                    // and just let the caller instantiate its own instance.
10606                    ContentProviderHolder holder = cpr.newHolder(null);
10607                    // don't give caller the provider object, it needs
10608                    // to make its own.
10609                    holder.provider = null;
10610                    return holder;
10611                }
10612
10613                final long origId = Binder.clearCallingIdentity();
10614
10615                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10616
10617                // In this case the provider instance already exists, so we can
10618                // return it right away.
10619                conn = incProviderCountLocked(r, cpr, token, stable);
10620                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10621                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10622                        // If this is a perceptible app accessing the provider,
10623                        // make sure to count it as being accessed and thus
10624                        // back up on the LRU list.  This is good because
10625                        // content providers are often expensive to start.
10626                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10627                        updateLruProcessLocked(cpr.proc, false, null);
10628                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10629                    }
10630                }
10631
10632                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10633                final int verifiedAdj = cpr.proc.verifiedAdj;
10634                boolean success = updateOomAdjLocked(cpr.proc);
10635                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10636                // if the process has been successfully adjusted.  So to reduce races with
10637                // it, we will check whether the process still exists.  Note that this doesn't
10638                // completely get rid of races with LMK killing the process, but should make
10639                // them much smaller.
10640                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10641                    success = false;
10642                }
10643                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10644                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10645                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10646                // NOTE: there is still a race here where a signal could be
10647                // pending on the process even though we managed to update its
10648                // adj level.  Not sure what to do about this, but at least
10649                // the race is now smaller.
10650                if (!success) {
10651                    // Uh oh...  it looks like the provider's process
10652                    // has been killed on us.  We need to wait for a new
10653                    // process to be started, and make sure its death
10654                    // doesn't kill our process.
10655                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10656                            + " is crashing; detaching " + r);
10657                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10658                    checkTime(startTime, "getContentProviderImpl: before appDied");
10659                    appDiedLocked(cpr.proc);
10660                    checkTime(startTime, "getContentProviderImpl: after appDied");
10661                    if (!lastRef) {
10662                        // This wasn't the last ref our process had on
10663                        // the provider...  we have now been killed, bail.
10664                        return null;
10665                    }
10666                    providerRunning = false;
10667                    conn = null;
10668                } else {
10669                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10670                }
10671
10672                Binder.restoreCallingIdentity(origId);
10673            }
10674
10675            if (!providerRunning) {
10676                try {
10677                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10678                    cpi = AppGlobals.getPackageManager().
10679                        resolveContentProvider(name,
10680                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10681                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10682                } catch (RemoteException ex) {
10683                }
10684                if (cpi == null) {
10685                    return null;
10686                }
10687                // If the provider is a singleton AND
10688                // (it's a call within the same user || the provider is a
10689                // privileged app)
10690                // Then allow connecting to the singleton provider
10691                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10692                        cpi.name, cpi.flags)
10693                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10694                if (singleton) {
10695                    userId = UserHandle.USER_SYSTEM;
10696                }
10697                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10698                checkTime(startTime, "getContentProviderImpl: got app info for user");
10699
10700                String msg;
10701                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10702                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10703                        != null) {
10704                    throw new SecurityException(msg);
10705                }
10706                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10707
10708                if (!mProcessesReady
10709                        && !cpi.processName.equals("system")) {
10710                    // If this content provider does not run in the system
10711                    // process, and the system is not yet ready to run other
10712                    // processes, then fail fast instead of hanging.
10713                    throw new IllegalArgumentException(
10714                            "Attempt to launch content provider before system ready");
10715                }
10716
10717                // Make sure that the user who owns this provider is running.  If not,
10718                // we don't want to allow it to run.
10719                if (!mUserController.isUserRunningLocked(userId, 0)) {
10720                    Slog.w(TAG, "Unable to launch app "
10721                            + cpi.applicationInfo.packageName + "/"
10722                            + cpi.applicationInfo.uid + " for provider "
10723                            + name + ": user " + userId + " is stopped");
10724                    return null;
10725                }
10726
10727                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10728                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10729                cpr = mProviderMap.getProviderByClass(comp, userId);
10730                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10731                final boolean firstClass = cpr == null;
10732                if (firstClass) {
10733                    final long ident = Binder.clearCallingIdentity();
10734
10735                    // If permissions need a review before any of the app components can run,
10736                    // we return no provider and launch a review activity if the calling app
10737                    // is in the foreground.
10738                    if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10739                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10740                            return null;
10741                        }
10742                    }
10743
10744                    try {
10745                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10746                        ApplicationInfo ai =
10747                            AppGlobals.getPackageManager().
10748                                getApplicationInfo(
10749                                        cpi.applicationInfo.packageName,
10750                                        STOCK_PM_FLAGS, userId);
10751                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10752                        if (ai == null) {
10753                            Slog.w(TAG, "No package info for content provider "
10754                                    + cpi.name);
10755                            return null;
10756                        }
10757                        ai = getAppInfoForUser(ai, userId);
10758                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10759                    } catch (RemoteException ex) {
10760                        // pm is in same process, this will never happen.
10761                    } finally {
10762                        Binder.restoreCallingIdentity(ident);
10763                    }
10764                }
10765
10766                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10767
10768                if (r != null && cpr.canRunHere(r)) {
10769                    // If this is a multiprocess provider, then just return its
10770                    // info and allow the caller to instantiate it.  Only do
10771                    // this if the provider is the same user as the caller's
10772                    // process, or can run as root (so can be in any process).
10773                    return cpr.newHolder(null);
10774                }
10775
10776                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10777                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10778                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10779
10780                // This is single process, and our app is now connecting to it.
10781                // See if we are already in the process of launching this
10782                // provider.
10783                final int N = mLaunchingProviders.size();
10784                int i;
10785                for (i = 0; i < N; i++) {
10786                    if (mLaunchingProviders.get(i) == cpr) {
10787                        break;
10788                    }
10789                }
10790
10791                // If the provider is not already being launched, then get it
10792                // started.
10793                if (i >= N) {
10794                    final long origId = Binder.clearCallingIdentity();
10795
10796                    try {
10797                        // Content provider is now in use, its package can't be stopped.
10798                        try {
10799                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
10800                            AppGlobals.getPackageManager().setPackageStoppedState(
10801                                    cpr.appInfo.packageName, false, userId);
10802                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
10803                        } catch (RemoteException e) {
10804                        } catch (IllegalArgumentException e) {
10805                            Slog.w(TAG, "Failed trying to unstop package "
10806                                    + cpr.appInfo.packageName + ": " + e);
10807                        }
10808
10809                        // Use existing process if already started
10810                        checkTime(startTime, "getContentProviderImpl: looking for process record");
10811                        ProcessRecord proc = getProcessRecordLocked(
10812                                cpi.processName, cpr.appInfo.uid, false);
10813                        if (proc != null && proc.thread != null && !proc.killed) {
10814                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10815                                    "Installing in existing process " + proc);
10816                            if (!proc.pubProviders.containsKey(cpi.name)) {
10817                                checkTime(startTime, "getContentProviderImpl: scheduling install");
10818                                proc.pubProviders.put(cpi.name, cpr);
10819                                try {
10820                                    proc.thread.scheduleInstallProvider(cpi);
10821                                } catch (RemoteException e) {
10822                                }
10823                            }
10824                        } else {
10825                            checkTime(startTime, "getContentProviderImpl: before start process");
10826                            proc = startProcessLocked(cpi.processName,
10827                                    cpr.appInfo, false, 0, "content provider",
10828                                    new ComponentName(cpi.applicationInfo.packageName,
10829                                            cpi.name), false, false, false);
10830                            checkTime(startTime, "getContentProviderImpl: after start process");
10831                            if (proc == null) {
10832                                Slog.w(TAG, "Unable to launch app "
10833                                        + cpi.applicationInfo.packageName + "/"
10834                                        + cpi.applicationInfo.uid + " for provider "
10835                                        + name + ": process is bad");
10836                                return null;
10837                            }
10838                        }
10839                        cpr.launchingApp = proc;
10840                        mLaunchingProviders.add(cpr);
10841                    } finally {
10842                        Binder.restoreCallingIdentity(origId);
10843                    }
10844                }
10845
10846                checkTime(startTime, "getContentProviderImpl: updating data structures");
10847
10848                // Make sure the provider is published (the same provider class
10849                // may be published under multiple names).
10850                if (firstClass) {
10851                    mProviderMap.putProviderByClass(comp, cpr);
10852                }
10853
10854                mProviderMap.putProviderByName(name, cpr);
10855                conn = incProviderCountLocked(r, cpr, token, stable);
10856                if (conn != null) {
10857                    conn.waiting = true;
10858                }
10859            }
10860            checkTime(startTime, "getContentProviderImpl: done!");
10861        }
10862
10863        // Wait for the provider to be published...
10864        synchronized (cpr) {
10865            while (cpr.provider == null) {
10866                if (cpr.launchingApp == null) {
10867                    Slog.w(TAG, "Unable to launch app "
10868                            + cpi.applicationInfo.packageName + "/"
10869                            + cpi.applicationInfo.uid + " for provider "
10870                            + name + ": launching app became null");
10871                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10872                            UserHandle.getUserId(cpi.applicationInfo.uid),
10873                            cpi.applicationInfo.packageName,
10874                            cpi.applicationInfo.uid, name);
10875                    return null;
10876                }
10877                try {
10878                    if (DEBUG_MU) Slog.v(TAG_MU,
10879                            "Waiting to start provider " + cpr
10880                            + " launchingApp=" + cpr.launchingApp);
10881                    if (conn != null) {
10882                        conn.waiting = true;
10883                    }
10884                    cpr.wait();
10885                } catch (InterruptedException ex) {
10886                } finally {
10887                    if (conn != null) {
10888                        conn.waiting = false;
10889                    }
10890                }
10891            }
10892        }
10893        return cpr != null ? cpr.newHolder(conn) : null;
10894    }
10895
10896    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10897            ProcessRecord r, final int userId) {
10898        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10899                cpi.packageName, userId)) {
10900
10901            final boolean callerForeground = r == null || r.setSchedGroup
10902                    != ProcessList.SCHED_GROUP_BACKGROUND;
10903
10904            // Show a permission review UI only for starting from a foreground app
10905            if (!callerForeground) {
10906                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10907                        + cpi.packageName + " requires a permissions review");
10908                return false;
10909            }
10910
10911            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10912            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10913                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10914            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10915
10916            if (DEBUG_PERMISSIONS_REVIEW) {
10917                Slog.i(TAG, "u" + userId + " Launching permission review "
10918                        + "for package " + cpi.packageName);
10919            }
10920
10921            final UserHandle userHandle = new UserHandle(userId);
10922            mHandler.post(new Runnable() {
10923                @Override
10924                public void run() {
10925                    mContext.startActivityAsUser(intent, userHandle);
10926                }
10927            });
10928
10929            return false;
10930        }
10931
10932        return true;
10933    }
10934
10935    PackageManagerInternal getPackageManagerInternalLocked() {
10936        if (mPackageManagerInt == null) {
10937            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10938        }
10939        return mPackageManagerInt;
10940    }
10941
10942    @Override
10943    public final ContentProviderHolder getContentProvider(
10944            IApplicationThread caller, String name, int userId, boolean stable) {
10945        enforceNotIsolatedCaller("getContentProvider");
10946        if (caller == null) {
10947            String msg = "null IApplicationThread when getting content provider "
10948                    + name;
10949            Slog.w(TAG, msg);
10950            throw new SecurityException(msg);
10951        }
10952        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10953        // with cross-user grant.
10954        return getContentProviderImpl(caller, name, null, stable, userId);
10955    }
10956
10957    public ContentProviderHolder getContentProviderExternal(
10958            String name, int userId, IBinder token) {
10959        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10960            "Do not have permission in call getContentProviderExternal()");
10961        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10962                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10963        return getContentProviderExternalUnchecked(name, token, userId);
10964    }
10965
10966    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10967            IBinder token, int userId) {
10968        return getContentProviderImpl(null, name, token, true, userId);
10969    }
10970
10971    /**
10972     * Drop a content provider from a ProcessRecord's bookkeeping
10973     */
10974    public void removeContentProvider(IBinder connection, boolean stable) {
10975        enforceNotIsolatedCaller("removeContentProvider");
10976        long ident = Binder.clearCallingIdentity();
10977        try {
10978            synchronized (this) {
10979                ContentProviderConnection conn;
10980                try {
10981                    conn = (ContentProviderConnection)connection;
10982                } catch (ClassCastException e) {
10983                    String msg ="removeContentProvider: " + connection
10984                            + " not a ContentProviderConnection";
10985                    Slog.w(TAG, msg);
10986                    throw new IllegalArgumentException(msg);
10987                }
10988                if (conn == null) {
10989                    throw new NullPointerException("connection is null");
10990                }
10991                if (decProviderCountLocked(conn, null, null, stable)) {
10992                    updateOomAdjLocked();
10993                }
10994            }
10995        } finally {
10996            Binder.restoreCallingIdentity(ident);
10997        }
10998    }
10999
11000    public void removeContentProviderExternal(String name, IBinder token) {
11001        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11002            "Do not have permission in call removeContentProviderExternal()");
11003        int userId = UserHandle.getCallingUserId();
11004        long ident = Binder.clearCallingIdentity();
11005        try {
11006            removeContentProviderExternalUnchecked(name, token, userId);
11007        } finally {
11008            Binder.restoreCallingIdentity(ident);
11009        }
11010    }
11011
11012    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11013        synchronized (this) {
11014            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11015            if(cpr == null) {
11016                //remove from mProvidersByClass
11017                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11018                return;
11019            }
11020
11021            //update content provider record entry info
11022            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11023            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11024            if (localCpr.hasExternalProcessHandles()) {
11025                if (localCpr.removeExternalProcessHandleLocked(token)) {
11026                    updateOomAdjLocked();
11027                } else {
11028                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11029                            + " with no external reference for token: "
11030                            + token + ".");
11031                }
11032            } else {
11033                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11034                        + " with no external references.");
11035            }
11036        }
11037    }
11038
11039    public final void publishContentProviders(IApplicationThread caller,
11040            List<ContentProviderHolder> providers) {
11041        if (providers == null) {
11042            return;
11043        }
11044
11045        enforceNotIsolatedCaller("publishContentProviders");
11046        synchronized (this) {
11047            final ProcessRecord r = getRecordForAppLocked(caller);
11048            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11049            if (r == null) {
11050                throw new SecurityException(
11051                        "Unable to find app for caller " + caller
11052                      + " (pid=" + Binder.getCallingPid()
11053                      + ") when publishing content providers");
11054            }
11055
11056            final long origId = Binder.clearCallingIdentity();
11057
11058            final int N = providers.size();
11059            for (int i = 0; i < N; i++) {
11060                ContentProviderHolder src = providers.get(i);
11061                if (src == null || src.info == null || src.provider == null) {
11062                    continue;
11063                }
11064                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11065                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11066                if (dst != null) {
11067                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11068                    mProviderMap.putProviderByClass(comp, dst);
11069                    String names[] = dst.info.authority.split(";");
11070                    for (int j = 0; j < names.length; j++) {
11071                        mProviderMap.putProviderByName(names[j], dst);
11072                    }
11073
11074                    int launchingCount = mLaunchingProviders.size();
11075                    int j;
11076                    boolean wasInLaunchingProviders = false;
11077                    for (j = 0; j < launchingCount; j++) {
11078                        if (mLaunchingProviders.get(j) == dst) {
11079                            mLaunchingProviders.remove(j);
11080                            wasInLaunchingProviders = true;
11081                            j--;
11082                            launchingCount--;
11083                        }
11084                    }
11085                    if (wasInLaunchingProviders) {
11086                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11087                    }
11088                    synchronized (dst) {
11089                        dst.provider = src.provider;
11090                        dst.proc = r;
11091                        dst.notifyAll();
11092                    }
11093                    updateOomAdjLocked(r);
11094                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11095                            src.info.authority);
11096                }
11097            }
11098
11099            Binder.restoreCallingIdentity(origId);
11100        }
11101    }
11102
11103    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11104        ContentProviderConnection conn;
11105        try {
11106            conn = (ContentProviderConnection)connection;
11107        } catch (ClassCastException e) {
11108            String msg ="refContentProvider: " + connection
11109                    + " not a ContentProviderConnection";
11110            Slog.w(TAG, msg);
11111            throw new IllegalArgumentException(msg);
11112        }
11113        if (conn == null) {
11114            throw new NullPointerException("connection is null");
11115        }
11116
11117        synchronized (this) {
11118            if (stable > 0) {
11119                conn.numStableIncs += stable;
11120            }
11121            stable = conn.stableCount + stable;
11122            if (stable < 0) {
11123                throw new IllegalStateException("stableCount < 0: " + stable);
11124            }
11125
11126            if (unstable > 0) {
11127                conn.numUnstableIncs += unstable;
11128            }
11129            unstable = conn.unstableCount + unstable;
11130            if (unstable < 0) {
11131                throw new IllegalStateException("unstableCount < 0: " + unstable);
11132            }
11133
11134            if ((stable+unstable) <= 0) {
11135                throw new IllegalStateException("ref counts can't go to zero here: stable="
11136                        + stable + " unstable=" + unstable);
11137            }
11138            conn.stableCount = stable;
11139            conn.unstableCount = unstable;
11140            return !conn.dead;
11141        }
11142    }
11143
11144    public void unstableProviderDied(IBinder connection) {
11145        ContentProviderConnection conn;
11146        try {
11147            conn = (ContentProviderConnection)connection;
11148        } catch (ClassCastException e) {
11149            String msg ="refContentProvider: " + connection
11150                    + " not a ContentProviderConnection";
11151            Slog.w(TAG, msg);
11152            throw new IllegalArgumentException(msg);
11153        }
11154        if (conn == null) {
11155            throw new NullPointerException("connection is null");
11156        }
11157
11158        // Safely retrieve the content provider associated with the connection.
11159        IContentProvider provider;
11160        synchronized (this) {
11161            provider = conn.provider.provider;
11162        }
11163
11164        if (provider == null) {
11165            // Um, yeah, we're way ahead of you.
11166            return;
11167        }
11168
11169        // Make sure the caller is being honest with us.
11170        if (provider.asBinder().pingBinder()) {
11171            // Er, no, still looks good to us.
11172            synchronized (this) {
11173                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11174                        + " says " + conn + " died, but we don't agree");
11175                return;
11176            }
11177        }
11178
11179        // Well look at that!  It's dead!
11180        synchronized (this) {
11181            if (conn.provider.provider != provider) {
11182                // But something changed...  good enough.
11183                return;
11184            }
11185
11186            ProcessRecord proc = conn.provider.proc;
11187            if (proc == null || proc.thread == null) {
11188                // Seems like the process is already cleaned up.
11189                return;
11190            }
11191
11192            // As far as we're concerned, this is just like receiving a
11193            // death notification...  just a bit prematurely.
11194            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11195                    + ") early provider death");
11196            final long ident = Binder.clearCallingIdentity();
11197            try {
11198                appDiedLocked(proc);
11199            } finally {
11200                Binder.restoreCallingIdentity(ident);
11201            }
11202        }
11203    }
11204
11205    @Override
11206    public void appNotRespondingViaProvider(IBinder connection) {
11207        enforceCallingPermission(
11208                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11209
11210        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11211        if (conn == null) {
11212            Slog.w(TAG, "ContentProviderConnection is null");
11213            return;
11214        }
11215
11216        final ProcessRecord host = conn.provider.proc;
11217        if (host == null) {
11218            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11219            return;
11220        }
11221
11222        mHandler.post(new Runnable() {
11223            @Override
11224            public void run() {
11225                mAppErrors.appNotResponding(host, null, null, false,
11226                        "ContentProvider not responding");
11227            }
11228        });
11229    }
11230
11231    public final void installSystemProviders() {
11232        List<ProviderInfo> providers;
11233        synchronized (this) {
11234            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11235            providers = generateApplicationProvidersLocked(app);
11236            if (providers != null) {
11237                for (int i=providers.size()-1; i>=0; i--) {
11238                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11239                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11240                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11241                                + ": not system .apk");
11242                        providers.remove(i);
11243                    }
11244                }
11245            }
11246        }
11247        if (providers != null) {
11248            mSystemThread.installSystemProviders(providers);
11249        }
11250
11251        mCoreSettingsObserver = new CoreSettingsObserver(this);
11252        mFontScaleSettingObserver = new FontScaleSettingObserver();
11253
11254        //mUsageStatsService.monitorPackages();
11255    }
11256
11257    private void startPersistentApps(int matchFlags) {
11258        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11259
11260        synchronized (this) {
11261            try {
11262                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11263                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11264                for (ApplicationInfo app : apps) {
11265                    if (!"android".equals(app.packageName)) {
11266                        addAppLocked(app, false, null /* ABI override */);
11267                    }
11268                }
11269            } catch (RemoteException ex) {
11270            }
11271        }
11272    }
11273
11274    /**
11275     * When a user is unlocked, we need to install encryption-unaware providers
11276     * belonging to any running apps.
11277     */
11278    private void installEncryptionUnawareProviders(int userId) {
11279        // We're only interested in providers that are encryption unaware, and
11280        // we don't care about uninstalled apps, since there's no way they're
11281        // running at this point.
11282        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11283
11284        synchronized (this) {
11285            final int NP = mProcessNames.getMap().size();
11286            for (int ip = 0; ip < NP; ip++) {
11287                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11288                final int NA = apps.size();
11289                for (int ia = 0; ia < NA; ia++) {
11290                    final ProcessRecord app = apps.valueAt(ia);
11291                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11292
11293                    final int NG = app.pkgList.size();
11294                    for (int ig = 0; ig < NG; ig++) {
11295                        try {
11296                            final String pkgName = app.pkgList.keyAt(ig);
11297                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11298                                    .getPackageInfo(pkgName, matchFlags, userId);
11299                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11300                                for (ProviderInfo pi : pkgInfo.providers) {
11301                                    // TODO: keep in sync with generateApplicationProvidersLocked
11302                                    final boolean processMatch = Objects.equals(pi.processName,
11303                                            app.processName) || pi.multiprocess;
11304                                    final boolean userMatch = isSingleton(pi.processName,
11305                                            pi.applicationInfo, pi.name, pi.flags)
11306                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11307                                    if (processMatch && userMatch) {
11308                                        Log.v(TAG, "Installing " + pi);
11309                                        app.thread.scheduleInstallProvider(pi);
11310                                    } else {
11311                                        Log.v(TAG, "Skipping " + pi);
11312                                    }
11313                                }
11314                            }
11315                        } catch (RemoteException ignored) {
11316                        }
11317                    }
11318                }
11319            }
11320        }
11321    }
11322
11323    /**
11324     * Allows apps to retrieve the MIME type of a URI.
11325     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11326     * users, then it does not need permission to access the ContentProvider.
11327     * Either, it needs cross-user uri grants.
11328     *
11329     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11330     *
11331     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11332     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11333     */
11334    public String getProviderMimeType(Uri uri, int userId) {
11335        enforceNotIsolatedCaller("getProviderMimeType");
11336        final String name = uri.getAuthority();
11337        int callingUid = Binder.getCallingUid();
11338        int callingPid = Binder.getCallingPid();
11339        long ident = 0;
11340        boolean clearedIdentity = false;
11341        synchronized (this) {
11342            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11343        }
11344        if (canClearIdentity(callingPid, callingUid, userId)) {
11345            clearedIdentity = true;
11346            ident = Binder.clearCallingIdentity();
11347        }
11348        ContentProviderHolder holder = null;
11349        try {
11350            holder = getContentProviderExternalUnchecked(name, null, userId);
11351            if (holder != null) {
11352                return holder.provider.getType(uri);
11353            }
11354        } catch (RemoteException e) {
11355            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11356            return null;
11357        } catch (Exception e) {
11358            Log.w(TAG, "Exception while determining type of " + uri, e);
11359            return null;
11360        } finally {
11361            // We need to clear the identity to call removeContentProviderExternalUnchecked
11362            if (!clearedIdentity) {
11363                ident = Binder.clearCallingIdentity();
11364            }
11365            try {
11366                if (holder != null) {
11367                    removeContentProviderExternalUnchecked(name, null, userId);
11368                }
11369            } finally {
11370                Binder.restoreCallingIdentity(ident);
11371            }
11372        }
11373
11374        return null;
11375    }
11376
11377    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11378        if (UserHandle.getUserId(callingUid) == userId) {
11379            return true;
11380        }
11381        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11382                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11383                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11384                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11385                return true;
11386        }
11387        return false;
11388    }
11389
11390    // =========================================================
11391    // GLOBAL MANAGEMENT
11392    // =========================================================
11393
11394    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11395            boolean isolated, int isolatedUid) {
11396        String proc = customProcess != null ? customProcess : info.processName;
11397        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11398        final int userId = UserHandle.getUserId(info.uid);
11399        int uid = info.uid;
11400        if (isolated) {
11401            if (isolatedUid == 0) {
11402                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11403                while (true) {
11404                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11405                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11406                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11407                    }
11408                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11409                    mNextIsolatedProcessUid++;
11410                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11411                        // No process for this uid, use it.
11412                        break;
11413                    }
11414                    stepsLeft--;
11415                    if (stepsLeft <= 0) {
11416                        return null;
11417                    }
11418                }
11419            } else {
11420                // Special case for startIsolatedProcess (internal only), where
11421                // the uid of the isolated process is specified by the caller.
11422                uid = isolatedUid;
11423            }
11424        }
11425        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11426        if (!mBooted && !mBooting
11427                && userId == UserHandle.USER_SYSTEM
11428                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11429            r.persistent = true;
11430        }
11431        addProcessNameLocked(r);
11432        return r;
11433    }
11434
11435    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11436            String abiOverride) {
11437        ProcessRecord app;
11438        if (!isolated) {
11439            app = getProcessRecordLocked(info.processName, info.uid, true);
11440        } else {
11441            app = null;
11442        }
11443
11444        if (app == null) {
11445            app = newProcessRecordLocked(info, null, isolated, 0);
11446            updateLruProcessLocked(app, false, null);
11447            updateOomAdjLocked();
11448        }
11449
11450        // This package really, really can not be stopped.
11451        try {
11452            AppGlobals.getPackageManager().setPackageStoppedState(
11453                    info.packageName, false, UserHandle.getUserId(app.uid));
11454        } catch (RemoteException e) {
11455        } catch (IllegalArgumentException e) {
11456            Slog.w(TAG, "Failed trying to unstop package "
11457                    + info.packageName + ": " + e);
11458        }
11459
11460        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11461            app.persistent = true;
11462            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11463        }
11464        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11465            mPersistentStartingProcesses.add(app);
11466            startProcessLocked(app, "added application", app.processName, abiOverride,
11467                    null /* entryPoint */, null /* entryPointArgs */);
11468        }
11469
11470        return app;
11471    }
11472
11473    public void unhandledBack() {
11474        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11475                "unhandledBack()");
11476
11477        synchronized(this) {
11478            final long origId = Binder.clearCallingIdentity();
11479            try {
11480                getFocusedStack().unhandledBackLocked();
11481            } finally {
11482                Binder.restoreCallingIdentity(origId);
11483            }
11484        }
11485    }
11486
11487    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11488        enforceNotIsolatedCaller("openContentUri");
11489        final int userId = UserHandle.getCallingUserId();
11490        String name = uri.getAuthority();
11491        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11492        ParcelFileDescriptor pfd = null;
11493        if (cph != null) {
11494            // We record the binder invoker's uid in thread-local storage before
11495            // going to the content provider to open the file.  Later, in the code
11496            // that handles all permissions checks, we look for this uid and use
11497            // that rather than the Activity Manager's own uid.  The effect is that
11498            // we do the check against the caller's permissions even though it looks
11499            // to the content provider like the Activity Manager itself is making
11500            // the request.
11501            Binder token = new Binder();
11502            sCallerIdentity.set(new Identity(
11503                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11504            try {
11505                pfd = cph.provider.openFile(null, uri, "r", null, token);
11506            } catch (FileNotFoundException e) {
11507                // do nothing; pfd will be returned null
11508            } finally {
11509                // Ensure that whatever happens, we clean up the identity state
11510                sCallerIdentity.remove();
11511                // Ensure we're done with the provider.
11512                removeContentProviderExternalUnchecked(name, null, userId);
11513            }
11514        } else {
11515            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11516        }
11517        return pfd;
11518    }
11519
11520    // Actually is sleeping or shutting down or whatever else in the future
11521    // is an inactive state.
11522    boolean isSleepingOrShuttingDownLocked() {
11523        return isSleepingLocked() || mShuttingDown;
11524    }
11525
11526    boolean isShuttingDownLocked() {
11527        return mShuttingDown;
11528    }
11529
11530    boolean isSleepingLocked() {
11531        return mSleeping;
11532    }
11533
11534    void onWakefulnessChanged(int wakefulness) {
11535        synchronized(this) {
11536            mWakefulness = wakefulness;
11537            updateSleepIfNeededLocked();
11538        }
11539    }
11540
11541    void finishRunningVoiceLocked() {
11542        if (mRunningVoice != null) {
11543            mRunningVoice = null;
11544            mVoiceWakeLock.release();
11545            updateSleepIfNeededLocked();
11546        }
11547    }
11548
11549    void startTimeTrackingFocusedActivityLocked() {
11550        if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11551            mCurAppTimeTracker.start(mFocusedActivity.packageName);
11552        }
11553    }
11554
11555    void updateSleepIfNeededLocked() {
11556        if (mSleeping && !shouldSleepLocked()) {
11557            mSleeping = false;
11558            startTimeTrackingFocusedActivityLocked();
11559            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11560            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11561            updateOomAdjLocked();
11562        } else if (!mSleeping && shouldSleepLocked()) {
11563            mSleeping = true;
11564            if (mCurAppTimeTracker != null) {
11565                mCurAppTimeTracker.stop();
11566            }
11567            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11568            mStackSupervisor.goingToSleepLocked();
11569            updateOomAdjLocked();
11570
11571            // Initialize the wake times of all processes.
11572            checkExcessivePowerUsageLocked(false);
11573            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11574            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11575            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11576        }
11577    }
11578
11579    private boolean shouldSleepLocked() {
11580        // Resume applications while running a voice interactor.
11581        if (mRunningVoice != null) {
11582            return false;
11583        }
11584
11585        // TODO: Transform the lock screen state into a sleep token instead.
11586        switch (mWakefulness) {
11587            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11588            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11589            case PowerManagerInternal.WAKEFULNESS_DOZING:
11590                // Pause applications whenever the lock screen is shown or any sleep
11591                // tokens have been acquired.
11592                return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11593            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11594            default:
11595                // If we're asleep then pause applications unconditionally.
11596                return true;
11597        }
11598    }
11599
11600    /** Pokes the task persister. */
11601    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11602        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11603    }
11604
11605    /** Notifies all listeners when the task stack has changed. */
11606    void notifyTaskStackChangedLocked() {
11607        mHandler.sendEmptyMessage(LOG_STACK_STATE);
11608        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11609        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11610        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11611    }
11612
11613    /** Notifies all listeners when an Activity is pinned. */
11614    void notifyActivityPinnedLocked() {
11615        mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11616        mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11617    }
11618
11619    /**
11620     * Notifies all listeners when an attempt was made to start an an activity that is already
11621     * running in the pinned stack and the activity was not actually started, but the task is
11622     * either brought to the front or a new Intent is delivered to it.
11623     */
11624    void notifyPinnedActivityRestartAttemptLocked() {
11625        mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11626        mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11627    }
11628
11629    /** Notifies all listeners when the pinned stack animation ends. */
11630    @Override
11631    public void notifyPinnedStackAnimationEnded() {
11632        synchronized (this) {
11633            mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11634            mHandler.obtainMessage(
11635                    NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11636        }
11637    }
11638
11639    @Override
11640    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11641        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11642    }
11643
11644    @Override
11645    public boolean shutdown(int timeout) {
11646        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11647                != PackageManager.PERMISSION_GRANTED) {
11648            throw new SecurityException("Requires permission "
11649                    + android.Manifest.permission.SHUTDOWN);
11650        }
11651
11652        boolean timedout = false;
11653
11654        synchronized(this) {
11655            mShuttingDown = true;
11656            updateEventDispatchingLocked();
11657            timedout = mStackSupervisor.shutdownLocked(timeout);
11658        }
11659
11660        mAppOpsService.shutdown();
11661        if (mUsageStatsService != null) {
11662            mUsageStatsService.prepareShutdown();
11663        }
11664        mBatteryStatsService.shutdown();
11665        synchronized (this) {
11666            mProcessStats.shutdownLocked();
11667            notifyTaskPersisterLocked(null, true);
11668        }
11669
11670        return timedout;
11671    }
11672
11673    public final void activitySlept(IBinder token) {
11674        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11675
11676        final long origId = Binder.clearCallingIdentity();
11677
11678        synchronized (this) {
11679            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11680            if (r != null) {
11681                mStackSupervisor.activitySleptLocked(r);
11682            }
11683        }
11684
11685        Binder.restoreCallingIdentity(origId);
11686    }
11687
11688    private String lockScreenShownToString() {
11689        switch (mLockScreenShown) {
11690            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11691            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11692            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11693            default: return "Unknown=" + mLockScreenShown;
11694        }
11695    }
11696
11697    void logLockScreen(String msg) {
11698        if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11699                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11700                + PowerManagerInternal.wakefulnessToString(mWakefulness)
11701                + " mSleeping=" + mSleeping);
11702    }
11703
11704    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11705        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11706        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11707        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11708            boolean wasRunningVoice = mRunningVoice != null;
11709            mRunningVoice = session;
11710            if (!wasRunningVoice) {
11711                mVoiceWakeLock.acquire();
11712                updateSleepIfNeededLocked();
11713            }
11714        }
11715    }
11716
11717    private void updateEventDispatchingLocked() {
11718        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11719    }
11720
11721    public void setLockScreenShown(boolean showing, boolean occluded) {
11722        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11723                != PackageManager.PERMISSION_GRANTED) {
11724            throw new SecurityException("Requires permission "
11725                    + android.Manifest.permission.DEVICE_POWER);
11726        }
11727
11728        synchronized(this) {
11729            long ident = Binder.clearCallingIdentity();
11730            try {
11731                if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11732                mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11733                if (showing && occluded) {
11734                    // The lock screen is currently showing, but is occluded by a window that can
11735                    // show on top of the lock screen. In this can we want to dismiss the docked
11736                    // stack since it will be complicated/risky to try to put the activity on top
11737                    // of the lock screen in the right fullscreen configuration.
11738                    mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11739                            mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11740                }
11741
11742                updateSleepIfNeededLocked();
11743            } finally {
11744                Binder.restoreCallingIdentity(ident);
11745            }
11746        }
11747    }
11748
11749    @Override
11750    public void notifyLockedProfile(@UserIdInt int userId) {
11751        try {
11752            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11753                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11754            }
11755        } catch (RemoteException ex) {
11756            throw new SecurityException("Fail to check is caller a privileged app", ex);
11757        }
11758
11759        synchronized (this) {
11760            if (mStackSupervisor.isUserLockedProfile(userId)) {
11761                final long ident = Binder.clearCallingIdentity();
11762                try {
11763                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11764                    if (mUserController.isLockScreenDisabled(currentUserId)) {
11765                        // If there is no device lock, we will show the profile's credential page.
11766                        mActivityStarter.showConfirmDeviceCredential(userId);
11767                    } else {
11768                        // Showing launcher to avoid user entering credential twice.
11769                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11770                    }
11771                } finally {
11772                    Binder.restoreCallingIdentity(ident);
11773                }
11774            }
11775        }
11776    }
11777
11778    @Override
11779    public void startConfirmDeviceCredentialIntent(Intent intent) {
11780        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11781        synchronized (this) {
11782            final long ident = Binder.clearCallingIdentity();
11783            try {
11784                mActivityStarter.startConfirmCredentialIntent(intent);
11785            } finally {
11786                Binder.restoreCallingIdentity(ident);
11787            }
11788        }
11789    }
11790
11791    @Override
11792    public void stopAppSwitches() {
11793        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11794                != PackageManager.PERMISSION_GRANTED) {
11795            throw new SecurityException("viewquires permission "
11796                    + android.Manifest.permission.STOP_APP_SWITCHES);
11797        }
11798
11799        synchronized(this) {
11800            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11801                    + APP_SWITCH_DELAY_TIME;
11802            mDidAppSwitch = false;
11803            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11804            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11805            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11806        }
11807    }
11808
11809    public void resumeAppSwitches() {
11810        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11811                != PackageManager.PERMISSION_GRANTED) {
11812            throw new SecurityException("Requires permission "
11813                    + android.Manifest.permission.STOP_APP_SWITCHES);
11814        }
11815
11816        synchronized(this) {
11817            // Note that we don't execute any pending app switches... we will
11818            // let those wait until either the timeout, or the next start
11819            // activity request.
11820            mAppSwitchesAllowedTime = 0;
11821        }
11822    }
11823
11824    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11825            int callingPid, int callingUid, String name) {
11826        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11827            return true;
11828        }
11829
11830        int perm = checkComponentPermission(
11831                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11832                sourceUid, -1, true);
11833        if (perm == PackageManager.PERMISSION_GRANTED) {
11834            return true;
11835        }
11836
11837        // If the actual IPC caller is different from the logical source, then
11838        // also see if they are allowed to control app switches.
11839        if (callingUid != -1 && callingUid != sourceUid) {
11840            perm = checkComponentPermission(
11841                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11842                    callingUid, -1, true);
11843            if (perm == PackageManager.PERMISSION_GRANTED) {
11844                return true;
11845            }
11846        }
11847
11848        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11849        return false;
11850    }
11851
11852    public void setDebugApp(String packageName, boolean waitForDebugger,
11853            boolean persistent) {
11854        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11855                "setDebugApp()");
11856
11857        long ident = Binder.clearCallingIdentity();
11858        try {
11859            // Note that this is not really thread safe if there are multiple
11860            // callers into it at the same time, but that's not a situation we
11861            // care about.
11862            if (persistent) {
11863                final ContentResolver resolver = mContext.getContentResolver();
11864                Settings.Global.putString(
11865                    resolver, Settings.Global.DEBUG_APP,
11866                    packageName);
11867                Settings.Global.putInt(
11868                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11869                    waitForDebugger ? 1 : 0);
11870            }
11871
11872            synchronized (this) {
11873                if (!persistent) {
11874                    mOrigDebugApp = mDebugApp;
11875                    mOrigWaitForDebugger = mWaitForDebugger;
11876                }
11877                mDebugApp = packageName;
11878                mWaitForDebugger = waitForDebugger;
11879                mDebugTransient = !persistent;
11880                if (packageName != null) {
11881                    forceStopPackageLocked(packageName, -1, false, false, true, true,
11882                            false, UserHandle.USER_ALL, "set debug app");
11883                }
11884            }
11885        } finally {
11886            Binder.restoreCallingIdentity(ident);
11887        }
11888    }
11889
11890    void setTrackAllocationApp(ApplicationInfo app, String processName) {
11891        synchronized (this) {
11892            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11893            if (!isDebuggable) {
11894                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11895                    throw new SecurityException("Process not debuggable: " + app.packageName);
11896                }
11897            }
11898
11899            mTrackAllocationApp = processName;
11900        }
11901    }
11902
11903    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11904        synchronized (this) {
11905            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11906            if (!isDebuggable) {
11907                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11908                    throw new SecurityException("Process not debuggable: " + app.packageName);
11909                }
11910            }
11911            mProfileApp = processName;
11912            mProfileFile = profilerInfo.profileFile;
11913            if (mProfileFd != null) {
11914                try {
11915                    mProfileFd.close();
11916                } catch (IOException e) {
11917                }
11918                mProfileFd = null;
11919            }
11920            mProfileFd = profilerInfo.profileFd;
11921            mSamplingInterval = profilerInfo.samplingInterval;
11922            mAutoStopProfiler = profilerInfo.autoStopProfiler;
11923            mProfileType = 0;
11924        }
11925    }
11926
11927    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11928        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11929        if (!isDebuggable) {
11930            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11931                throw new SecurityException("Process not debuggable: " + app.packageName);
11932            }
11933        }
11934        mNativeDebuggingApp = processName;
11935    }
11936
11937    @Override
11938    public void setAlwaysFinish(boolean enabled) {
11939        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11940                "setAlwaysFinish()");
11941
11942        long ident = Binder.clearCallingIdentity();
11943        try {
11944            Settings.Global.putInt(
11945                    mContext.getContentResolver(),
11946                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11947
11948            synchronized (this) {
11949                mAlwaysFinishActivities = enabled;
11950            }
11951        } finally {
11952            Binder.restoreCallingIdentity(ident);
11953        }
11954    }
11955
11956    @Override
11957    public void setLenientBackgroundCheck(boolean enabled) {
11958        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11959                "setLenientBackgroundCheck()");
11960
11961        long ident = Binder.clearCallingIdentity();
11962        try {
11963            Settings.Global.putInt(
11964                    mContext.getContentResolver(),
11965                    Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11966
11967            synchronized (this) {
11968                mLenientBackgroundCheck = enabled;
11969            }
11970        } finally {
11971            Binder.restoreCallingIdentity(ident);
11972        }
11973    }
11974
11975    @Override
11976    public void setActivityController(IActivityController controller, boolean imAMonkey) {
11977        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11978                "setActivityController()");
11979        synchronized (this) {
11980            mController = controller;
11981            mControllerIsAMonkey = imAMonkey;
11982            Watchdog.getInstance().setActivityController(controller);
11983        }
11984    }
11985
11986    @Override
11987    public void setUserIsMonkey(boolean userIsMonkey) {
11988        synchronized (this) {
11989            synchronized (mPidsSelfLocked) {
11990                final int callingPid = Binder.getCallingPid();
11991                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11992                if (precessRecord == null) {
11993                    throw new SecurityException("Unknown process: " + callingPid);
11994                }
11995                if (precessRecord.instrumentationUiAutomationConnection  == null) {
11996                    throw new SecurityException("Only an instrumentation process "
11997                            + "with a UiAutomation can call setUserIsMonkey");
11998                }
11999            }
12000            mUserIsMonkey = userIsMonkey;
12001        }
12002    }
12003
12004    @Override
12005    public boolean isUserAMonkey() {
12006        synchronized (this) {
12007            // If there is a controller also implies the user is a monkey.
12008            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12009        }
12010    }
12011
12012    public void requestBugReport(int bugreportType) {
12013        String service = null;
12014        switch (bugreportType) {
12015            case ActivityManager.BUGREPORT_OPTION_FULL:
12016                service = "bugreport";
12017                break;
12018            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12019                service = "bugreportplus";
12020                break;
12021            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12022                service = "bugreportremote";
12023                break;
12024        }
12025        if (service == null) {
12026            throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12027                    + bugreportType);
12028        }
12029        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12030        SystemProperties.set("ctl.start", service);
12031    }
12032
12033    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12034        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12035    }
12036
12037    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12038        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12039            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12040        }
12041        return KEY_DISPATCHING_TIMEOUT;
12042    }
12043
12044    @Override
12045    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12046        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12047                != PackageManager.PERMISSION_GRANTED) {
12048            throw new SecurityException("Requires permission "
12049                    + android.Manifest.permission.FILTER_EVENTS);
12050        }
12051        ProcessRecord proc;
12052        long timeout;
12053        synchronized (this) {
12054            synchronized (mPidsSelfLocked) {
12055                proc = mPidsSelfLocked.get(pid);
12056            }
12057            timeout = getInputDispatchingTimeoutLocked(proc);
12058        }
12059
12060        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12061            return -1;
12062        }
12063
12064        return timeout;
12065    }
12066
12067    /**
12068     * Handle input dispatching timeouts.
12069     * Returns whether input dispatching should be aborted or not.
12070     */
12071    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12072            final ActivityRecord activity, final ActivityRecord parent,
12073            final boolean aboveSystem, String reason) {
12074        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12075                != PackageManager.PERMISSION_GRANTED) {
12076            throw new SecurityException("Requires permission "
12077                    + android.Manifest.permission.FILTER_EVENTS);
12078        }
12079
12080        final String annotation;
12081        if (reason == null) {
12082            annotation = "Input dispatching timed out";
12083        } else {
12084            annotation = "Input dispatching timed out (" + reason + ")";
12085        }
12086
12087        if (proc != null) {
12088            synchronized (this) {
12089                if (proc.debugging) {
12090                    return false;
12091                }
12092
12093                if (mDidDexOpt) {
12094                    // Give more time since we were dexopting.
12095                    mDidDexOpt = false;
12096                    return false;
12097                }
12098
12099                if (proc.instrumentationClass != null) {
12100                    Bundle info = new Bundle();
12101                    info.putString("shortMsg", "keyDispatchingTimedOut");
12102                    info.putString("longMsg", annotation);
12103                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12104                    return true;
12105                }
12106            }
12107            mHandler.post(new Runnable() {
12108                @Override
12109                public void run() {
12110                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12111                }
12112            });
12113        }
12114
12115        return true;
12116    }
12117
12118    @Override
12119    public Bundle getAssistContextExtras(int requestType) {
12120        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12121                null, null, true /* focused */, true /* newSessionId */,
12122                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12123        if (pae == null) {
12124            return null;
12125        }
12126        synchronized (pae) {
12127            while (!pae.haveResult) {
12128                try {
12129                    pae.wait();
12130                } catch (InterruptedException e) {
12131                }
12132            }
12133        }
12134        synchronized (this) {
12135            buildAssistBundleLocked(pae, pae.result);
12136            mPendingAssistExtras.remove(pae);
12137            mUiHandler.removeCallbacks(pae);
12138        }
12139        return pae.extras;
12140    }
12141
12142    @Override
12143    public boolean isAssistDataAllowedOnCurrentActivity() {
12144        int userId;
12145        synchronized (this) {
12146            userId = mUserController.getCurrentUserIdLocked();
12147            ActivityRecord activity = getFocusedStack().topActivity();
12148            if (activity == null) {
12149                return false;
12150            }
12151            userId = activity.userId;
12152        }
12153        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12154                Context.DEVICE_POLICY_SERVICE);
12155        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12156    }
12157
12158    @Override
12159    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12160        long ident = Binder.clearCallingIdentity();
12161        try {
12162            synchronized (this) {
12163                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12164                ActivityRecord top = getFocusedStack().topActivity();
12165                if (top != caller) {
12166                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12167                            + " is not current top " + top);
12168                    return false;
12169                }
12170                if (!top.nowVisible) {
12171                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12172                            + " is not visible");
12173                    return false;
12174                }
12175            }
12176            AssistUtils utils = new AssistUtils(mContext);
12177            return utils.showSessionForActiveService(args,
12178                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12179        } finally {
12180            Binder.restoreCallingIdentity(ident);
12181        }
12182    }
12183
12184    @Override
12185    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12186            Bundle receiverExtras,
12187            IBinder activityToken, boolean focused, boolean newSessionId) {
12188        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12189                activityToken, focused, newSessionId,
12190                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12191                != null;
12192    }
12193
12194    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12195            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12196            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12197        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12198                "enqueueAssistContext()");
12199        synchronized (this) {
12200            ActivityRecord activity = getFocusedStack().topActivity();
12201            if (activity == null) {
12202                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12203                return null;
12204            }
12205            if (activity.app == null || activity.app.thread == null) {
12206                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12207                return null;
12208            }
12209            if (focused) {
12210                if (activityToken != null) {
12211                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12212                    if (activity != caller) {
12213                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12214                                + " is not current top " + activity);
12215                        return null;
12216                    }
12217                }
12218            } else {
12219                activity = ActivityRecord.forTokenLocked(activityToken);
12220                if (activity == null) {
12221                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12222                            + " couldn't be found");
12223                    return null;
12224                }
12225            }
12226
12227            PendingAssistExtras pae;
12228            Bundle extras = new Bundle();
12229            if (args != null) {
12230                extras.putAll(args);
12231            }
12232            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12233            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12234            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12235                    userHandle);
12236            // Increment the sessionId if necessary
12237            if (newSessionId) {
12238                mViSessionId++;
12239            }
12240            try {
12241                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12242                        requestType, mViSessionId);
12243                mPendingAssistExtras.add(pae);
12244                mUiHandler.postDelayed(pae, timeout);
12245            } catch (RemoteException e) {
12246                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12247                return null;
12248            }
12249            return pae;
12250        }
12251    }
12252
12253    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12254        IResultReceiver receiver;
12255        synchronized (this) {
12256            mPendingAssistExtras.remove(pae);
12257            receiver = pae.receiver;
12258        }
12259        if (receiver != null) {
12260            // Caller wants result sent back to them.
12261            Bundle sendBundle = new Bundle();
12262            // At least return the receiver extras
12263            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12264                    pae.receiverExtras);
12265            try {
12266                pae.receiver.send(0, sendBundle);
12267            } catch (RemoteException e) {
12268            }
12269        }
12270    }
12271
12272    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12273        if (result != null) {
12274            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12275        }
12276        if (pae.hint != null) {
12277            pae.extras.putBoolean(pae.hint, true);
12278        }
12279    }
12280
12281    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12282            AssistContent content, Uri referrer) {
12283        PendingAssistExtras pae = (PendingAssistExtras)token;
12284        synchronized (pae) {
12285            pae.result = extras;
12286            pae.structure = structure;
12287            pae.content = content;
12288            if (referrer != null) {
12289                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12290            }
12291            pae.haveResult = true;
12292            pae.notifyAll();
12293            if (pae.intent == null && pae.receiver == null) {
12294                // Caller is just waiting for the result.
12295                return;
12296            }
12297        }
12298
12299        // We are now ready to launch the assist activity.
12300        IResultReceiver sendReceiver = null;
12301        Bundle sendBundle = null;
12302        synchronized (this) {
12303            buildAssistBundleLocked(pae, extras);
12304            boolean exists = mPendingAssistExtras.remove(pae);
12305            mUiHandler.removeCallbacks(pae);
12306            if (!exists) {
12307                // Timed out.
12308                return;
12309            }
12310            if ((sendReceiver=pae.receiver) != null) {
12311                // Caller wants result sent back to them.
12312                sendBundle = new Bundle();
12313                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12314                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12315                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12316                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12317                        pae.receiverExtras);
12318            }
12319        }
12320        if (sendReceiver != null) {
12321            try {
12322                sendReceiver.send(0, sendBundle);
12323            } catch (RemoteException e) {
12324            }
12325            return;
12326        }
12327
12328        long ident = Binder.clearCallingIdentity();
12329        try {
12330            pae.intent.replaceExtras(pae.extras);
12331            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12332                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12333                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12334            closeSystemDialogs("assist");
12335            try {
12336                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12337            } catch (ActivityNotFoundException e) {
12338                Slog.w(TAG, "No activity to handle assist action.", e);
12339            }
12340        } finally {
12341            Binder.restoreCallingIdentity(ident);
12342        }
12343    }
12344
12345    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12346            Bundle args) {
12347        return enqueueAssistContext(requestType, intent, hint, null, null, null,
12348                true /* focused */, true /* newSessionId */,
12349                userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12350    }
12351
12352    public void registerProcessObserver(IProcessObserver observer) {
12353        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12354                "registerProcessObserver()");
12355        synchronized (this) {
12356            mProcessObservers.register(observer);
12357        }
12358    }
12359
12360    @Override
12361    public void unregisterProcessObserver(IProcessObserver observer) {
12362        synchronized (this) {
12363            mProcessObservers.unregister(observer);
12364        }
12365    }
12366
12367    @Override
12368    public void registerUidObserver(IUidObserver observer, int which) {
12369        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12370                "registerUidObserver()");
12371        synchronized (this) {
12372            mUidObservers.register(observer, which);
12373        }
12374    }
12375
12376    @Override
12377    public void unregisterUidObserver(IUidObserver observer) {
12378        synchronized (this) {
12379            mUidObservers.unregister(observer);
12380        }
12381    }
12382
12383    @Override
12384    public boolean convertFromTranslucent(IBinder token) {
12385        final long origId = Binder.clearCallingIdentity();
12386        try {
12387            synchronized (this) {
12388                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12389                if (r == null) {
12390                    return false;
12391                }
12392                final boolean translucentChanged = r.changeWindowTranslucency(true);
12393                if (translucentChanged) {
12394                    r.task.stack.releaseBackgroundResources(r);
12395                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12396                }
12397                mWindowManager.setAppFullscreen(token, true);
12398                return translucentChanged;
12399            }
12400        } finally {
12401            Binder.restoreCallingIdentity(origId);
12402        }
12403    }
12404
12405    @Override
12406    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12407        final long origId = Binder.clearCallingIdentity();
12408        try {
12409            synchronized (this) {
12410                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12411                if (r == null) {
12412                    return false;
12413                }
12414                int index = r.task.mActivities.lastIndexOf(r);
12415                if (index > 0) {
12416                    ActivityRecord under = r.task.mActivities.get(index - 1);
12417                    under.returningOptions = options;
12418                }
12419                final boolean translucentChanged = r.changeWindowTranslucency(false);
12420                if (translucentChanged) {
12421                    r.task.stack.convertActivityToTranslucent(r);
12422                }
12423                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12424                mWindowManager.setAppFullscreen(token, false);
12425                return translucentChanged;
12426            }
12427        } finally {
12428            Binder.restoreCallingIdentity(origId);
12429        }
12430    }
12431
12432    @Override
12433    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12434        final long origId = Binder.clearCallingIdentity();
12435        try {
12436            synchronized (this) {
12437                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12438                if (r != null) {
12439                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12440                }
12441            }
12442            return false;
12443        } finally {
12444            Binder.restoreCallingIdentity(origId);
12445        }
12446    }
12447
12448    @Override
12449    public boolean isBackgroundVisibleBehind(IBinder token) {
12450        final long origId = Binder.clearCallingIdentity();
12451        try {
12452            synchronized (this) {
12453                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12454                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12455                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12456                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12457                return visible;
12458            }
12459        } finally {
12460            Binder.restoreCallingIdentity(origId);
12461        }
12462    }
12463
12464    @Override
12465    public ActivityOptions getActivityOptions(IBinder token) {
12466        final long origId = Binder.clearCallingIdentity();
12467        try {
12468            synchronized (this) {
12469                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12470                if (r != null) {
12471                    final ActivityOptions activityOptions = r.pendingOptions;
12472                    r.pendingOptions = null;
12473                    return activityOptions;
12474                }
12475                return null;
12476            }
12477        } finally {
12478            Binder.restoreCallingIdentity(origId);
12479        }
12480    }
12481
12482    @Override
12483    public void setImmersive(IBinder token, boolean immersive) {
12484        synchronized(this) {
12485            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12486            if (r == null) {
12487                throw new IllegalArgumentException();
12488            }
12489            r.immersive = immersive;
12490
12491            // update associated state if we're frontmost
12492            if (r == mFocusedActivity) {
12493                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12494                applyUpdateLockStateLocked(r);
12495            }
12496        }
12497    }
12498
12499    @Override
12500    public boolean isImmersive(IBinder token) {
12501        synchronized (this) {
12502            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12503            if (r == null) {
12504                throw new IllegalArgumentException();
12505            }
12506            return r.immersive;
12507        }
12508    }
12509
12510    @Override
12511    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12512        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12513            throw new UnsupportedOperationException("VR mode not supported on this device!");
12514        }
12515
12516        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12517
12518        ActivityRecord r;
12519        synchronized (this) {
12520            r = ActivityRecord.isInStackLocked(token);
12521        }
12522
12523        if (r == null) {
12524            throw new IllegalArgumentException();
12525        }
12526
12527        int err;
12528        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12529                VrManagerInternal.NO_ERROR) {
12530            return err;
12531        }
12532
12533        synchronized(this) {
12534            r.requestedVrComponent = (enabled) ? packageName : null;
12535
12536            // Update associated state if this activity is currently focused
12537            if (r == mFocusedActivity) {
12538                applyUpdateVrModeLocked(r);
12539            }
12540            return 0;
12541        }
12542    }
12543
12544    @Override
12545    public boolean isVrModePackageEnabled(ComponentName packageName) {
12546        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12547            throw new UnsupportedOperationException("VR mode not supported on this device!");
12548        }
12549
12550        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12551
12552        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12553                VrManagerInternal.NO_ERROR;
12554    }
12555
12556    public boolean isTopActivityImmersive() {
12557        enforceNotIsolatedCaller("startActivity");
12558        synchronized (this) {
12559            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12560            return (r != null) ? r.immersive : false;
12561        }
12562    }
12563
12564    @Override
12565    public boolean isTopOfTask(IBinder token) {
12566        synchronized (this) {
12567            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12568            if (r == null) {
12569                throw new IllegalArgumentException();
12570            }
12571            return r.task.getTopActivity() == r;
12572        }
12573    }
12574
12575    public final void enterSafeMode() {
12576        synchronized(this) {
12577            // It only makes sense to do this before the system is ready
12578            // and started launching other packages.
12579            if (!mSystemReady) {
12580                try {
12581                    AppGlobals.getPackageManager().enterSafeMode();
12582                } catch (RemoteException e) {
12583                }
12584            }
12585
12586            mSafeMode = true;
12587        }
12588    }
12589
12590    public final void showSafeModeOverlay() {
12591        View v = LayoutInflater.from(mContext).inflate(
12592                com.android.internal.R.layout.safe_mode, null);
12593        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12594        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12595        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12596        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12597        lp.gravity = Gravity.BOTTOM | Gravity.START;
12598        lp.format = v.getBackground().getOpacity();
12599        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12600                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12601        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12602        ((WindowManager)mContext.getSystemService(
12603                Context.WINDOW_SERVICE)).addView(v, lp);
12604    }
12605
12606    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12607        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12608            return;
12609        }
12610        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12611        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12612        synchronized (stats) {
12613            if (mBatteryStatsService.isOnBattery()) {
12614                mBatteryStatsService.enforceCallingPermission();
12615                int MY_UID = Binder.getCallingUid();
12616                final int uid;
12617                if (sender == null) {
12618                    uid = sourceUid;
12619                } else {
12620                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12621                }
12622                BatteryStatsImpl.Uid.Pkg pkg =
12623                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12624                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12625                pkg.noteWakeupAlarmLocked(tag);
12626            }
12627        }
12628    }
12629
12630    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12631        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12632            return;
12633        }
12634        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12635        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12636        synchronized (stats) {
12637            mBatteryStatsService.enforceCallingPermission();
12638            int MY_UID = Binder.getCallingUid();
12639            final int uid;
12640            if (sender == null) {
12641                uid = sourceUid;
12642            } else {
12643                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12644            }
12645            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12646        }
12647    }
12648
12649    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12650        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12651            return;
12652        }
12653        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12654        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12655        synchronized (stats) {
12656            mBatteryStatsService.enforceCallingPermission();
12657            int MY_UID = Binder.getCallingUid();
12658            final int uid;
12659            if (sender == null) {
12660                uid = sourceUid;
12661            } else {
12662                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12663            }
12664            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12665        }
12666    }
12667
12668    public boolean killPids(int[] pids, String pReason, boolean secure) {
12669        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12670            throw new SecurityException("killPids only available to the system");
12671        }
12672        String reason = (pReason == null) ? "Unknown" : pReason;
12673        // XXX Note: don't acquire main activity lock here, because the window
12674        // manager calls in with its locks held.
12675
12676        boolean killed = false;
12677        synchronized (mPidsSelfLocked) {
12678            int worstType = 0;
12679            for (int i=0; i<pids.length; i++) {
12680                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12681                if (proc != null) {
12682                    int type = proc.setAdj;
12683                    if (type > worstType) {
12684                        worstType = type;
12685                    }
12686                }
12687            }
12688
12689            // If the worst oom_adj is somewhere in the cached proc LRU range,
12690            // then constrain it so we will kill all cached procs.
12691            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12692                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12693                worstType = ProcessList.CACHED_APP_MIN_ADJ;
12694            }
12695
12696            // If this is not a secure call, don't let it kill processes that
12697            // are important.
12698            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12699                worstType = ProcessList.SERVICE_ADJ;
12700            }
12701
12702            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12703            for (int i=0; i<pids.length; i++) {
12704                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12705                if (proc == null) {
12706                    continue;
12707                }
12708                int adj = proc.setAdj;
12709                if (adj >= worstType && !proc.killedByAm) {
12710                    proc.kill(reason, true);
12711                    killed = true;
12712                }
12713            }
12714        }
12715        return killed;
12716    }
12717
12718    @Override
12719    public void killUid(int appId, int userId, String reason) {
12720        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12721        synchronized (this) {
12722            final long identity = Binder.clearCallingIdentity();
12723            try {
12724                killPackageProcessesLocked(null, appId, userId,
12725                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12726                        reason != null ? reason : "kill uid");
12727            } finally {
12728                Binder.restoreCallingIdentity(identity);
12729            }
12730        }
12731    }
12732
12733    @Override
12734    public boolean killProcessesBelowForeground(String reason) {
12735        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12736            throw new SecurityException("killProcessesBelowForeground() only available to system");
12737        }
12738
12739        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12740    }
12741
12742    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12743        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12744            throw new SecurityException("killProcessesBelowAdj() only available to system");
12745        }
12746
12747        boolean killed = false;
12748        synchronized (mPidsSelfLocked) {
12749            final int size = mPidsSelfLocked.size();
12750            for (int i = 0; i < size; i++) {
12751                final int pid = mPidsSelfLocked.keyAt(i);
12752                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12753                if (proc == null) continue;
12754
12755                final int adj = proc.setAdj;
12756                if (adj > belowAdj && !proc.killedByAm) {
12757                    proc.kill(reason, true);
12758                    killed = true;
12759                }
12760            }
12761        }
12762        return killed;
12763    }
12764
12765    @Override
12766    public void hang(final IBinder who, boolean allowRestart) {
12767        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12768                != PackageManager.PERMISSION_GRANTED) {
12769            throw new SecurityException("Requires permission "
12770                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12771        }
12772
12773        final IBinder.DeathRecipient death = new DeathRecipient() {
12774            @Override
12775            public void binderDied() {
12776                synchronized (this) {
12777                    notifyAll();
12778                }
12779            }
12780        };
12781
12782        try {
12783            who.linkToDeath(death, 0);
12784        } catch (RemoteException e) {
12785            Slog.w(TAG, "hang: given caller IBinder is already dead.");
12786            return;
12787        }
12788
12789        synchronized (this) {
12790            Watchdog.getInstance().setAllowRestart(allowRestart);
12791            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12792            synchronized (death) {
12793                while (who.isBinderAlive()) {
12794                    try {
12795                        death.wait();
12796                    } catch (InterruptedException e) {
12797                    }
12798                }
12799            }
12800            Watchdog.getInstance().setAllowRestart(true);
12801        }
12802    }
12803
12804    @Override
12805    public void restart() {
12806        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12807                != PackageManager.PERMISSION_GRANTED) {
12808            throw new SecurityException("Requires permission "
12809                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12810        }
12811
12812        Log.i(TAG, "Sending shutdown broadcast...");
12813
12814        BroadcastReceiver br = new BroadcastReceiver() {
12815            @Override public void onReceive(Context context, Intent intent) {
12816                // Now the broadcast is done, finish up the low-level shutdown.
12817                Log.i(TAG, "Shutting down activity manager...");
12818                shutdown(10000);
12819                Log.i(TAG, "Shutdown complete, restarting!");
12820                Process.killProcess(Process.myPid());
12821                System.exit(10);
12822            }
12823        };
12824
12825        // First send the high-level shut down broadcast.
12826        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12827        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12828        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12829        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12830        mContext.sendOrderedBroadcastAsUser(intent,
12831                UserHandle.ALL, null, br, mHandler, 0, null, null);
12832        */
12833        br.onReceive(mContext, intent);
12834    }
12835
12836    private long getLowRamTimeSinceIdle(long now) {
12837        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12838    }
12839
12840    @Override
12841    public void performIdleMaintenance() {
12842        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12843                != PackageManager.PERMISSION_GRANTED) {
12844            throw new SecurityException("Requires permission "
12845                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12846        }
12847
12848        synchronized (this) {
12849            final long now = SystemClock.uptimeMillis();
12850            final long timeSinceLastIdle = now - mLastIdleTime;
12851            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12852            mLastIdleTime = now;
12853            mLowRamTimeSinceLastIdle = 0;
12854            if (mLowRamStartTime != 0) {
12855                mLowRamStartTime = now;
12856            }
12857
12858            StringBuilder sb = new StringBuilder(128);
12859            sb.append("Idle maintenance over ");
12860            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12861            sb.append(" low RAM for ");
12862            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12863            Slog.i(TAG, sb.toString());
12864
12865            // If at least 1/3 of our time since the last idle period has been spent
12866            // with RAM low, then we want to kill processes.
12867            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12868
12869            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12870                ProcessRecord proc = mLruProcesses.get(i);
12871                if (proc.notCachedSinceIdle) {
12872                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12873                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12874                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12875                        if (doKilling && proc.initialIdlePss != 0
12876                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12877                            sb = new StringBuilder(128);
12878                            sb.append("Kill");
12879                            sb.append(proc.processName);
12880                            sb.append(" in idle maint: pss=");
12881                            sb.append(proc.lastPss);
12882                            sb.append(", swapPss=");
12883                            sb.append(proc.lastSwapPss);
12884                            sb.append(", initialPss=");
12885                            sb.append(proc.initialIdlePss);
12886                            sb.append(", period=");
12887                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
12888                            sb.append(", lowRamPeriod=");
12889                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12890                            Slog.wtfQuiet(TAG, sb.toString());
12891                            proc.kill("idle maint (pss " + proc.lastPss
12892                                    + " from " + proc.initialIdlePss + ")", true);
12893                        }
12894                    }
12895                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12896                        && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12897                    proc.notCachedSinceIdle = true;
12898                    proc.initialIdlePss = 0;
12899                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12900                            mTestPssMode, isSleepingLocked(), now);
12901                }
12902            }
12903
12904            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12905            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12906        }
12907    }
12908
12909    @Override
12910    public void sendIdleJobTrigger() {
12911        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12912                != PackageManager.PERMISSION_GRANTED) {
12913            throw new SecurityException("Requires permission "
12914                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12915        }
12916
12917        final long ident = Binder.clearCallingIdentity();
12918        try {
12919            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12920                    .setPackage("android")
12921                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12922            broadcastIntent(null, intent, null, null, 0, null, null, null,
12923                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12924        } finally {
12925            Binder.restoreCallingIdentity(ident);
12926        }
12927    }
12928
12929    private void retrieveSettings() {
12930        final ContentResolver resolver = mContext.getContentResolver();
12931        final boolean freeformWindowManagement =
12932                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12933                        || Settings.Global.getInt(
12934                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12935        final boolean supportsPictureInPicture =
12936                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12937
12938        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12939        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12940        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12941        final boolean alwaysFinishActivities =
12942                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12943        final boolean lenientBackgroundCheck =
12944                Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12945        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12946        final boolean forceResizable = Settings.Global.getInt(
12947                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12948        final boolean supportsLeanbackOnly =
12949                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12950
12951        // Transfer any global setting for forcing RTL layout, into a System Property
12952        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12953
12954        final Configuration configuration = new Configuration();
12955        Settings.System.getConfiguration(resolver, configuration);
12956        if (forceRtl) {
12957            // This will take care of setting the correct layout direction flags
12958            configuration.setLayoutDirection(configuration.locale);
12959        }
12960
12961        synchronized (this) {
12962            mDebugApp = mOrigDebugApp = debugApp;
12963            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12964            mAlwaysFinishActivities = alwaysFinishActivities;
12965            mLenientBackgroundCheck = lenientBackgroundCheck;
12966            mSupportsLeanbackOnly = supportsLeanbackOnly;
12967            mForceResizableActivities = forceResizable;
12968            mWindowManager.setForceResizableTasks(mForceResizableActivities);
12969            if (supportsMultiWindow || forceResizable) {
12970                mSupportsMultiWindow = true;
12971                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12972                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12973            } else {
12974                mSupportsMultiWindow = false;
12975                mSupportsFreeformWindowManagement = false;
12976                mSupportsPictureInPicture = false;
12977            }
12978            // This happens before any activities are started, so we can
12979            // change mConfiguration in-place.
12980            updateConfigurationLocked(configuration, null, true);
12981            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12982                    "Initial config: " + mConfiguration);
12983
12984            // Load resources only after the current configuration has been set.
12985            final Resources res = mContext.getResources();
12986            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12987            mThumbnailWidth = res.getDimensionPixelSize(
12988                    com.android.internal.R.dimen.thumbnail_width);
12989            mThumbnailHeight = res.getDimensionPixelSize(
12990                    com.android.internal.R.dimen.thumbnail_height);
12991            mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12992                    com.android.internal.R.string.config_defaultPictureInPictureBounds));
12993            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12994                    com.android.internal.R.string.config_appsNotReportingCrashes));
12995            if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12996                mFullscreenThumbnailScale = (float) res
12997                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12998                    (float) mConfiguration.screenWidthDp;
12999            } else {
13000                mFullscreenThumbnailScale = res.getFraction(
13001                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13002            }
13003        }
13004    }
13005
13006    public boolean testIsSystemReady() {
13007        // no need to synchronize(this) just to read & return the value
13008        return mSystemReady;
13009    }
13010
13011    public void systemReady(final Runnable goingCallback) {
13012        synchronized(this) {
13013            if (mSystemReady) {
13014                // If we're done calling all the receivers, run the next "boot phase" passed in
13015                // by the SystemServer
13016                if (goingCallback != null) {
13017                    goingCallback.run();
13018                }
13019                return;
13020            }
13021
13022            mLocalDeviceIdleController
13023                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13024
13025            // Make sure we have the current profile info, since it is needed for security checks.
13026            mUserController.onSystemReady();
13027            mRecentTasks.onSystemReadyLocked();
13028            mAppOpsService.systemReady();
13029            mSystemReady = true;
13030        }
13031
13032        ArrayList<ProcessRecord> procsToKill = null;
13033        synchronized(mPidsSelfLocked) {
13034            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13035                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13036                if (!isAllowedWhileBooting(proc.info)){
13037                    if (procsToKill == null) {
13038                        procsToKill = new ArrayList<ProcessRecord>();
13039                    }
13040                    procsToKill.add(proc);
13041                }
13042            }
13043        }
13044
13045        synchronized(this) {
13046            if (procsToKill != null) {
13047                for (int i=procsToKill.size()-1; i>=0; i--) {
13048                    ProcessRecord proc = procsToKill.get(i);
13049                    Slog.i(TAG, "Removing system update proc: " + proc);
13050                    removeProcessLocked(proc, true, false, "system update done");
13051                }
13052            }
13053
13054            // Now that we have cleaned up any update processes, we
13055            // are ready to start launching real processes and know that
13056            // we won't trample on them any more.
13057            mProcessesReady = true;
13058        }
13059
13060        Slog.i(TAG, "System now ready");
13061        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13062            SystemClock.uptimeMillis());
13063
13064        synchronized(this) {
13065            // Make sure we have no pre-ready processes sitting around.
13066
13067            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13068                ResolveInfo ri = mContext.getPackageManager()
13069                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13070                                STOCK_PM_FLAGS);
13071                CharSequence errorMsg = null;
13072                if (ri != null) {
13073                    ActivityInfo ai = ri.activityInfo;
13074                    ApplicationInfo app = ai.applicationInfo;
13075                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13076                        mTopAction = Intent.ACTION_FACTORY_TEST;
13077                        mTopData = null;
13078                        mTopComponent = new ComponentName(app.packageName,
13079                                ai.name);
13080                    } else {
13081                        errorMsg = mContext.getResources().getText(
13082                                com.android.internal.R.string.factorytest_not_system);
13083                    }
13084                } else {
13085                    errorMsg = mContext.getResources().getText(
13086                            com.android.internal.R.string.factorytest_no_action);
13087                }
13088                if (errorMsg != null) {
13089                    mTopAction = null;
13090                    mTopData = null;
13091                    mTopComponent = null;
13092                    Message msg = Message.obtain();
13093                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13094                    msg.getData().putCharSequence("msg", errorMsg);
13095                    mUiHandler.sendMessage(msg);
13096                }
13097            }
13098        }
13099
13100        retrieveSettings();
13101        final int currentUserId;
13102        synchronized (this) {
13103            currentUserId = mUserController.getCurrentUserIdLocked();
13104            readGrantedUriPermissionsLocked();
13105        }
13106
13107        if (goingCallback != null) goingCallback.run();
13108
13109        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13110                Integer.toString(currentUserId), currentUserId);
13111        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13112                Integer.toString(currentUserId), currentUserId);
13113        mSystemServiceManager.startUser(currentUserId);
13114
13115        synchronized (this) {
13116            // Only start up encryption-aware persistent apps; once user is
13117            // unlocked we'll come back around and start unaware apps
13118            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13119
13120            // Start up initial activity.
13121            mBooting = true;
13122            // Enable home activity for system user, so that the system can always boot. We don't
13123            // do this when the system user is not setup since the setup wizard should be the one
13124            // to handle home activity in this case.
13125            if (UserManager.isSplitSystemUser() &&
13126                    Settings.Secure.getInt(mContext.getContentResolver(),
13127                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
13128                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13129                try {
13130                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13131                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13132                            UserHandle.USER_SYSTEM);
13133                } catch (RemoteException e) {
13134                    throw e.rethrowAsRuntimeException();
13135                }
13136            }
13137            startHomeActivityLocked(currentUserId, "systemReady");
13138
13139            try {
13140                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13141                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13142                            + " data partition or your device will be unstable.");
13143                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13144                }
13145            } catch (RemoteException e) {
13146            }
13147
13148            if (!Build.isBuildConsistent()) {
13149                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13150                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13151            }
13152
13153            long ident = Binder.clearCallingIdentity();
13154            try {
13155                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13156                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13157                        | Intent.FLAG_RECEIVER_FOREGROUND);
13158                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13159                broadcastIntentLocked(null, null, intent,
13160                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13161                        null, false, false, MY_PID, Process.SYSTEM_UID,
13162                        currentUserId);
13163                intent = new Intent(Intent.ACTION_USER_STARTING);
13164                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13165                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13166                broadcastIntentLocked(null, null, intent,
13167                        null, new IIntentReceiver.Stub() {
13168                            @Override
13169                            public void performReceive(Intent intent, int resultCode, String data,
13170                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13171                                    throws RemoteException {
13172                            }
13173                        }, 0, null, null,
13174                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13175                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13176            } catch (Throwable t) {
13177                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13178            } finally {
13179                Binder.restoreCallingIdentity(ident);
13180            }
13181            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13182            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13183        }
13184    }
13185
13186    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13187        synchronized (this) {
13188            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13189        }
13190    }
13191
13192    void skipCurrentReceiverLocked(ProcessRecord app) {
13193        for (BroadcastQueue queue : mBroadcastQueues) {
13194            queue.skipCurrentReceiverLocked(app);
13195        }
13196    }
13197
13198    /**
13199     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13200     * The application process will exit immediately after this call returns.
13201     * @param app object of the crashing app, null for the system server
13202     * @param crashInfo describing the exception
13203     */
13204    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13205        ProcessRecord r = findAppProcess(app, "Crash");
13206        final String processName = app == null ? "system_server"
13207                : (r == null ? "unknown" : r.processName);
13208
13209        handleApplicationCrashInner("crash", r, processName, crashInfo);
13210    }
13211
13212    /* Native crash reporting uses this inner version because it needs to be somewhat
13213     * decoupled from the AM-managed cleanup lifecycle
13214     */
13215    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13216            ApplicationErrorReport.CrashInfo crashInfo) {
13217        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13218                UserHandle.getUserId(Binder.getCallingUid()), processName,
13219                r == null ? -1 : r.info.flags,
13220                crashInfo.exceptionClassName,
13221                crashInfo.exceptionMessage,
13222                crashInfo.throwFileName,
13223                crashInfo.throwLineNumber);
13224
13225        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13226
13227        mAppErrors.crashApplication(r, crashInfo);
13228    }
13229
13230    public void handleApplicationStrictModeViolation(
13231            IBinder app,
13232            int violationMask,
13233            StrictMode.ViolationInfo info) {
13234        ProcessRecord r = findAppProcess(app, "StrictMode");
13235        if (r == null) {
13236            return;
13237        }
13238
13239        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13240            Integer stackFingerprint = info.hashCode();
13241            boolean logIt = true;
13242            synchronized (mAlreadyLoggedViolatedStacks) {
13243                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13244                    logIt = false;
13245                    // TODO: sub-sample into EventLog for these, with
13246                    // the info.durationMillis?  Then we'd get
13247                    // the relative pain numbers, without logging all
13248                    // the stack traces repeatedly.  We'd want to do
13249                    // likewise in the client code, which also does
13250                    // dup suppression, before the Binder call.
13251                } else {
13252                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13253                        mAlreadyLoggedViolatedStacks.clear();
13254                    }
13255                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13256                }
13257            }
13258            if (logIt) {
13259                logStrictModeViolationToDropBox(r, info);
13260            }
13261        }
13262
13263        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13264            AppErrorResult result = new AppErrorResult();
13265            synchronized (this) {
13266                final long origId = Binder.clearCallingIdentity();
13267
13268                Message msg = Message.obtain();
13269                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13270                HashMap<String, Object> data = new HashMap<String, Object>();
13271                data.put("result", result);
13272                data.put("app", r);
13273                data.put("violationMask", violationMask);
13274                data.put("info", info);
13275                msg.obj = data;
13276                mUiHandler.sendMessage(msg);
13277
13278                Binder.restoreCallingIdentity(origId);
13279            }
13280            int res = result.get();
13281            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13282        }
13283    }
13284
13285    // Depending on the policy in effect, there could be a bunch of
13286    // these in quick succession so we try to batch these together to
13287    // minimize disk writes, number of dropbox entries, and maximize
13288    // compression, by having more fewer, larger records.
13289    private void logStrictModeViolationToDropBox(
13290            ProcessRecord process,
13291            StrictMode.ViolationInfo info) {
13292        if (info == null) {
13293            return;
13294        }
13295        final boolean isSystemApp = process == null ||
13296                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13297                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13298        final String processName = process == null ? "unknown" : process.processName;
13299        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13300        final DropBoxManager dbox = (DropBoxManager)
13301                mContext.getSystemService(Context.DROPBOX_SERVICE);
13302
13303        // Exit early if the dropbox isn't configured to accept this report type.
13304        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13305
13306        boolean bufferWasEmpty;
13307        boolean needsFlush;
13308        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13309        synchronized (sb) {
13310            bufferWasEmpty = sb.length() == 0;
13311            appendDropBoxProcessHeaders(process, processName, sb);
13312            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13313            sb.append("System-App: ").append(isSystemApp).append("\n");
13314            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13315            if (info.violationNumThisLoop != 0) {
13316                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13317            }
13318            if (info.numAnimationsRunning != 0) {
13319                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13320            }
13321            if (info.broadcastIntentAction != null) {
13322                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13323            }
13324            if (info.durationMillis != -1) {
13325                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13326            }
13327            if (info.numInstances != -1) {
13328                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13329            }
13330            if (info.tags != null) {
13331                for (String tag : info.tags) {
13332                    sb.append("Span-Tag: ").append(tag).append("\n");
13333                }
13334            }
13335            sb.append("\n");
13336            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13337                sb.append(info.crashInfo.stackTrace);
13338                sb.append("\n");
13339            }
13340            if (info.message != null) {
13341                sb.append(info.message);
13342                sb.append("\n");
13343            }
13344
13345            // Only buffer up to ~64k.  Various logging bits truncate
13346            // things at 128k.
13347            needsFlush = (sb.length() > 64 * 1024);
13348        }
13349
13350        // Flush immediately if the buffer's grown too large, or this
13351        // is a non-system app.  Non-system apps are isolated with a
13352        // different tag & policy and not batched.
13353        //
13354        // Batching is useful during internal testing with
13355        // StrictMode settings turned up high.  Without batching,
13356        // thousands of separate files could be created on boot.
13357        if (!isSystemApp || needsFlush) {
13358            new Thread("Error dump: " + dropboxTag) {
13359                @Override
13360                public void run() {
13361                    String report;
13362                    synchronized (sb) {
13363                        report = sb.toString();
13364                        sb.delete(0, sb.length());
13365                        sb.trimToSize();
13366                    }
13367                    if (report.length() != 0) {
13368                        dbox.addText(dropboxTag, report);
13369                    }
13370                }
13371            }.start();
13372            return;
13373        }
13374
13375        // System app batching:
13376        if (!bufferWasEmpty) {
13377            // An existing dropbox-writing thread is outstanding, so
13378            // we don't need to start it up.  The existing thread will
13379            // catch the buffer appends we just did.
13380            return;
13381        }
13382
13383        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13384        // (After this point, we shouldn't access AMS internal data structures.)
13385        new Thread("Error dump: " + dropboxTag) {
13386            @Override
13387            public void run() {
13388                // 5 second sleep to let stacks arrive and be batched together
13389                try {
13390                    Thread.sleep(5000);  // 5 seconds
13391                } catch (InterruptedException e) {}
13392
13393                String errorReport;
13394                synchronized (mStrictModeBuffer) {
13395                    errorReport = mStrictModeBuffer.toString();
13396                    if (errorReport.length() == 0) {
13397                        return;
13398                    }
13399                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13400                    mStrictModeBuffer.trimToSize();
13401                }
13402                dbox.addText(dropboxTag, errorReport);
13403            }
13404        }.start();
13405    }
13406
13407    /**
13408     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13409     * @param app object of the crashing app, null for the system server
13410     * @param tag reported by the caller
13411     * @param system whether this wtf is coming from the system
13412     * @param crashInfo describing the context of the error
13413     * @return true if the process should exit immediately (WTF is fatal)
13414     */
13415    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13416            final ApplicationErrorReport.CrashInfo crashInfo) {
13417        final int callingUid = Binder.getCallingUid();
13418        final int callingPid = Binder.getCallingPid();
13419
13420        if (system) {
13421            // If this is coming from the system, we could very well have low-level
13422            // system locks held, so we want to do this all asynchronously.  And we
13423            // never want this to become fatal, so there is that too.
13424            mHandler.post(new Runnable() {
13425                @Override public void run() {
13426                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13427                }
13428            });
13429            return false;
13430        }
13431
13432        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13433                crashInfo);
13434
13435        if (r != null && r.pid != Process.myPid() &&
13436                Settings.Global.getInt(mContext.getContentResolver(),
13437                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
13438            mAppErrors.crashApplication(r, crashInfo);
13439            return true;
13440        } else {
13441            return false;
13442        }
13443    }
13444
13445    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13446            final ApplicationErrorReport.CrashInfo crashInfo) {
13447        final ProcessRecord r = findAppProcess(app, "WTF");
13448        final String processName = app == null ? "system_server"
13449                : (r == null ? "unknown" : r.processName);
13450
13451        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13452                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13453
13454        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13455
13456        return r;
13457    }
13458
13459    /**
13460     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13461     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13462     */
13463    private ProcessRecord findAppProcess(IBinder app, String reason) {
13464        if (app == null) {
13465            return null;
13466        }
13467
13468        synchronized (this) {
13469            final int NP = mProcessNames.getMap().size();
13470            for (int ip=0; ip<NP; ip++) {
13471                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13472                final int NA = apps.size();
13473                for (int ia=0; ia<NA; ia++) {
13474                    ProcessRecord p = apps.valueAt(ia);
13475                    if (p.thread != null && p.thread.asBinder() == app) {
13476                        return p;
13477                    }
13478                }
13479            }
13480
13481            Slog.w(TAG, "Can't find mystery application for " + reason
13482                    + " from pid=" + Binder.getCallingPid()
13483                    + " uid=" + Binder.getCallingUid() + ": " + app);
13484            return null;
13485        }
13486    }
13487
13488    /**
13489     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13490     * to append various headers to the dropbox log text.
13491     */
13492    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13493            StringBuilder sb) {
13494        // Watchdog thread ends up invoking this function (with
13495        // a null ProcessRecord) to add the stack file to dropbox.
13496        // Do not acquire a lock on this (am) in such cases, as it
13497        // could cause a potential deadlock, if and when watchdog
13498        // is invoked due to unavailability of lock on am and it
13499        // would prevent watchdog from killing system_server.
13500        if (process == null) {
13501            sb.append("Process: ").append(processName).append("\n");
13502            return;
13503        }
13504        // Note: ProcessRecord 'process' is guarded by the service
13505        // instance.  (notably process.pkgList, which could otherwise change
13506        // concurrently during execution of this method)
13507        synchronized (this) {
13508            sb.append("Process: ").append(processName).append("\n");
13509            int flags = process.info.flags;
13510            IPackageManager pm = AppGlobals.getPackageManager();
13511            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13512            for (int ip=0; ip<process.pkgList.size(); ip++) {
13513                String pkg = process.pkgList.keyAt(ip);
13514                sb.append("Package: ").append(pkg);
13515                try {
13516                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13517                    if (pi != null) {
13518                        sb.append(" v").append(pi.versionCode);
13519                        if (pi.versionName != null) {
13520                            sb.append(" (").append(pi.versionName).append(")");
13521                        }
13522                    }
13523                } catch (RemoteException e) {
13524                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13525                }
13526                sb.append("\n");
13527            }
13528        }
13529    }
13530
13531    private static String processClass(ProcessRecord process) {
13532        if (process == null || process.pid == MY_PID) {
13533            return "system_server";
13534        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13535            return "system_app";
13536        } else {
13537            return "data_app";
13538        }
13539    }
13540
13541    private volatile long mWtfClusterStart;
13542    private volatile int mWtfClusterCount;
13543
13544    /**
13545     * Write a description of an error (crash, WTF, ANR) to the drop box.
13546     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13547     * @param process which caused the error, null means the system server
13548     * @param activity which triggered the error, null if unknown
13549     * @param parent activity related to the error, null if unknown
13550     * @param subject line related to the error, null if absent
13551     * @param report in long form describing the error, null if absent
13552     * @param dataFile text file to include in the report, null if none
13553     * @param crashInfo giving an application stack trace, null if absent
13554     */
13555    public void addErrorToDropBox(String eventType,
13556            ProcessRecord process, String processName, ActivityRecord activity,
13557            ActivityRecord parent, String subject,
13558            final String report, final File dataFile,
13559            final ApplicationErrorReport.CrashInfo crashInfo) {
13560        // NOTE -- this must never acquire the ActivityManagerService lock,
13561        // otherwise the watchdog may be prevented from resetting the system.
13562
13563        final String dropboxTag = processClass(process) + "_" + eventType;
13564        final DropBoxManager dbox = (DropBoxManager)
13565                mContext.getSystemService(Context.DROPBOX_SERVICE);
13566
13567        // Exit early if the dropbox isn't configured to accept this report type.
13568        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13569
13570        // Rate-limit how often we're willing to do the heavy lifting below to
13571        // collect and record logs; currently 5 logs per 10 second period.
13572        final long now = SystemClock.elapsedRealtime();
13573        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13574            mWtfClusterStart = now;
13575            mWtfClusterCount = 1;
13576        } else {
13577            if (mWtfClusterCount++ >= 5) return;
13578        }
13579
13580        final StringBuilder sb = new StringBuilder(1024);
13581        appendDropBoxProcessHeaders(process, processName, sb);
13582        if (process != null) {
13583            sb.append("Foreground: ")
13584                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13585                    .append("\n");
13586        }
13587        if (activity != null) {
13588            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13589        }
13590        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13591            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13592        }
13593        if (parent != null && parent != activity) {
13594            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13595        }
13596        if (subject != null) {
13597            sb.append("Subject: ").append(subject).append("\n");
13598        }
13599        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13600        if (Debug.isDebuggerConnected()) {
13601            sb.append("Debugger: Connected\n");
13602        }
13603        sb.append("\n");
13604
13605        // Do the rest in a worker thread to avoid blocking the caller on I/O
13606        // (After this point, we shouldn't access AMS internal data structures.)
13607        Thread worker = new Thread("Error dump: " + dropboxTag) {
13608            @Override
13609            public void run() {
13610                if (report != null) {
13611                    sb.append(report);
13612                }
13613
13614                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13615                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13616                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13617                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13618
13619                if (dataFile != null && maxDataFileSize > 0) {
13620                    try {
13621                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13622                                    "\n\n[[TRUNCATED]]"));
13623                    } catch (IOException e) {
13624                        Slog.e(TAG, "Error reading " + dataFile, e);
13625                    }
13626                }
13627                if (crashInfo != null && crashInfo.stackTrace != null) {
13628                    sb.append(crashInfo.stackTrace);
13629                }
13630
13631                if (lines > 0) {
13632                    sb.append("\n");
13633
13634                    // Merge several logcat streams, and take the last N lines
13635                    InputStreamReader input = null;
13636                    try {
13637                        java.lang.Process logcat = new ProcessBuilder(
13638                                "/system/bin/timeout", "-k", "15s", "10s",
13639                                "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13640                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13641                                        .redirectErrorStream(true).start();
13642
13643                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13644                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13645                        input = new InputStreamReader(logcat.getInputStream());
13646
13647                        int num;
13648                        char[] buf = new char[8192];
13649                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13650                    } catch (IOException e) {
13651                        Slog.e(TAG, "Error running logcat", e);
13652                    } finally {
13653                        if (input != null) try { input.close(); } catch (IOException e) {}
13654                    }
13655                }
13656
13657                dbox.addText(dropboxTag, sb.toString());
13658            }
13659        };
13660
13661        if (process == null) {
13662            // If process is null, we are being called from some internal code
13663            // and may be about to die -- run this synchronously.
13664            worker.run();
13665        } else {
13666            worker.start();
13667        }
13668    }
13669
13670    @Override
13671    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13672        enforceNotIsolatedCaller("getProcessesInErrorState");
13673        // assume our apps are happy - lazy create the list
13674        List<ActivityManager.ProcessErrorStateInfo> errList = null;
13675
13676        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13677                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13678        int userId = UserHandle.getUserId(Binder.getCallingUid());
13679
13680        synchronized (this) {
13681
13682            // iterate across all processes
13683            for (int i=mLruProcesses.size()-1; i>=0; i--) {
13684                ProcessRecord app = mLruProcesses.get(i);
13685                if (!allUsers && app.userId != userId) {
13686                    continue;
13687                }
13688                if ((app.thread != null) && (app.crashing || app.notResponding)) {
13689                    // This one's in trouble, so we'll generate a report for it
13690                    // crashes are higher priority (in case there's a crash *and* an anr)
13691                    ActivityManager.ProcessErrorStateInfo report = null;
13692                    if (app.crashing) {
13693                        report = app.crashingReport;
13694                    } else if (app.notResponding) {
13695                        report = app.notRespondingReport;
13696                    }
13697
13698                    if (report != null) {
13699                        if (errList == null) {
13700                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13701                        }
13702                        errList.add(report);
13703                    } else {
13704                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
13705                                " crashing = " + app.crashing +
13706                                " notResponding = " + app.notResponding);
13707                    }
13708                }
13709            }
13710        }
13711
13712        return errList;
13713    }
13714
13715    static int procStateToImportance(int procState, int memAdj,
13716            ActivityManager.RunningAppProcessInfo currApp) {
13717        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13718        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13719            currApp.lru = memAdj;
13720        } else {
13721            currApp.lru = 0;
13722        }
13723        return imp;
13724    }
13725
13726    private void fillInProcMemInfo(ProcessRecord app,
13727            ActivityManager.RunningAppProcessInfo outInfo) {
13728        outInfo.pid = app.pid;
13729        outInfo.uid = app.info.uid;
13730        if (mHeavyWeightProcess == app) {
13731            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13732        }
13733        if (app.persistent) {
13734            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13735        }
13736        if (app.activities.size() > 0) {
13737            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13738        }
13739        outInfo.lastTrimLevel = app.trimMemoryLevel;
13740        int adj = app.curAdj;
13741        int procState = app.curProcState;
13742        outInfo.importance = procStateToImportance(procState, adj, outInfo);
13743        outInfo.importanceReasonCode = app.adjTypeCode;
13744        outInfo.processState = app.curProcState;
13745    }
13746
13747    @Override
13748    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13749        enforceNotIsolatedCaller("getRunningAppProcesses");
13750
13751        final int callingUid = Binder.getCallingUid();
13752
13753        // Lazy instantiation of list
13754        List<ActivityManager.RunningAppProcessInfo> runList = null;
13755        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13756                callingUid) == PackageManager.PERMISSION_GRANTED;
13757        final int userId = UserHandle.getUserId(callingUid);
13758        final boolean allUids = isGetTasksAllowed(
13759                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13760
13761        synchronized (this) {
13762            // Iterate across all processes
13763            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13764                ProcessRecord app = mLruProcesses.get(i);
13765                if ((!allUsers && app.userId != userId)
13766                        || (!allUids && app.uid != callingUid)) {
13767                    continue;
13768                }
13769                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13770                    // Generate process state info for running application
13771                    ActivityManager.RunningAppProcessInfo currApp =
13772                        new ActivityManager.RunningAppProcessInfo(app.processName,
13773                                app.pid, app.getPackageList());
13774                    fillInProcMemInfo(app, currApp);
13775                    if (app.adjSource instanceof ProcessRecord) {
13776                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13777                        currApp.importanceReasonImportance =
13778                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
13779                                        app.adjSourceProcState);
13780                    } else if (app.adjSource instanceof ActivityRecord) {
13781                        ActivityRecord r = (ActivityRecord)app.adjSource;
13782                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13783                    }
13784                    if (app.adjTarget instanceof ComponentName) {
13785                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13786                    }
13787                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13788                    //        + " lru=" + currApp.lru);
13789                    if (runList == null) {
13790                        runList = new ArrayList<>();
13791                    }
13792                    runList.add(currApp);
13793                }
13794            }
13795        }
13796        return runList;
13797    }
13798
13799    @Override
13800    public List<ApplicationInfo> getRunningExternalApplications() {
13801        enforceNotIsolatedCaller("getRunningExternalApplications");
13802        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13803        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13804        if (runningApps != null && runningApps.size() > 0) {
13805            Set<String> extList = new HashSet<String>();
13806            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13807                if (app.pkgList != null) {
13808                    for (String pkg : app.pkgList) {
13809                        extList.add(pkg);
13810                    }
13811                }
13812            }
13813            IPackageManager pm = AppGlobals.getPackageManager();
13814            for (String pkg : extList) {
13815                try {
13816                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13817                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13818                        retList.add(info);
13819                    }
13820                } catch (RemoteException e) {
13821                }
13822            }
13823        }
13824        return retList;
13825    }
13826
13827    @Override
13828    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13829        enforceNotIsolatedCaller("getMyMemoryState");
13830        synchronized (this) {
13831            ProcessRecord proc;
13832            synchronized (mPidsSelfLocked) {
13833                proc = mPidsSelfLocked.get(Binder.getCallingPid());
13834            }
13835            fillInProcMemInfo(proc, outInfo);
13836        }
13837    }
13838
13839    @Override
13840    public int getMemoryTrimLevel() {
13841        enforceNotIsolatedCaller("getMyMemoryState");
13842        synchronized (this) {
13843            return mLastMemoryLevel;
13844        }
13845    }
13846
13847    @Override
13848    public void onShellCommand(FileDescriptor in, FileDescriptor out,
13849            FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13850        (new ActivityManagerShellCommand(this, false)).exec(
13851                this, in, out, err, args, resultReceiver);
13852    }
13853
13854    @Override
13855    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13856        if (checkCallingPermission(android.Manifest.permission.DUMP)
13857                != PackageManager.PERMISSION_GRANTED) {
13858            pw.println("Permission Denial: can't dump ActivityManager from from pid="
13859                    + Binder.getCallingPid()
13860                    + ", uid=" + Binder.getCallingUid()
13861                    + " without permission "
13862                    + android.Manifest.permission.DUMP);
13863            return;
13864        }
13865
13866        boolean dumpAll = false;
13867        boolean dumpClient = false;
13868        boolean dumpCheckin = false;
13869        boolean dumpCheckinFormat = false;
13870        String dumpPackage = null;
13871
13872        int opti = 0;
13873        while (opti < args.length) {
13874            String opt = args[opti];
13875            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13876                break;
13877            }
13878            opti++;
13879            if ("-a".equals(opt)) {
13880                dumpAll = true;
13881            } else if ("-c".equals(opt)) {
13882                dumpClient = true;
13883            } else if ("-p".equals(opt)) {
13884                if (opti < args.length) {
13885                    dumpPackage = args[opti];
13886                    opti++;
13887                } else {
13888                    pw.println("Error: -p option requires package argument");
13889                    return;
13890                }
13891                dumpClient = true;
13892            } else if ("--checkin".equals(opt)) {
13893                dumpCheckin = dumpCheckinFormat = true;
13894            } else if ("-C".equals(opt)) {
13895                dumpCheckinFormat = true;
13896            } else if ("-h".equals(opt)) {
13897                ActivityManagerShellCommand.dumpHelp(pw, true);
13898                return;
13899            } else {
13900                pw.println("Unknown argument: " + opt + "; use -h for help");
13901            }
13902        }
13903
13904        long origId = Binder.clearCallingIdentity();
13905        boolean more = false;
13906        // Is the caller requesting to dump a particular piece of data?
13907        if (opti < args.length) {
13908            String cmd = args[opti];
13909            opti++;
13910            if ("activities".equals(cmd) || "a".equals(cmd)) {
13911                synchronized (this) {
13912                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13913                }
13914            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13915                synchronized (this) {
13916                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13917                }
13918            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13919                String[] newArgs;
13920                String name;
13921                if (opti >= args.length) {
13922                    name = null;
13923                    newArgs = EMPTY_STRING_ARRAY;
13924                } else {
13925                    dumpPackage = args[opti];
13926                    opti++;
13927                    newArgs = new String[args.length - opti];
13928                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13929                            args.length - opti);
13930                }
13931                synchronized (this) {
13932                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13933                }
13934            } else if ("broadcast-stats".equals(cmd)) {
13935                String[] newArgs;
13936                String name;
13937                if (opti >= args.length) {
13938                    name = null;
13939                    newArgs = EMPTY_STRING_ARRAY;
13940                } else {
13941                    dumpPackage = args[opti];
13942                    opti++;
13943                    newArgs = new String[args.length - opti];
13944                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13945                            args.length - opti);
13946                }
13947                synchronized (this) {
13948                    if (dumpCheckinFormat) {
13949                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
13950                                dumpPackage);
13951                    } else {
13952                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
13953                    }
13954                }
13955            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13956                String[] newArgs;
13957                String name;
13958                if (opti >= args.length) {
13959                    name = null;
13960                    newArgs = EMPTY_STRING_ARRAY;
13961                } else {
13962                    dumpPackage = args[opti];
13963                    opti++;
13964                    newArgs = new String[args.length - opti];
13965                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13966                            args.length - opti);
13967                }
13968                synchronized (this) {
13969                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13970                }
13971            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13972                String[] newArgs;
13973                String name;
13974                if (opti >= args.length) {
13975                    name = null;
13976                    newArgs = EMPTY_STRING_ARRAY;
13977                } else {
13978                    dumpPackage = args[opti];
13979                    opti++;
13980                    newArgs = new String[args.length - opti];
13981                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13982                            args.length - opti);
13983                }
13984                synchronized (this) {
13985                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13986                }
13987            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13988                synchronized (this) {
13989                    dumpOomLocked(fd, pw, args, opti, true);
13990                }
13991            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13992                synchronized (this) {
13993                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
13994                }
13995            } else if ("provider".equals(cmd)) {
13996                String[] newArgs;
13997                String name;
13998                if (opti >= args.length) {
13999                    name = null;
14000                    newArgs = EMPTY_STRING_ARRAY;
14001                } else {
14002                    name = args[opti];
14003                    opti++;
14004                    newArgs = new String[args.length - opti];
14005                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14006                }
14007                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14008                    pw.println("No providers match: " + name);
14009                    pw.println("Use -h for help.");
14010                }
14011            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14012                synchronized (this) {
14013                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14014                }
14015            } else if ("service".equals(cmd)) {
14016                String[] newArgs;
14017                String name;
14018                if (opti >= args.length) {
14019                    name = null;
14020                    newArgs = EMPTY_STRING_ARRAY;
14021                } else {
14022                    name = args[opti];
14023                    opti++;
14024                    newArgs = new String[args.length - opti];
14025                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14026                            args.length - opti);
14027                }
14028                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14029                    pw.println("No services match: " + name);
14030                    pw.println("Use -h for help.");
14031                }
14032            } else if ("package".equals(cmd)) {
14033                String[] newArgs;
14034                if (opti >= args.length) {
14035                    pw.println("package: no package name specified");
14036                    pw.println("Use -h for help.");
14037                } else {
14038                    dumpPackage = args[opti];
14039                    opti++;
14040                    newArgs = new String[args.length - opti];
14041                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14042                            args.length - opti);
14043                    args = newArgs;
14044                    opti = 0;
14045                    more = true;
14046                }
14047            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14048                synchronized (this) {
14049                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14050                }
14051            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14052                if (dumpClient) {
14053                    ActiveServices.ServiceDumper dumper;
14054                    synchronized (this) {
14055                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14056                                dumpPackage);
14057                    }
14058                    dumper.dumpWithClient();
14059                } else {
14060                    synchronized (this) {
14061                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14062                                dumpPackage).dumpLocked();
14063                    }
14064                }
14065            } else if ("locks".equals(cmd)) {
14066                LockGuard.dump(fd, pw, args);
14067            } else {
14068                // Dumping a single activity?
14069                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14070                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14071                    int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14072                    if (res < 0) {
14073                        pw.println("Bad activity command, or no activities match: " + cmd);
14074                        pw.println("Use -h for help.");
14075                    }
14076                }
14077            }
14078            if (!more) {
14079                Binder.restoreCallingIdentity(origId);
14080                return;
14081            }
14082        }
14083
14084        // No piece of data specified, dump everything.
14085        if (dumpCheckinFormat) {
14086            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14087        } else if (dumpClient) {
14088            ActiveServices.ServiceDumper sdumper;
14089            synchronized (this) {
14090                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14091                pw.println();
14092                if (dumpAll) {
14093                    pw.println("-------------------------------------------------------------------------------");
14094                }
14095                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14096                pw.println();
14097                if (dumpAll) {
14098                    pw.println("-------------------------------------------------------------------------------");
14099                }
14100                if (dumpAll || dumpPackage != null) {
14101                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14102                    pw.println();
14103                    if (dumpAll) {
14104                        pw.println("-------------------------------------------------------------------------------");
14105                    }
14106                }
14107                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14108                pw.println();
14109                if (dumpAll) {
14110                    pw.println("-------------------------------------------------------------------------------");
14111                }
14112                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14113                pw.println();
14114                if (dumpAll) {
14115                    pw.println("-------------------------------------------------------------------------------");
14116                }
14117                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14118                        dumpPackage);
14119            }
14120            sdumper.dumpWithClient();
14121            pw.println();
14122            synchronized (this) {
14123                if (dumpAll) {
14124                    pw.println("-------------------------------------------------------------------------------");
14125                }
14126                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14127                pw.println();
14128                if (dumpAll) {
14129                    pw.println("-------------------------------------------------------------------------------");
14130                }
14131                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14132                if (mAssociations.size() > 0) {
14133                    pw.println();
14134                    if (dumpAll) {
14135                        pw.println("-------------------------------------------------------------------------------");
14136                    }
14137                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14138                }
14139                pw.println();
14140                if (dumpAll) {
14141                    pw.println("-------------------------------------------------------------------------------");
14142                }
14143                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14144            }
14145
14146        } else {
14147            synchronized (this) {
14148                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14149                pw.println();
14150                if (dumpAll) {
14151                    pw.println("-------------------------------------------------------------------------------");
14152                }
14153                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14154                pw.println();
14155                if (dumpAll) {
14156                    pw.println("-------------------------------------------------------------------------------");
14157                }
14158                if (dumpAll || dumpPackage != null) {
14159                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14160                    pw.println();
14161                    if (dumpAll) {
14162                        pw.println("-------------------------------------------------------------------------------");
14163                    }
14164                }
14165                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14166                pw.println();
14167                if (dumpAll) {
14168                    pw.println("-------------------------------------------------------------------------------");
14169                }
14170                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14171                pw.println();
14172                if (dumpAll) {
14173                    pw.println("-------------------------------------------------------------------------------");
14174                }
14175                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14176                        .dumpLocked();
14177                pw.println();
14178                if (dumpAll) {
14179                    pw.println("-------------------------------------------------------------------------------");
14180                }
14181                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14182                pw.println();
14183                if (dumpAll) {
14184                    pw.println("-------------------------------------------------------------------------------");
14185                }
14186                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14187                if (mAssociations.size() > 0) {
14188                    pw.println();
14189                    if (dumpAll) {
14190                        pw.println("-------------------------------------------------------------------------------");
14191                    }
14192                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14193                }
14194                pw.println();
14195                if (dumpAll) {
14196                    pw.println("-------------------------------------------------------------------------------");
14197                }
14198                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14199            }
14200        }
14201        Binder.restoreCallingIdentity(origId);
14202    }
14203
14204    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14205            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14206        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14207
14208        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14209                dumpPackage);
14210        boolean needSep = printedAnything;
14211
14212        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14213                dumpPackage, needSep, "  mFocusedActivity: ");
14214        if (printed) {
14215            printedAnything = true;
14216            needSep = false;
14217        }
14218
14219        if (dumpPackage == null) {
14220            if (needSep) {
14221                pw.println();
14222            }
14223            needSep = true;
14224            printedAnything = true;
14225            mStackSupervisor.dump(pw, "  ");
14226        }
14227
14228        if (!printedAnything) {
14229            pw.println("  (nothing)");
14230        }
14231    }
14232
14233    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14234            int opti, boolean dumpAll, String dumpPackage) {
14235        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14236
14237        boolean printedAnything = false;
14238
14239        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14240            boolean printedHeader = false;
14241
14242            final int N = mRecentTasks.size();
14243            for (int i=0; i<N; i++) {
14244                TaskRecord tr = mRecentTasks.get(i);
14245                if (dumpPackage != null) {
14246                    if (tr.realActivity == null ||
14247                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
14248                        continue;
14249                    }
14250                }
14251                if (!printedHeader) {
14252                    pw.println("  Recent tasks:");
14253                    printedHeader = true;
14254                    printedAnything = true;
14255                }
14256                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14257                        pw.println(tr);
14258                if (dumpAll) {
14259                    mRecentTasks.get(i).dump(pw, "    ");
14260                }
14261            }
14262        }
14263
14264        if (!printedAnything) {
14265            pw.println("  (nothing)");
14266        }
14267    }
14268
14269    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14270            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14271        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14272
14273        int dumpUid = 0;
14274        if (dumpPackage != null) {
14275            IPackageManager pm = AppGlobals.getPackageManager();
14276            try {
14277                dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14278            } catch (RemoteException e) {
14279            }
14280        }
14281
14282        boolean printedAnything = false;
14283
14284        final long now = SystemClock.uptimeMillis();
14285
14286        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14287            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14288                    = mAssociations.valueAt(i1);
14289            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14290                SparseArray<ArrayMap<String, Association>> sourceUids
14291                        = targetComponents.valueAt(i2);
14292                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14293                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14294                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14295                        Association ass = sourceProcesses.valueAt(i4);
14296                        if (dumpPackage != null) {
14297                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14298                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14299                                continue;
14300                            }
14301                        }
14302                        printedAnything = true;
14303                        pw.print("  ");
14304                        pw.print(ass.mTargetProcess);
14305                        pw.print("/");
14306                        UserHandle.formatUid(pw, ass.mTargetUid);
14307                        pw.print(" <- ");
14308                        pw.print(ass.mSourceProcess);
14309                        pw.print("/");
14310                        UserHandle.formatUid(pw, ass.mSourceUid);
14311                        pw.println();
14312                        pw.print("    via ");
14313                        pw.print(ass.mTargetComponent.flattenToShortString());
14314                        pw.println();
14315                        pw.print("    ");
14316                        long dur = ass.mTime;
14317                        if (ass.mNesting > 0) {
14318                            dur += now - ass.mStartTime;
14319                        }
14320                        TimeUtils.formatDuration(dur, pw);
14321                        pw.print(" (");
14322                        pw.print(ass.mCount);
14323                        pw.print(" times)");
14324                        pw.print("  ");
14325                        for (int i=0; i<ass.mStateTimes.length; i++) {
14326                            long amt = ass.mStateTimes[i];
14327                            if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14328                                amt += now - ass.mLastStateUptime;
14329                            }
14330                            if (amt != 0) {
14331                                pw.print(" ");
14332                                pw.print(ProcessList.makeProcStateString(
14333                                            i + ActivityManager.MIN_PROCESS_STATE));
14334                                pw.print("=");
14335                                TimeUtils.formatDuration(amt, pw);
14336                                if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14337                                    pw.print("*");
14338                                }
14339                            }
14340                        }
14341                        pw.println();
14342                        if (ass.mNesting > 0) {
14343                            pw.print("    Currently active: ");
14344                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14345                            pw.println();
14346                        }
14347                    }
14348                }
14349            }
14350
14351        }
14352
14353        if (!printedAnything) {
14354            pw.println("  (nothing)");
14355        }
14356    }
14357
14358    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14359            String header, boolean needSep) {
14360        boolean printed = false;
14361        int whichAppId = -1;
14362        if (dumpPackage != null) {
14363            try {
14364                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14365                        dumpPackage, 0);
14366                whichAppId = UserHandle.getAppId(info.uid);
14367            } catch (NameNotFoundException e) {
14368                e.printStackTrace();
14369            }
14370        }
14371        for (int i=0; i<uids.size(); i++) {
14372            UidRecord uidRec = uids.valueAt(i);
14373            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14374                continue;
14375            }
14376            if (!printed) {
14377                printed = true;
14378                if (needSep) {
14379                    pw.println();
14380                }
14381                pw.print("  ");
14382                pw.println(header);
14383                needSep = true;
14384            }
14385            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14386            pw.print(": "); pw.println(uidRec);
14387        }
14388        return printed;
14389    }
14390
14391    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14392            int opti, boolean dumpAll, String dumpPackage) {
14393        boolean needSep = false;
14394        boolean printedAnything = false;
14395        int numPers = 0;
14396
14397        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14398
14399        if (dumpAll) {
14400            final int NP = mProcessNames.getMap().size();
14401            for (int ip=0; ip<NP; ip++) {
14402                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14403                final int NA = procs.size();
14404                for (int ia=0; ia<NA; ia++) {
14405                    ProcessRecord r = procs.valueAt(ia);
14406                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14407                        continue;
14408                    }
14409                    if (!needSep) {
14410                        pw.println("  All known processes:");
14411                        needSep = true;
14412                        printedAnything = true;
14413                    }
14414                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14415                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14416                        pw.print(" "); pw.println(r);
14417                    r.dump(pw, "    ");
14418                    if (r.persistent) {
14419                        numPers++;
14420                    }
14421                }
14422            }
14423        }
14424
14425        if (mIsolatedProcesses.size() > 0) {
14426            boolean printed = false;
14427            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14428                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14429                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14430                    continue;
14431                }
14432                if (!printed) {
14433                    if (needSep) {
14434                        pw.println();
14435                    }
14436                    pw.println("  Isolated process list (sorted by uid):");
14437                    printedAnything = true;
14438                    printed = true;
14439                    needSep = true;
14440                }
14441                pw.println(String.format("%sIsolated #%2d: %s",
14442                        "    ", i, r.toString()));
14443            }
14444        }
14445
14446        if (mActiveUids.size() > 0) {
14447            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14448                printedAnything = needSep = true;
14449            }
14450        }
14451        if (mValidateUids.size() > 0) {
14452            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14453                printedAnything = needSep = true;
14454            }
14455        }
14456
14457        if (mLruProcesses.size() > 0) {
14458            if (needSep) {
14459                pw.println();
14460            }
14461            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14462                    pw.print(" total, non-act at ");
14463                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14464                    pw.print(", non-svc at ");
14465                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14466                    pw.println("):");
14467            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14468            needSep = true;
14469            printedAnything = true;
14470        }
14471
14472        if (dumpAll || dumpPackage != null) {
14473            synchronized (mPidsSelfLocked) {
14474                boolean printed = false;
14475                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14476                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14477                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14478                        continue;
14479                    }
14480                    if (!printed) {
14481                        if (needSep) pw.println();
14482                        needSep = true;
14483                        pw.println("  PID mappings:");
14484                        printed = true;
14485                        printedAnything = true;
14486                    }
14487                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14488                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14489                }
14490            }
14491        }
14492
14493        if (mForegroundProcesses.size() > 0) {
14494            synchronized (mPidsSelfLocked) {
14495                boolean printed = false;
14496                for (int i=0; i<mForegroundProcesses.size(); i++) {
14497                    ProcessRecord r = mPidsSelfLocked.get(
14498                            mForegroundProcesses.valueAt(i).pid);
14499                    if (dumpPackage != null && (r == null
14500                            || !r.pkgList.containsKey(dumpPackage))) {
14501                        continue;
14502                    }
14503                    if (!printed) {
14504                        if (needSep) pw.println();
14505                        needSep = true;
14506                        pw.println("  Foreground Processes:");
14507                        printed = true;
14508                        printedAnything = true;
14509                    }
14510                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14511                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14512                }
14513            }
14514        }
14515
14516        if (mPersistentStartingProcesses.size() > 0) {
14517            if (needSep) pw.println();
14518            needSep = true;
14519            printedAnything = true;
14520            pw.println("  Persisent processes that are starting:");
14521            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14522                    "Starting Norm", "Restarting PERS", dumpPackage);
14523        }
14524
14525        if (mRemovedProcesses.size() > 0) {
14526            if (needSep) pw.println();
14527            needSep = true;
14528            printedAnything = true;
14529            pw.println("  Processes that are being removed:");
14530            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14531                    "Removed Norm", "Removed PERS", dumpPackage);
14532        }
14533
14534        if (mProcessesOnHold.size() > 0) {
14535            if (needSep) pw.println();
14536            needSep = true;
14537            printedAnything = true;
14538            pw.println("  Processes that are on old until the system is ready:");
14539            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14540                    "OnHold Norm", "OnHold PERS", dumpPackage);
14541        }
14542
14543        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14544
14545        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14546        if (needSep) {
14547            printedAnything = true;
14548        }
14549
14550        if (dumpPackage == null) {
14551            pw.println();
14552            needSep = false;
14553            mUserController.dump(pw, dumpAll);
14554        }
14555        if (mHomeProcess != null && (dumpPackage == null
14556                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14557            if (needSep) {
14558                pw.println();
14559                needSep = false;
14560            }
14561            pw.println("  mHomeProcess: " + mHomeProcess);
14562        }
14563        if (mPreviousProcess != null && (dumpPackage == null
14564                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14565            if (needSep) {
14566                pw.println();
14567                needSep = false;
14568            }
14569            pw.println("  mPreviousProcess: " + mPreviousProcess);
14570        }
14571        if (dumpAll) {
14572            StringBuilder sb = new StringBuilder(128);
14573            sb.append("  mPreviousProcessVisibleTime: ");
14574            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14575            pw.println(sb);
14576        }
14577        if (mHeavyWeightProcess != null && (dumpPackage == null
14578                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14579            if (needSep) {
14580                pw.println();
14581                needSep = false;
14582            }
14583            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14584        }
14585        if (dumpPackage == null) {
14586            pw.println("  mConfiguration: " + mConfiguration);
14587        }
14588        if (dumpAll) {
14589            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14590            if (mCompatModePackages.getPackages().size() > 0) {
14591                boolean printed = false;
14592                for (Map.Entry<String, Integer> entry
14593                        : mCompatModePackages.getPackages().entrySet()) {
14594                    String pkg = entry.getKey();
14595                    int mode = entry.getValue();
14596                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14597                        continue;
14598                    }
14599                    if (!printed) {
14600                        pw.println("  mScreenCompatPackages:");
14601                        printed = true;
14602                    }
14603                    pw.print("    "); pw.print(pkg); pw.print(": ");
14604                            pw.print(mode); pw.println();
14605                }
14606            }
14607        }
14608        if (dumpPackage == null) {
14609            pw.println("  mWakefulness="
14610                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14611            pw.println("  mSleepTokens=" + mSleepTokens);
14612            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14613                    + lockScreenShownToString());
14614            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14615            if (mRunningVoice != null) {
14616                pw.println("  mRunningVoice=" + mRunningVoice);
14617                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14618            }
14619        }
14620        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14621                || mOrigWaitForDebugger) {
14622            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14623                    || dumpPackage.equals(mOrigDebugApp)) {
14624                if (needSep) {
14625                    pw.println();
14626                    needSep = false;
14627                }
14628                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14629                        + " mDebugTransient=" + mDebugTransient
14630                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14631            }
14632        }
14633        if (mCurAppTimeTracker != null) {
14634            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14635        }
14636        if (mMemWatchProcesses.getMap().size() > 0) {
14637            pw.println("  Mem watch processes:");
14638            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14639                    = mMemWatchProcesses.getMap();
14640            for (int i=0; i<procs.size(); i++) {
14641                final String proc = procs.keyAt(i);
14642                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14643                for (int j=0; j<uids.size(); j++) {
14644                    if (needSep) {
14645                        pw.println();
14646                        needSep = false;
14647                    }
14648                    StringBuilder sb = new StringBuilder();
14649                    sb.append("    ").append(proc).append('/');
14650                    UserHandle.formatUid(sb, uids.keyAt(j));
14651                    Pair<Long, String> val = uids.valueAt(j);
14652                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14653                    if (val.second != null) {
14654                        sb.append(", report to ").append(val.second);
14655                    }
14656                    pw.println(sb.toString());
14657                }
14658            }
14659            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14660            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14661            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14662                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14663        }
14664        if (mTrackAllocationApp != null) {
14665            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14666                if (needSep) {
14667                    pw.println();
14668                    needSep = false;
14669                }
14670                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14671            }
14672        }
14673        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14674                || mProfileFd != null) {
14675            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14676                if (needSep) {
14677                    pw.println();
14678                    needSep = false;
14679                }
14680                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14681                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14682                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14683                        + mAutoStopProfiler);
14684                pw.println("  mProfileType=" + mProfileType);
14685            }
14686        }
14687        if (mNativeDebuggingApp != null) {
14688            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14689                if (needSep) {
14690                    pw.println();
14691                    needSep = false;
14692                }
14693                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14694            }
14695        }
14696        if (dumpPackage == null) {
14697            if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14698                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14699                        + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14700            }
14701            if (mController != null) {
14702                pw.println("  mController=" + mController
14703                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14704            }
14705            if (dumpAll) {
14706                pw.println("  Total persistent processes: " + numPers);
14707                pw.println("  mProcessesReady=" + mProcessesReady
14708                        + " mSystemReady=" + mSystemReady
14709                        + " mBooted=" + mBooted
14710                        + " mFactoryTest=" + mFactoryTest);
14711                pw.println("  mBooting=" + mBooting
14712                        + " mCallFinishBooting=" + mCallFinishBooting
14713                        + " mBootAnimationComplete=" + mBootAnimationComplete);
14714                pw.print("  mLastPowerCheckRealtime=");
14715                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14716                        pw.println("");
14717                pw.print("  mLastPowerCheckUptime=");
14718                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14719                        pw.println("");
14720                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14721                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14722                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14723                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14724                        + " (" + mLruProcesses.size() + " total)"
14725                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14726                        + " mNumServiceProcs=" + mNumServiceProcs
14727                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14728                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14729                        + " mLastMemoryLevel=" + mLastMemoryLevel
14730                        + " mLastNumProcesses=" + mLastNumProcesses);
14731                long now = SystemClock.uptimeMillis();
14732                pw.print("  mLastIdleTime=");
14733                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
14734                        pw.print(" mLowRamSinceLastIdle=");
14735                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14736                        pw.println();
14737            }
14738        }
14739
14740        if (!printedAnything) {
14741            pw.println("  (nothing)");
14742        }
14743    }
14744
14745    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14746            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14747        if (mProcessesToGc.size() > 0) {
14748            boolean printed = false;
14749            long now = SystemClock.uptimeMillis();
14750            for (int i=0; i<mProcessesToGc.size(); i++) {
14751                ProcessRecord proc = mProcessesToGc.get(i);
14752                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14753                    continue;
14754                }
14755                if (!printed) {
14756                    if (needSep) pw.println();
14757                    needSep = true;
14758                    pw.println("  Processes that are waiting to GC:");
14759                    printed = true;
14760                }
14761                pw.print("    Process "); pw.println(proc);
14762                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14763                        pw.print(", last gced=");
14764                        pw.print(now-proc.lastRequestedGc);
14765                        pw.print(" ms ago, last lowMem=");
14766                        pw.print(now-proc.lastLowMemory);
14767                        pw.println(" ms ago");
14768
14769            }
14770        }
14771        return needSep;
14772    }
14773
14774    void printOomLevel(PrintWriter pw, String name, int adj) {
14775        pw.print("    ");
14776        if (adj >= 0) {
14777            pw.print(' ');
14778            if (adj < 10) pw.print(' ');
14779        } else {
14780            if (adj > -10) pw.print(' ');
14781        }
14782        pw.print(adj);
14783        pw.print(": ");
14784        pw.print(name);
14785        pw.print(" (");
14786        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14787        pw.println(")");
14788    }
14789
14790    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14791            int opti, boolean dumpAll) {
14792        boolean needSep = false;
14793
14794        if (mLruProcesses.size() > 0) {
14795            if (needSep) pw.println();
14796            needSep = true;
14797            pw.println("  OOM levels:");
14798            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14799            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14800            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14801            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14802            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14803            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14804            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14805            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14806            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14807            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14808            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14809            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14810            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14811            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14812
14813            if (needSep) pw.println();
14814            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
14815                    pw.print(" total, non-act at ");
14816                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14817                    pw.print(", non-svc at ");
14818                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14819                    pw.println("):");
14820            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
14821            needSep = true;
14822        }
14823
14824        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14825
14826        pw.println();
14827        pw.println("  mHomeProcess: " + mHomeProcess);
14828        pw.println("  mPreviousProcess: " + mPreviousProcess);
14829        if (mHeavyWeightProcess != null) {
14830            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14831        }
14832
14833        return true;
14834    }
14835
14836    /**
14837     * There are three ways to call this:
14838     *  - no provider specified: dump all the providers
14839     *  - a flattened component name that matched an existing provider was specified as the
14840     *    first arg: dump that one provider
14841     *  - the first arg isn't the flattened component name of an existing provider:
14842     *    dump all providers whose component contains the first arg as a substring
14843     */
14844    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14845            int opti, boolean dumpAll) {
14846        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14847    }
14848
14849    static class ItemMatcher {
14850        ArrayList<ComponentName> components;
14851        ArrayList<String> strings;
14852        ArrayList<Integer> objects;
14853        boolean all;
14854
14855        ItemMatcher() {
14856            all = true;
14857        }
14858
14859        void build(String name) {
14860            ComponentName componentName = ComponentName.unflattenFromString(name);
14861            if (componentName != null) {
14862                if (components == null) {
14863                    components = new ArrayList<ComponentName>();
14864                }
14865                components.add(componentName);
14866                all = false;
14867            } else {
14868                int objectId = 0;
14869                // Not a '/' separated full component name; maybe an object ID?
14870                try {
14871                    objectId = Integer.parseInt(name, 16);
14872                    if (objects == null) {
14873                        objects = new ArrayList<Integer>();
14874                    }
14875                    objects.add(objectId);
14876                    all = false;
14877                } catch (RuntimeException e) {
14878                    // Not an integer; just do string match.
14879                    if (strings == null) {
14880                        strings = new ArrayList<String>();
14881                    }
14882                    strings.add(name);
14883                    all = false;
14884                }
14885            }
14886        }
14887
14888        int build(String[] args, int opti) {
14889            for (; opti<args.length; opti++) {
14890                String name = args[opti];
14891                if ("--".equals(name)) {
14892                    return opti+1;
14893                }
14894                build(name);
14895            }
14896            return opti;
14897        }
14898
14899        boolean match(Object object, ComponentName comp) {
14900            if (all) {
14901                return true;
14902            }
14903            if (components != null) {
14904                for (int i=0; i<components.size(); i++) {
14905                    if (components.get(i).equals(comp)) {
14906                        return true;
14907                    }
14908                }
14909            }
14910            if (objects != null) {
14911                for (int i=0; i<objects.size(); i++) {
14912                    if (System.identityHashCode(object) == objects.get(i)) {
14913                        return true;
14914                    }
14915                }
14916            }
14917            if (strings != null) {
14918                String flat = comp.flattenToString();
14919                for (int i=0; i<strings.size(); i++) {
14920                    if (flat.contains(strings.get(i))) {
14921                        return true;
14922                    }
14923                }
14924            }
14925            return false;
14926        }
14927    }
14928
14929    /**
14930     * There are three things that cmd can be:
14931     *  - a flattened component name that matches an existing activity
14932     *  - the cmd arg isn't the flattened component name of an existing activity:
14933     *    dump all activity whose component contains the cmd as a substring
14934     *  - A hex number of the ActivityRecord object instance.
14935     */
14936    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14937            int opti, boolean dumpAll) {
14938        ArrayList<ActivityRecord> activities;
14939
14940        synchronized (this) {
14941            activities = mStackSupervisor.getDumpActivitiesLocked(name);
14942        }
14943
14944        if (activities.size() <= 0) {
14945            return false;
14946        }
14947
14948        String[] newArgs = new String[args.length - opti];
14949        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14950
14951        TaskRecord lastTask = null;
14952        boolean needSep = false;
14953        for (int i=activities.size()-1; i>=0; i--) {
14954            ActivityRecord r = activities.get(i);
14955            if (needSep) {
14956                pw.println();
14957            }
14958            needSep = true;
14959            synchronized (this) {
14960                if (lastTask != r.task) {
14961                    lastTask = r.task;
14962                    pw.print("TASK "); pw.print(lastTask.affinity);
14963                            pw.print(" id="); pw.println(lastTask.taskId);
14964                    if (dumpAll) {
14965                        lastTask.dump(pw, "  ");
14966                    }
14967                }
14968            }
14969            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
14970        }
14971        return true;
14972    }
14973
14974    /**
14975     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14976     * there is a thread associated with the activity.
14977     */
14978    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14979            final ActivityRecord r, String[] args, boolean dumpAll) {
14980        String innerPrefix = prefix + "  ";
14981        synchronized (this) {
14982            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14983                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14984                    pw.print(" pid=");
14985                    if (r.app != null) pw.println(r.app.pid);
14986                    else pw.println("(not running)");
14987            if (dumpAll) {
14988                r.dump(pw, innerPrefix);
14989            }
14990        }
14991        if (r.app != null && r.app.thread != null) {
14992            // flush anything that is already in the PrintWriter since the thread is going
14993            // to write to the file descriptor directly
14994            pw.flush();
14995            try {
14996                TransferPipe tp = new TransferPipe();
14997                try {
14998                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14999                            r.appToken, innerPrefix, args);
15000                    tp.go(fd);
15001                } finally {
15002                    tp.kill();
15003                }
15004            } catch (IOException e) {
15005                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15006            } catch (RemoteException e) {
15007                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15008            }
15009        }
15010    }
15011
15012    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15013            int opti, boolean dumpAll, String dumpPackage) {
15014        boolean needSep = false;
15015        boolean onlyHistory = false;
15016        boolean printedAnything = false;
15017
15018        if ("history".equals(dumpPackage)) {
15019            if (opti < args.length && "-s".equals(args[opti])) {
15020                dumpAll = false;
15021            }
15022            onlyHistory = true;
15023            dumpPackage = null;
15024        }
15025
15026        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15027        if (!onlyHistory && dumpAll) {
15028            if (mRegisteredReceivers.size() > 0) {
15029                boolean printed = false;
15030                Iterator it = mRegisteredReceivers.values().iterator();
15031                while (it.hasNext()) {
15032                    ReceiverList r = (ReceiverList)it.next();
15033                    if (dumpPackage != null && (r.app == null ||
15034                            !dumpPackage.equals(r.app.info.packageName))) {
15035                        continue;
15036                    }
15037                    if (!printed) {
15038                        pw.println("  Registered Receivers:");
15039                        needSep = true;
15040                        printed = true;
15041                        printedAnything = true;
15042                    }
15043                    pw.print("  * "); pw.println(r);
15044                    r.dump(pw, "    ");
15045                }
15046            }
15047
15048            if (mReceiverResolver.dump(pw, needSep ?
15049                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15050                    "    ", dumpPackage, false, false)) {
15051                needSep = true;
15052                printedAnything = true;
15053            }
15054        }
15055
15056        for (BroadcastQueue q : mBroadcastQueues) {
15057            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15058            printedAnything |= needSep;
15059        }
15060
15061        needSep = true;
15062
15063        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15064            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15065                if (needSep) {
15066                    pw.println();
15067                }
15068                needSep = true;
15069                printedAnything = true;
15070                pw.print("  Sticky broadcasts for user ");
15071                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15072                StringBuilder sb = new StringBuilder(128);
15073                for (Map.Entry<String, ArrayList<Intent>> ent
15074                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15075                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15076                    if (dumpAll) {
15077                        pw.println(":");
15078                        ArrayList<Intent> intents = ent.getValue();
15079                        final int N = intents.size();
15080                        for (int i=0; i<N; i++) {
15081                            sb.setLength(0);
15082                            sb.append("    Intent: ");
15083                            intents.get(i).toShortString(sb, false, true, false, false);
15084                            pw.println(sb.toString());
15085                            Bundle bundle = intents.get(i).getExtras();
15086                            if (bundle != null) {
15087                                pw.print("      ");
15088                                pw.println(bundle.toString());
15089                            }
15090                        }
15091                    } else {
15092                        pw.println("");
15093                    }
15094                }
15095            }
15096        }
15097
15098        if (!onlyHistory && dumpAll) {
15099            pw.println();
15100            for (BroadcastQueue queue : mBroadcastQueues) {
15101                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15102                        + queue.mBroadcastsScheduled);
15103            }
15104            pw.println("  mHandler:");
15105            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15106            needSep = true;
15107            printedAnything = true;
15108        }
15109
15110        if (!printedAnything) {
15111            pw.println("  (nothing)");
15112        }
15113    }
15114
15115    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15116            int opti, boolean dumpAll, String dumpPackage) {
15117        if (mCurBroadcastStats == null) {
15118            return;
15119        }
15120
15121        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15122        final long now = SystemClock.elapsedRealtime();
15123        if (mLastBroadcastStats != null) {
15124            pw.print("  Last stats (from ");
15125            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15126            pw.print(" to ");
15127            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15128            pw.print(", ");
15129            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15130                    - mLastBroadcastStats.mStartUptime, pw);
15131            pw.println(" uptime):");
15132            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15133                pw.println("    (nothing)");
15134            }
15135            pw.println();
15136        }
15137        pw.print("  Current stats (from ");
15138        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15139        pw.print(" to now, ");
15140        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15141                - mCurBroadcastStats.mStartUptime, pw);
15142        pw.println(" uptime):");
15143        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15144            pw.println("    (nothing)");
15145        }
15146    }
15147
15148    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15149            int opti, boolean fullCheckin, String dumpPackage) {
15150        if (mCurBroadcastStats == null) {
15151            return;
15152        }
15153
15154        if (mLastBroadcastStats != null) {
15155            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15156            if (fullCheckin) {
15157                mLastBroadcastStats = null;
15158                return;
15159            }
15160        }
15161        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15162        if (fullCheckin) {
15163            mCurBroadcastStats = null;
15164        }
15165    }
15166
15167    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15168            int opti, boolean dumpAll, String dumpPackage) {
15169        boolean needSep;
15170        boolean printedAnything = false;
15171
15172        ItemMatcher matcher = new ItemMatcher();
15173        matcher.build(args, opti);
15174
15175        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15176
15177        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15178        printedAnything |= needSep;
15179
15180        if (mLaunchingProviders.size() > 0) {
15181            boolean printed = false;
15182            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15183                ContentProviderRecord r = mLaunchingProviders.get(i);
15184                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15185                    continue;
15186                }
15187                if (!printed) {
15188                    if (needSep) pw.println();
15189                    needSep = true;
15190                    pw.println("  Launching content providers:");
15191                    printed = true;
15192                    printedAnything = true;
15193                }
15194                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15195                        pw.println(r);
15196            }
15197        }
15198
15199        if (!printedAnything) {
15200            pw.println("  (nothing)");
15201        }
15202    }
15203
15204    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15205            int opti, boolean dumpAll, String dumpPackage) {
15206        boolean needSep = false;
15207        boolean printedAnything = false;
15208
15209        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15210
15211        if (mGrantedUriPermissions.size() > 0) {
15212            boolean printed = false;
15213            int dumpUid = -2;
15214            if (dumpPackage != null) {
15215                try {
15216                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15217                            MATCH_UNINSTALLED_PACKAGES, 0);
15218                } catch (NameNotFoundException e) {
15219                    dumpUid = -1;
15220                }
15221            }
15222            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15223                int uid = mGrantedUriPermissions.keyAt(i);
15224                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15225                    continue;
15226                }
15227                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15228                if (!printed) {
15229                    if (needSep) pw.println();
15230                    needSep = true;
15231                    pw.println("  Granted Uri Permissions:");
15232                    printed = true;
15233                    printedAnything = true;
15234                }
15235                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15236                for (UriPermission perm : perms.values()) {
15237                    pw.print("    "); pw.println(perm);
15238                    if (dumpAll) {
15239                        perm.dump(pw, "      ");
15240                    }
15241                }
15242            }
15243        }
15244
15245        if (!printedAnything) {
15246            pw.println("  (nothing)");
15247        }
15248    }
15249
15250    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15251            int opti, boolean dumpAll, String dumpPackage) {
15252        boolean printed = false;
15253
15254        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15255
15256        if (mIntentSenderRecords.size() > 0) {
15257            Iterator<WeakReference<PendingIntentRecord>> it
15258                    = mIntentSenderRecords.values().iterator();
15259            while (it.hasNext()) {
15260                WeakReference<PendingIntentRecord> ref = it.next();
15261                PendingIntentRecord rec = ref != null ? ref.get(): null;
15262                if (dumpPackage != null && (rec == null
15263                        || !dumpPackage.equals(rec.key.packageName))) {
15264                    continue;
15265                }
15266                printed = true;
15267                if (rec != null) {
15268                    pw.print("  * "); pw.println(rec);
15269                    if (dumpAll) {
15270                        rec.dump(pw, "    ");
15271                    }
15272                } else {
15273                    pw.print("  * "); pw.println(ref);
15274                }
15275            }
15276        }
15277
15278        if (!printed) {
15279            pw.println("  (nothing)");
15280        }
15281    }
15282
15283    private static final int dumpProcessList(PrintWriter pw,
15284            ActivityManagerService service, List list,
15285            String prefix, String normalLabel, String persistentLabel,
15286            String dumpPackage) {
15287        int numPers = 0;
15288        final int N = list.size()-1;
15289        for (int i=N; i>=0; i--) {
15290            ProcessRecord r = (ProcessRecord)list.get(i);
15291            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15292                continue;
15293            }
15294            pw.println(String.format("%s%s #%2d: %s",
15295                    prefix, (r.persistent ? persistentLabel : normalLabel),
15296                    i, r.toString()));
15297            if (r.persistent) {
15298                numPers++;
15299            }
15300        }
15301        return numPers;
15302    }
15303
15304    private static final boolean dumpProcessOomList(PrintWriter pw,
15305            ActivityManagerService service, List<ProcessRecord> origList,
15306            String prefix, String normalLabel, String persistentLabel,
15307            boolean inclDetails, String dumpPackage) {
15308
15309        ArrayList<Pair<ProcessRecord, Integer>> list
15310                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15311        for (int i=0; i<origList.size(); i++) {
15312            ProcessRecord r = origList.get(i);
15313            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15314                continue;
15315            }
15316            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15317        }
15318
15319        if (list.size() <= 0) {
15320            return false;
15321        }
15322
15323        Comparator<Pair<ProcessRecord, Integer>> comparator
15324                = new Comparator<Pair<ProcessRecord, Integer>>() {
15325            @Override
15326            public int compare(Pair<ProcessRecord, Integer> object1,
15327                    Pair<ProcessRecord, Integer> object2) {
15328                if (object1.first.setAdj != object2.first.setAdj) {
15329                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15330                }
15331                if (object1.first.setProcState != object2.first.setProcState) {
15332                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15333                }
15334                if (object1.second.intValue() != object2.second.intValue()) {
15335                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15336                }
15337                return 0;
15338            }
15339        };
15340
15341        Collections.sort(list, comparator);
15342
15343        final long curRealtime = SystemClock.elapsedRealtime();
15344        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15345        final long curUptime = SystemClock.uptimeMillis();
15346        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15347
15348        for (int i=list.size()-1; i>=0; i--) {
15349            ProcessRecord r = list.get(i).first;
15350            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15351            char schedGroup;
15352            switch (r.setSchedGroup) {
15353                case ProcessList.SCHED_GROUP_BACKGROUND:
15354                    schedGroup = 'B';
15355                    break;
15356                case ProcessList.SCHED_GROUP_DEFAULT:
15357                    schedGroup = 'F';
15358                    break;
15359                case ProcessList.SCHED_GROUP_TOP_APP:
15360                    schedGroup = 'T';
15361                    break;
15362                default:
15363                    schedGroup = '?';
15364                    break;
15365            }
15366            char foreground;
15367            if (r.foregroundActivities) {
15368                foreground = 'A';
15369            } else if (r.foregroundServices) {
15370                foreground = 'S';
15371            } else {
15372                foreground = ' ';
15373            }
15374            String procState = ProcessList.makeProcStateString(r.curProcState);
15375            pw.print(prefix);
15376            pw.print(r.persistent ? persistentLabel : normalLabel);
15377            pw.print(" #");
15378            int num = (origList.size()-1)-list.get(i).second;
15379            if (num < 10) pw.print(' ');
15380            pw.print(num);
15381            pw.print(": ");
15382            pw.print(oomAdj);
15383            pw.print(' ');
15384            pw.print(schedGroup);
15385            pw.print('/');
15386            pw.print(foreground);
15387            pw.print('/');
15388            pw.print(procState);
15389            pw.print(" trm:");
15390            if (r.trimMemoryLevel < 10) pw.print(' ');
15391            pw.print(r.trimMemoryLevel);
15392            pw.print(' ');
15393            pw.print(r.toShortString());
15394            pw.print(" (");
15395            pw.print(r.adjType);
15396            pw.println(')');
15397            if (r.adjSource != null || r.adjTarget != null) {
15398                pw.print(prefix);
15399                pw.print("    ");
15400                if (r.adjTarget instanceof ComponentName) {
15401                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15402                } else if (r.adjTarget != null) {
15403                    pw.print(r.adjTarget.toString());
15404                } else {
15405                    pw.print("{null}");
15406                }
15407                pw.print("<=");
15408                if (r.adjSource instanceof ProcessRecord) {
15409                    pw.print("Proc{");
15410                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15411                    pw.println("}");
15412                } else if (r.adjSource != null) {
15413                    pw.println(r.adjSource.toString());
15414                } else {
15415                    pw.println("{null}");
15416                }
15417            }
15418            if (inclDetails) {
15419                pw.print(prefix);
15420                pw.print("    ");
15421                pw.print("oom: max="); pw.print(r.maxAdj);
15422                pw.print(" curRaw="); pw.print(r.curRawAdj);
15423                pw.print(" setRaw="); pw.print(r.setRawAdj);
15424                pw.print(" cur="); pw.print(r.curAdj);
15425                pw.print(" set="); pw.println(r.setAdj);
15426                pw.print(prefix);
15427                pw.print("    ");
15428                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15429                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15430                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15431                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15432                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15433                pw.println();
15434                pw.print(prefix);
15435                pw.print("    ");
15436                pw.print("cached="); pw.print(r.cached);
15437                pw.print(" empty="); pw.print(r.empty);
15438                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15439
15440                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15441                    if (r.lastWakeTime != 0) {
15442                        long wtime;
15443                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15444                        synchronized (stats) {
15445                            wtime = stats.getProcessWakeTime(r.info.uid,
15446                                    r.pid, curRealtime);
15447                        }
15448                        long timeUsed = wtime - r.lastWakeTime;
15449                        pw.print(prefix);
15450                        pw.print("    ");
15451                        pw.print("keep awake over ");
15452                        TimeUtils.formatDuration(realtimeSince, pw);
15453                        pw.print(" used ");
15454                        TimeUtils.formatDuration(timeUsed, pw);
15455                        pw.print(" (");
15456                        pw.print((timeUsed*100)/realtimeSince);
15457                        pw.println("%)");
15458                    }
15459                    if (r.lastCpuTime != 0) {
15460                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15461                        pw.print(prefix);
15462                        pw.print("    ");
15463                        pw.print("run cpu over ");
15464                        TimeUtils.formatDuration(uptimeSince, pw);
15465                        pw.print(" used ");
15466                        TimeUtils.formatDuration(timeUsed, pw);
15467                        pw.print(" (");
15468                        pw.print((timeUsed*100)/uptimeSince);
15469                        pw.println("%)");
15470                    }
15471                }
15472            }
15473        }
15474        return true;
15475    }
15476
15477    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15478            String[] args) {
15479        ArrayList<ProcessRecord> procs;
15480        synchronized (this) {
15481            if (args != null && args.length > start
15482                    && args[start].charAt(0) != '-') {
15483                procs = new ArrayList<ProcessRecord>();
15484                int pid = -1;
15485                try {
15486                    pid = Integer.parseInt(args[start]);
15487                } catch (NumberFormatException e) {
15488                }
15489                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15490                    ProcessRecord proc = mLruProcesses.get(i);
15491                    if (proc.pid == pid) {
15492                        procs.add(proc);
15493                    } else if (allPkgs && proc.pkgList != null
15494                            && proc.pkgList.containsKey(args[start])) {
15495                        procs.add(proc);
15496                    } else if (proc.processName.equals(args[start])) {
15497                        procs.add(proc);
15498                    }
15499                }
15500                if (procs.size() <= 0) {
15501                    return null;
15502                }
15503            } else {
15504                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15505            }
15506        }
15507        return procs;
15508    }
15509
15510    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15511            PrintWriter pw, String[] args) {
15512        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15513        if (procs == null) {
15514            pw.println("No process found for: " + args[0]);
15515            return;
15516        }
15517
15518        long uptime = SystemClock.uptimeMillis();
15519        long realtime = SystemClock.elapsedRealtime();
15520        pw.println("Applications Graphics Acceleration Info:");
15521        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15522
15523        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15524            ProcessRecord r = procs.get(i);
15525            if (r.thread != null) {
15526                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15527                pw.flush();
15528                try {
15529                    TransferPipe tp = new TransferPipe();
15530                    try {
15531                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15532                        tp.go(fd);
15533                    } finally {
15534                        tp.kill();
15535                    }
15536                } catch (IOException e) {
15537                    pw.println("Failure while dumping the app: " + r);
15538                    pw.flush();
15539                } catch (RemoteException e) {
15540                    pw.println("Got a RemoteException while dumping the app " + r);
15541                    pw.flush();
15542                }
15543            }
15544        }
15545    }
15546
15547    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15548        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15549        if (procs == null) {
15550            pw.println("No process found for: " + args[0]);
15551            return;
15552        }
15553
15554        pw.println("Applications Database Info:");
15555
15556        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15557            ProcessRecord r = procs.get(i);
15558            if (r.thread != null) {
15559                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15560                pw.flush();
15561                try {
15562                    TransferPipe tp = new TransferPipe();
15563                    try {
15564                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15565                        tp.go(fd);
15566                    } finally {
15567                        tp.kill();
15568                    }
15569                } catch (IOException e) {
15570                    pw.println("Failure while dumping the app: " + r);
15571                    pw.flush();
15572                } catch (RemoteException e) {
15573                    pw.println("Got a RemoteException while dumping the app " + r);
15574                    pw.flush();
15575                }
15576            }
15577        }
15578    }
15579
15580    final static class MemItem {
15581        final boolean isProc;
15582        final String label;
15583        final String shortLabel;
15584        final long pss;
15585        final long swapPss;
15586        final int id;
15587        final boolean hasActivities;
15588        ArrayList<MemItem> subitems;
15589
15590        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15591                boolean _hasActivities) {
15592            isProc = true;
15593            label = _label;
15594            shortLabel = _shortLabel;
15595            pss = _pss;
15596            swapPss = _swapPss;
15597            id = _id;
15598            hasActivities = _hasActivities;
15599        }
15600
15601        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15602            isProc = false;
15603            label = _label;
15604            shortLabel = _shortLabel;
15605            pss = _pss;
15606            swapPss = _swapPss;
15607            id = _id;
15608            hasActivities = false;
15609        }
15610    }
15611
15612    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15613            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15614        if (sort && !isCompact) {
15615            Collections.sort(items, new Comparator<MemItem>() {
15616                @Override
15617                public int compare(MemItem lhs, MemItem rhs) {
15618                    if (lhs.pss < rhs.pss) {
15619                        return 1;
15620                    } else if (lhs.pss > rhs.pss) {
15621                        return -1;
15622                    }
15623                    return 0;
15624                }
15625            });
15626        }
15627
15628        for (int i=0; i<items.size(); i++) {
15629            MemItem mi = items.get(i);
15630            if (!isCompact) {
15631                if (dumpSwapPss) {
15632                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15633                            mi.label, stringifyKBSize(mi.swapPss));
15634                } else {
15635                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15636                }
15637            } else if (mi.isProc) {
15638                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15639                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15640                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15641                pw.println(mi.hasActivities ? ",a" : ",e");
15642            } else {
15643                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15644                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15645            }
15646            if (mi.subitems != null) {
15647                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15648                        true, isCompact, dumpSwapPss);
15649            }
15650        }
15651    }
15652
15653    // These are in KB.
15654    static final long[] DUMP_MEM_BUCKETS = new long[] {
15655        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15656        120*1024, 160*1024, 200*1024,
15657        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15658        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15659    };
15660
15661    static final void appendMemBucket(StringBuilder out, long memKB, String label,
15662            boolean stackLike) {
15663        int start = label.lastIndexOf('.');
15664        if (start >= 0) start++;
15665        else start = 0;
15666        int end = label.length();
15667        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15668            if (DUMP_MEM_BUCKETS[i] >= memKB) {
15669                long bucket = DUMP_MEM_BUCKETS[i]/1024;
15670                out.append(bucket);
15671                out.append(stackLike ? "MB." : "MB ");
15672                out.append(label, start, end);
15673                return;
15674            }
15675        }
15676        out.append(memKB/1024);
15677        out.append(stackLike ? "MB." : "MB ");
15678        out.append(label, start, end);
15679    }
15680
15681    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15682            ProcessList.NATIVE_ADJ,
15683            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15684            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15685            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15686            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15687            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15688            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15689    };
15690    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15691            "Native",
15692            "System", "Persistent", "Persistent Service", "Foreground",
15693            "Visible", "Perceptible",
15694            "Heavy Weight", "Backup",
15695            "A Services", "Home",
15696            "Previous", "B Services", "Cached"
15697    };
15698    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15699            "native",
15700            "sys", "pers", "persvc", "fore",
15701            "vis", "percept",
15702            "heavy", "backup",
15703            "servicea", "home",
15704            "prev", "serviceb", "cached"
15705    };
15706
15707    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15708            long realtime, boolean isCheckinRequest, boolean isCompact) {
15709        if (isCompact) {
15710            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15711        }
15712        if (isCheckinRequest || isCompact) {
15713            // short checkin version
15714            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15715        } else {
15716            pw.println("Applications Memory Usage (in Kilobytes):");
15717            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15718        }
15719    }
15720
15721    private static final int KSM_SHARED = 0;
15722    private static final int KSM_SHARING = 1;
15723    private static final int KSM_UNSHARED = 2;
15724    private static final int KSM_VOLATILE = 3;
15725
15726    private final long[] getKsmInfo() {
15727        long[] longOut = new long[4];
15728        final int[] SINGLE_LONG_FORMAT = new int[] {
15729            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15730        };
15731        long[] longTmp = new long[1];
15732        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15733                SINGLE_LONG_FORMAT, null, longTmp, null);
15734        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15735        longTmp[0] = 0;
15736        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15737                SINGLE_LONG_FORMAT, null, longTmp, null);
15738        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15739        longTmp[0] = 0;
15740        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15741                SINGLE_LONG_FORMAT, null, longTmp, null);
15742        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15743        longTmp[0] = 0;
15744        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15745                SINGLE_LONG_FORMAT, null, longTmp, null);
15746        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15747        return longOut;
15748    }
15749
15750    private static String stringifySize(long size, int order) {
15751        Locale locale = Locale.US;
15752        switch (order) {
15753            case 1:
15754                return String.format(locale, "%,13d", size);
15755            case 1024:
15756                return String.format(locale, "%,9dK", size / 1024);
15757            case 1024 * 1024:
15758                return String.format(locale, "%,5dM", size / 1024 / 1024);
15759            case 1024 * 1024 * 1024:
15760                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15761            default:
15762                throw new IllegalArgumentException("Invalid size order");
15763        }
15764    }
15765
15766    private static String stringifyKBSize(long size) {
15767        return stringifySize(size * 1024, 1024);
15768    }
15769
15770    // Update this version number in case you change the 'compact' format
15771    private static final int MEMINFO_COMPACT_VERSION = 1;
15772
15773    final void dumpApplicationMemoryUsage(FileDescriptor fd,
15774            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15775        boolean dumpDetails = false;
15776        boolean dumpFullDetails = false;
15777        boolean dumpDalvik = false;
15778        boolean dumpSummaryOnly = false;
15779        boolean dumpUnreachable = false;
15780        boolean oomOnly = false;
15781        boolean isCompact = false;
15782        boolean localOnly = false;
15783        boolean packages = false;
15784        boolean isCheckinRequest = false;
15785        boolean dumpSwapPss = false;
15786
15787        int opti = 0;
15788        while (opti < args.length) {
15789            String opt = args[opti];
15790            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15791                break;
15792            }
15793            opti++;
15794            if ("-a".equals(opt)) {
15795                dumpDetails = true;
15796                dumpFullDetails = true;
15797                dumpDalvik = true;
15798                dumpSwapPss = true;
15799            } else if ("-d".equals(opt)) {
15800                dumpDalvik = true;
15801            } else if ("-c".equals(opt)) {
15802                isCompact = true;
15803            } else if ("-s".equals(opt)) {
15804                dumpDetails = true;
15805                dumpSummaryOnly = true;
15806            } else if ("-S".equals(opt)) {
15807                dumpSwapPss = true;
15808            } else if ("--unreachable".equals(opt)) {
15809                dumpUnreachable = true;
15810            } else if ("--oom".equals(opt)) {
15811                oomOnly = true;
15812            } else if ("--local".equals(opt)) {
15813                localOnly = true;
15814            } else if ("--package".equals(opt)) {
15815                packages = true;
15816            } else if ("--checkin".equals(opt)) {
15817                isCheckinRequest = true;
15818
15819            } else if ("-h".equals(opt)) {
15820                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15821                pw.println("  -a: include all available information for each process.");
15822                pw.println("  -d: include dalvik details.");
15823                pw.println("  -c: dump in a compact machine-parseable representation.");
15824                pw.println("  -s: dump only summary of application memory usage.");
15825                pw.println("  -S: dump also SwapPss.");
15826                pw.println("  --oom: only show processes organized by oom adj.");
15827                pw.println("  --local: only collect details locally, don't call process.");
15828                pw.println("  --package: interpret process arg as package, dumping all");
15829                pw.println("             processes that have loaded that package.");
15830                pw.println("  --checkin: dump data for a checkin");
15831                pw.println("If [process] is specified it can be the name or ");
15832                pw.println("pid of a specific process to dump.");
15833                return;
15834            } else {
15835                pw.println("Unknown argument: " + opt + "; use -h for help");
15836            }
15837        }
15838
15839        long uptime = SystemClock.uptimeMillis();
15840        long realtime = SystemClock.elapsedRealtime();
15841        final long[] tmpLong = new long[1];
15842
15843        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15844        if (procs == null) {
15845            // No Java processes.  Maybe they want to print a native process.
15846            if (args != null && args.length > opti
15847                    && args[opti].charAt(0) != '-') {
15848                ArrayList<ProcessCpuTracker.Stats> nativeProcs
15849                        = new ArrayList<ProcessCpuTracker.Stats>();
15850                updateCpuStatsNow();
15851                int findPid = -1;
15852                try {
15853                    findPid = Integer.parseInt(args[opti]);
15854                } catch (NumberFormatException e) {
15855                }
15856                synchronized (mProcessCpuTracker) {
15857                    final int N = mProcessCpuTracker.countStats();
15858                    for (int i=0; i<N; i++) {
15859                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15860                        if (st.pid == findPid || (st.baseName != null
15861                                && st.baseName.equals(args[opti]))) {
15862                            nativeProcs.add(st);
15863                        }
15864                    }
15865                }
15866                if (nativeProcs.size() > 0) {
15867                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15868                            isCompact);
15869                    Debug.MemoryInfo mi = null;
15870                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15871                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15872                        final int pid = r.pid;
15873                        if (!isCheckinRequest && dumpDetails) {
15874                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15875                        }
15876                        if (mi == null) {
15877                            mi = new Debug.MemoryInfo();
15878                        }
15879                        if (dumpDetails || (!brief && !oomOnly)) {
15880                            Debug.getMemoryInfo(pid, mi);
15881                        } else {
15882                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15883                            mi.dalvikPrivateDirty = (int)tmpLong[0];
15884                        }
15885                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15886                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15887                        if (isCheckinRequest) {
15888                            pw.println();
15889                        }
15890                    }
15891                    return;
15892                }
15893            }
15894            pw.println("No process found for: " + args[opti]);
15895            return;
15896        }
15897
15898        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15899            dumpDetails = true;
15900        }
15901
15902        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15903
15904        String[] innerArgs = new String[args.length-opti];
15905        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15906
15907        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15908        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15909        long nativePss = 0;
15910        long nativeSwapPss = 0;
15911        long dalvikPss = 0;
15912        long dalvikSwapPss = 0;
15913        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15914                EmptyArray.LONG;
15915        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15916                EmptyArray.LONG;
15917        long otherPss = 0;
15918        long otherSwapPss = 0;
15919        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15920        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15921
15922        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15923        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15924        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15925                new ArrayList[DUMP_MEM_OOM_LABEL.length];
15926
15927        long totalPss = 0;
15928        long totalSwapPss = 0;
15929        long cachedPss = 0;
15930        long cachedSwapPss = 0;
15931        boolean hasSwapPss = false;
15932
15933        Debug.MemoryInfo mi = null;
15934        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15935            final ProcessRecord r = procs.get(i);
15936            final IApplicationThread thread;
15937            final int pid;
15938            final int oomAdj;
15939            final boolean hasActivities;
15940            synchronized (this) {
15941                thread = r.thread;
15942                pid = r.pid;
15943                oomAdj = r.getSetAdjWithServices();
15944                hasActivities = r.activities.size() > 0;
15945            }
15946            if (thread != null) {
15947                if (!isCheckinRequest && dumpDetails) {
15948                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15949                }
15950                if (mi == null) {
15951                    mi = new Debug.MemoryInfo();
15952                }
15953                if (dumpDetails || (!brief && !oomOnly)) {
15954                    Debug.getMemoryInfo(pid, mi);
15955                    hasSwapPss = mi.hasSwappedOutPss;
15956                } else {
15957                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15958                    mi.dalvikPrivateDirty = (int)tmpLong[0];
15959                }
15960                if (dumpDetails) {
15961                    if (localOnly) {
15962                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15963                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15964                        if (isCheckinRequest) {
15965                            pw.println();
15966                        }
15967                    } else {
15968                        try {
15969                            pw.flush();
15970                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15971                                    dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15972                        } catch (RemoteException e) {
15973                            if (!isCheckinRequest) {
15974                                pw.println("Got RemoteException!");
15975                                pw.flush();
15976                            }
15977                        }
15978                    }
15979                }
15980
15981                final long myTotalPss = mi.getTotalPss();
15982                final long myTotalUss = mi.getTotalUss();
15983                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15984
15985                synchronized (this) {
15986                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15987                        // Record this for posterity if the process has been stable.
15988                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15989                    }
15990                }
15991
15992                if (!isCheckinRequest && mi != null) {
15993                    totalPss += myTotalPss;
15994                    totalSwapPss += myTotalSwapPss;
15995                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15996                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15997                            myTotalSwapPss, pid, hasActivities);
15998                    procMems.add(pssItem);
15999                    procMemsMap.put(pid, pssItem);
16000
16001                    nativePss += mi.nativePss;
16002                    nativeSwapPss += mi.nativeSwappedOutPss;
16003                    dalvikPss += mi.dalvikPss;
16004                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16005                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16006                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16007                        dalvikSubitemSwapPss[j] +=
16008                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16009                    }
16010                    otherPss += mi.otherPss;
16011                    otherSwapPss += mi.otherSwappedOutPss;
16012                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16013                        long mem = mi.getOtherPss(j);
16014                        miscPss[j] += mem;
16015                        otherPss -= mem;
16016                        mem = mi.getOtherSwappedOutPss(j);
16017                        miscSwapPss[j] += mem;
16018                        otherSwapPss -= mem;
16019                    }
16020
16021                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16022                        cachedPss += myTotalPss;
16023                        cachedSwapPss += myTotalSwapPss;
16024                    }
16025
16026                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16027                        if (oomIndex == (oomPss.length - 1)
16028                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16029                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16030                            oomPss[oomIndex] += myTotalPss;
16031                            oomSwapPss[oomIndex] += myTotalSwapPss;
16032                            if (oomProcs[oomIndex] == null) {
16033                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16034                            }
16035                            oomProcs[oomIndex].add(pssItem);
16036                            break;
16037                        }
16038                    }
16039                }
16040            }
16041        }
16042
16043        long nativeProcTotalPss = 0;
16044
16045        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16046            // If we are showing aggregations, also look for native processes to
16047            // include so that our aggregations are more accurate.
16048            updateCpuStatsNow();
16049            mi = null;
16050            synchronized (mProcessCpuTracker) {
16051                final int N = mProcessCpuTracker.countStats();
16052                for (int i=0; i<N; i++) {
16053                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16054                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16055                        if (mi == null) {
16056                            mi = new Debug.MemoryInfo();
16057                        }
16058                        if (!brief && !oomOnly) {
16059                            Debug.getMemoryInfo(st.pid, mi);
16060                        } else {
16061                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16062                            mi.nativePrivateDirty = (int)tmpLong[0];
16063                        }
16064
16065                        final long myTotalPss = mi.getTotalPss();
16066                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16067                        totalPss += myTotalPss;
16068                        nativeProcTotalPss += myTotalPss;
16069
16070                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16071                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16072                        procMems.add(pssItem);
16073
16074                        nativePss += mi.nativePss;
16075                        nativeSwapPss += mi.nativeSwappedOutPss;
16076                        dalvikPss += mi.dalvikPss;
16077                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16078                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16079                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16080                            dalvikSubitemSwapPss[j] +=
16081                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16082                        }
16083                        otherPss += mi.otherPss;
16084                        otherSwapPss += mi.otherSwappedOutPss;
16085                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16086                            long mem = mi.getOtherPss(j);
16087                            miscPss[j] += mem;
16088                            otherPss -= mem;
16089                            mem = mi.getOtherSwappedOutPss(j);
16090                            miscSwapPss[j] += mem;
16091                            otherSwapPss -= mem;
16092                        }
16093                        oomPss[0] += myTotalPss;
16094                        oomSwapPss[0] += myTotalSwapPss;
16095                        if (oomProcs[0] == null) {
16096                            oomProcs[0] = new ArrayList<MemItem>();
16097                        }
16098                        oomProcs[0].add(pssItem);
16099                    }
16100                }
16101            }
16102
16103            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16104
16105            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16106            final MemItem dalvikItem =
16107                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16108            if (dalvikSubitemPss.length > 0) {
16109                dalvikItem.subitems = new ArrayList<MemItem>();
16110                for (int j=0; j<dalvikSubitemPss.length; j++) {
16111                    final String name = Debug.MemoryInfo.getOtherLabel(
16112                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16113                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16114                                    dalvikSubitemSwapPss[j], j));
16115                }
16116            }
16117            catMems.add(dalvikItem);
16118            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16119            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16120                String label = Debug.MemoryInfo.getOtherLabel(j);
16121                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16122            }
16123
16124            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16125            for (int j=0; j<oomPss.length; j++) {
16126                if (oomPss[j] != 0) {
16127                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16128                            : DUMP_MEM_OOM_LABEL[j];
16129                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16130                            DUMP_MEM_OOM_ADJ[j]);
16131                    item.subitems = oomProcs[j];
16132                    oomMems.add(item);
16133                }
16134            }
16135
16136            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16137            if (!brief && !oomOnly && !isCompact) {
16138                pw.println();
16139                pw.println("Total PSS by process:");
16140                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16141                pw.println();
16142            }
16143            if (!isCompact) {
16144                pw.println("Total PSS by OOM adjustment:");
16145            }
16146            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16147            if (!brief && !oomOnly) {
16148                PrintWriter out = categoryPw != null ? categoryPw : pw;
16149                if (!isCompact) {
16150                    out.println();
16151                    out.println("Total PSS by category:");
16152                }
16153                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16154            }
16155            if (!isCompact) {
16156                pw.println();
16157            }
16158            MemInfoReader memInfo = new MemInfoReader();
16159            memInfo.readMemInfo();
16160            if (nativeProcTotalPss > 0) {
16161                synchronized (this) {
16162                    final long cachedKb = memInfo.getCachedSizeKb();
16163                    final long freeKb = memInfo.getFreeSizeKb();
16164                    final long zramKb = memInfo.getZramTotalSizeKb();
16165                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16166                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16167                            kernelKb*1024, nativeProcTotalPss*1024);
16168                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16169                            nativeProcTotalPss);
16170                }
16171            }
16172            if (!brief) {
16173                if (!isCompact) {
16174                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16175                    pw.print(" (status ");
16176                    switch (mLastMemoryLevel) {
16177                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16178                            pw.println("normal)");
16179                            break;
16180                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16181                            pw.println("moderate)");
16182                            break;
16183                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16184                            pw.println("low)");
16185                            break;
16186                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16187                            pw.println("critical)");
16188                            break;
16189                        default:
16190                            pw.print(mLastMemoryLevel);
16191                            pw.println(")");
16192                            break;
16193                    }
16194                    pw.print(" Free RAM: ");
16195                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16196                            + memInfo.getFreeSizeKb()));
16197                    pw.print(" (");
16198                    pw.print(stringifyKBSize(cachedPss));
16199                    pw.print(" cached pss + ");
16200                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16201                    pw.print(" cached kernel + ");
16202                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16203                    pw.println(" free)");
16204                } else {
16205                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16206                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16207                            + memInfo.getFreeSizeKb()); pw.print(",");
16208                    pw.println(totalPss - cachedPss);
16209                }
16210            }
16211            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16212                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16213                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16214            if (!isCompact) {
16215                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16216                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16217                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16218                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16219                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16220            } else {
16221                pw.print("lostram,"); pw.println(lostRAM);
16222            }
16223            if (!brief) {
16224                if (memInfo.getZramTotalSizeKb() != 0) {
16225                    if (!isCompact) {
16226                        pw.print("     ZRAM: ");
16227                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16228                                pw.print(" physical used for ");
16229                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16230                                        - memInfo.getSwapFreeSizeKb()));
16231                                pw.print(" in swap (");
16232                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16233                                pw.println(" total swap)");
16234                    } else {
16235                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16236                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16237                                pw.println(memInfo.getSwapFreeSizeKb());
16238                    }
16239                }
16240                final long[] ksm = getKsmInfo();
16241                if (!isCompact) {
16242                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16243                            || ksm[KSM_VOLATILE] != 0) {
16244                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16245                                pw.print(" saved from shared ");
16246                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16247                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16248                                pw.print(" unshared; ");
16249                                pw.print(stringifyKBSize(
16250                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16251                    }
16252                    pw.print("   Tuning: ");
16253                    pw.print(ActivityManager.staticGetMemoryClass());
16254                    pw.print(" (large ");
16255                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16256                    pw.print("), oom ");
16257                    pw.print(stringifySize(
16258                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16259                    pw.print(", restore limit ");
16260                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16261                    if (ActivityManager.isLowRamDeviceStatic()) {
16262                        pw.print(" (low-ram)");
16263                    }
16264                    if (ActivityManager.isHighEndGfx()) {
16265                        pw.print(" (high-end-gfx)");
16266                    }
16267                    pw.println();
16268                } else {
16269                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16270                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16271                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16272                    pw.print("tuning,");
16273                    pw.print(ActivityManager.staticGetMemoryClass());
16274                    pw.print(',');
16275                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16276                    pw.print(',');
16277                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16278                    if (ActivityManager.isLowRamDeviceStatic()) {
16279                        pw.print(",low-ram");
16280                    }
16281                    if (ActivityManager.isHighEndGfx()) {
16282                        pw.print(",high-end-gfx");
16283                    }
16284                    pw.println();
16285                }
16286            }
16287        }
16288    }
16289
16290    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16291            long memtrack, String name) {
16292        sb.append("  ");
16293        sb.append(ProcessList.makeOomAdjString(oomAdj));
16294        sb.append(' ');
16295        sb.append(ProcessList.makeProcStateString(procState));
16296        sb.append(' ');
16297        ProcessList.appendRamKb(sb, pss);
16298        sb.append(": ");
16299        sb.append(name);
16300        if (memtrack > 0) {
16301            sb.append(" (");
16302            sb.append(stringifyKBSize(memtrack));
16303            sb.append(" memtrack)");
16304        }
16305    }
16306
16307    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16308        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16309        sb.append(" (pid ");
16310        sb.append(mi.pid);
16311        sb.append(") ");
16312        sb.append(mi.adjType);
16313        sb.append('\n');
16314        if (mi.adjReason != null) {
16315            sb.append("                      ");
16316            sb.append(mi.adjReason);
16317            sb.append('\n');
16318        }
16319    }
16320
16321    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16322        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16323        for (int i=0, N=memInfos.size(); i<N; i++) {
16324            ProcessMemInfo mi = memInfos.get(i);
16325            infoMap.put(mi.pid, mi);
16326        }
16327        updateCpuStatsNow();
16328        long[] memtrackTmp = new long[1];
16329        synchronized (mProcessCpuTracker) {
16330            final int N = mProcessCpuTracker.countStats();
16331            for (int i=0; i<N; i++) {
16332                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16333                if (st.vsize > 0) {
16334                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
16335                    if (pss > 0) {
16336                        if (infoMap.indexOfKey(st.pid) < 0) {
16337                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16338                                    ProcessList.NATIVE_ADJ, -1, "native", null);
16339                            mi.pss = pss;
16340                            mi.memtrack = memtrackTmp[0];
16341                            memInfos.add(mi);
16342                        }
16343                    }
16344                }
16345            }
16346        }
16347
16348        long totalPss = 0;
16349        long totalMemtrack = 0;
16350        for (int i=0, N=memInfos.size(); i<N; i++) {
16351            ProcessMemInfo mi = memInfos.get(i);
16352            if (mi.pss == 0) {
16353                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16354                mi.memtrack = memtrackTmp[0];
16355            }
16356            totalPss += mi.pss;
16357            totalMemtrack += mi.memtrack;
16358        }
16359        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16360            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16361                if (lhs.oomAdj != rhs.oomAdj) {
16362                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16363                }
16364                if (lhs.pss != rhs.pss) {
16365                    return lhs.pss < rhs.pss ? 1 : -1;
16366                }
16367                return 0;
16368            }
16369        });
16370
16371        StringBuilder tag = new StringBuilder(128);
16372        StringBuilder stack = new StringBuilder(128);
16373        tag.append("Low on memory -- ");
16374        appendMemBucket(tag, totalPss, "total", false);
16375        appendMemBucket(stack, totalPss, "total", true);
16376
16377        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16378        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16379        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16380
16381        boolean firstLine = true;
16382        int lastOomAdj = Integer.MIN_VALUE;
16383        long extraNativeRam = 0;
16384        long extraNativeMemtrack = 0;
16385        long cachedPss = 0;
16386        for (int i=0, N=memInfos.size(); i<N; i++) {
16387            ProcessMemInfo mi = memInfos.get(i);
16388
16389            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16390                cachedPss += mi.pss;
16391            }
16392
16393            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16394                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16395                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16396                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16397                if (lastOomAdj != mi.oomAdj) {
16398                    lastOomAdj = mi.oomAdj;
16399                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16400                        tag.append(" / ");
16401                    }
16402                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16403                        if (firstLine) {
16404                            stack.append(":");
16405                            firstLine = false;
16406                        }
16407                        stack.append("\n\t at ");
16408                    } else {
16409                        stack.append("$");
16410                    }
16411                } else {
16412                    tag.append(" ");
16413                    stack.append("$");
16414                }
16415                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16416                    appendMemBucket(tag, mi.pss, mi.name, false);
16417                }
16418                appendMemBucket(stack, mi.pss, mi.name, true);
16419                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16420                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16421                    stack.append("(");
16422                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16423                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16424                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16425                            stack.append(":");
16426                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16427                        }
16428                    }
16429                    stack.append(")");
16430                }
16431            }
16432
16433            appendMemInfo(fullNativeBuilder, mi);
16434            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16435                // The short form only has native processes that are >= 512K.
16436                if (mi.pss >= 512) {
16437                    appendMemInfo(shortNativeBuilder, mi);
16438                } else {
16439                    extraNativeRam += mi.pss;
16440                    extraNativeMemtrack += mi.memtrack;
16441                }
16442            } else {
16443                // Short form has all other details, but if we have collected RAM
16444                // from smaller native processes let's dump a summary of that.
16445                if (extraNativeRam > 0) {
16446                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16447                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16448                    shortNativeBuilder.append('\n');
16449                    extraNativeRam = 0;
16450                }
16451                appendMemInfo(fullJavaBuilder, mi);
16452            }
16453        }
16454
16455        fullJavaBuilder.append("           ");
16456        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16457        fullJavaBuilder.append(": TOTAL");
16458        if (totalMemtrack > 0) {
16459            fullJavaBuilder.append(" (");
16460            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16461            fullJavaBuilder.append(" memtrack)");
16462        } else {
16463        }
16464        fullJavaBuilder.append("\n");
16465
16466        MemInfoReader memInfo = new MemInfoReader();
16467        memInfo.readMemInfo();
16468        final long[] infos = memInfo.getRawInfo();
16469
16470        StringBuilder memInfoBuilder = new StringBuilder(1024);
16471        Debug.getMemInfo(infos);
16472        memInfoBuilder.append("  MemInfo: ");
16473        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16474        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16475        memInfoBuilder.append(stringifyKBSize(
16476                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16477        memInfoBuilder.append(stringifyKBSize(
16478                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16479        memInfoBuilder.append(stringifyKBSize(
16480                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16481        memInfoBuilder.append("           ");
16482        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16483        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16484        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16485        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16486        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16487            memInfoBuilder.append("  ZRAM: ");
16488            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16489            memInfoBuilder.append(" RAM, ");
16490            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16491            memInfoBuilder.append(" swap total, ");
16492            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16493            memInfoBuilder.append(" swap free\n");
16494        }
16495        final long[] ksm = getKsmInfo();
16496        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16497                || ksm[KSM_VOLATILE] != 0) {
16498            memInfoBuilder.append("  KSM: ");
16499            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16500            memInfoBuilder.append(" saved from shared ");
16501            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16502            memInfoBuilder.append("\n       ");
16503            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16504            memInfoBuilder.append(" unshared; ");
16505            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16506            memInfoBuilder.append(" volatile\n");
16507        }
16508        memInfoBuilder.append("  Free RAM: ");
16509        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16510                + memInfo.getFreeSizeKb()));
16511        memInfoBuilder.append("\n");
16512        memInfoBuilder.append("  Used RAM: ");
16513        memInfoBuilder.append(stringifyKBSize(
16514                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16515        memInfoBuilder.append("\n");
16516        memInfoBuilder.append("  Lost RAM: ");
16517        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16518                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16519                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16520        memInfoBuilder.append("\n");
16521        Slog.i(TAG, "Low on memory:");
16522        Slog.i(TAG, shortNativeBuilder.toString());
16523        Slog.i(TAG, fullJavaBuilder.toString());
16524        Slog.i(TAG, memInfoBuilder.toString());
16525
16526        StringBuilder dropBuilder = new StringBuilder(1024);
16527        /*
16528        StringWriter oomSw = new StringWriter();
16529        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16530        StringWriter catSw = new StringWriter();
16531        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16532        String[] emptyArgs = new String[] { };
16533        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16534        oomPw.flush();
16535        String oomString = oomSw.toString();
16536        */
16537        dropBuilder.append("Low on memory:");
16538        dropBuilder.append(stack);
16539        dropBuilder.append('\n');
16540        dropBuilder.append(fullNativeBuilder);
16541        dropBuilder.append(fullJavaBuilder);
16542        dropBuilder.append('\n');
16543        dropBuilder.append(memInfoBuilder);
16544        dropBuilder.append('\n');
16545        /*
16546        dropBuilder.append(oomString);
16547        dropBuilder.append('\n');
16548        */
16549        StringWriter catSw = new StringWriter();
16550        synchronized (ActivityManagerService.this) {
16551            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16552            String[] emptyArgs = new String[] { };
16553            catPw.println();
16554            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16555            catPw.println();
16556            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16557                    false, null).dumpLocked();
16558            catPw.println();
16559            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16560            catPw.flush();
16561        }
16562        dropBuilder.append(catSw.toString());
16563        addErrorToDropBox("lowmem", null, "system_server", null,
16564                null, tag.toString(), dropBuilder.toString(), null, null);
16565        //Slog.i(TAG, "Sent to dropbox:");
16566        //Slog.i(TAG, dropBuilder.toString());
16567        synchronized (ActivityManagerService.this) {
16568            long now = SystemClock.uptimeMillis();
16569            if (mLastMemUsageReportTime < now) {
16570                mLastMemUsageReportTime = now;
16571            }
16572        }
16573    }
16574
16575    /**
16576     * Searches array of arguments for the specified string
16577     * @param args array of argument strings
16578     * @param value value to search for
16579     * @return true if the value is contained in the array
16580     */
16581    private static boolean scanArgs(String[] args, String value) {
16582        if (args != null) {
16583            for (String arg : args) {
16584                if (value.equals(arg)) {
16585                    return true;
16586                }
16587            }
16588        }
16589        return false;
16590    }
16591
16592    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16593            ContentProviderRecord cpr, boolean always) {
16594        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16595
16596        if (!inLaunching || always) {
16597            synchronized (cpr) {
16598                cpr.launchingApp = null;
16599                cpr.notifyAll();
16600            }
16601            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16602            String names[] = cpr.info.authority.split(";");
16603            for (int j = 0; j < names.length; j++) {
16604                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16605            }
16606        }
16607
16608        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16609            ContentProviderConnection conn = cpr.connections.get(i);
16610            if (conn.waiting) {
16611                // If this connection is waiting for the provider, then we don't
16612                // need to mess with its process unless we are always removing
16613                // or for some reason the provider is not currently launching.
16614                if (inLaunching && !always) {
16615                    continue;
16616                }
16617            }
16618            ProcessRecord capp = conn.client;
16619            conn.dead = true;
16620            if (conn.stableCount > 0) {
16621                if (!capp.persistent && capp.thread != null
16622                        && capp.pid != 0
16623                        && capp.pid != MY_PID) {
16624                    capp.kill("depends on provider "
16625                            + cpr.name.flattenToShortString()
16626                            + " in dying proc " + (proc != null ? proc.processName : "??")
16627                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16628                }
16629            } else if (capp.thread != null && conn.provider.provider != null) {
16630                try {
16631                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16632                } catch (RemoteException e) {
16633                }
16634                // In the protocol here, we don't expect the client to correctly
16635                // clean up this connection, we'll just remove it.
16636                cpr.connections.remove(i);
16637                if (conn.client.conProviders.remove(conn)) {
16638                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16639                }
16640            }
16641        }
16642
16643        if (inLaunching && always) {
16644            mLaunchingProviders.remove(cpr);
16645        }
16646        return inLaunching;
16647    }
16648
16649    /**
16650     * Main code for cleaning up a process when it has gone away.  This is
16651     * called both as a result of the process dying, or directly when stopping
16652     * a process when running in single process mode.
16653     *
16654     * @return Returns true if the given process has been restarted, so the
16655     * app that was passed in must remain on the process lists.
16656     */
16657    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16658            boolean restarting, boolean allowRestart, int index) {
16659        if (index >= 0) {
16660            removeLruProcessLocked(app);
16661            ProcessList.remove(app.pid);
16662        }
16663
16664        mProcessesToGc.remove(app);
16665        mPendingPssProcesses.remove(app);
16666
16667        // Dismiss any open dialogs.
16668        if (app.crashDialog != null && !app.forceCrashReport) {
16669            app.crashDialog.dismiss();
16670            app.crashDialog = null;
16671        }
16672        if (app.anrDialog != null) {
16673            app.anrDialog.dismiss();
16674            app.anrDialog = null;
16675        }
16676        if (app.waitDialog != null) {
16677            app.waitDialog.dismiss();
16678            app.waitDialog = null;
16679        }
16680
16681        app.crashing = false;
16682        app.notResponding = false;
16683
16684        app.resetPackageList(mProcessStats);
16685        app.unlinkDeathRecipient();
16686        app.makeInactive(mProcessStats);
16687        app.waitingToKill = null;
16688        app.forcingToForeground = null;
16689        updateProcessForegroundLocked(app, false, false);
16690        app.foregroundActivities = false;
16691        app.hasShownUi = false;
16692        app.treatLikeActivity = false;
16693        app.hasAboveClient = false;
16694        app.hasClientActivities = false;
16695
16696        mServices.killServicesLocked(app, allowRestart);
16697
16698        boolean restart = false;
16699
16700        // Remove published content providers.
16701        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16702            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16703            final boolean always = app.bad || !allowRestart;
16704            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16705            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16706                // We left the provider in the launching list, need to
16707                // restart it.
16708                restart = true;
16709            }
16710
16711            cpr.provider = null;
16712            cpr.proc = null;
16713        }
16714        app.pubProviders.clear();
16715
16716        // Take care of any launching providers waiting for this process.
16717        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16718            restart = true;
16719        }
16720
16721        // Unregister from connected content providers.
16722        if (!app.conProviders.isEmpty()) {
16723            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16724                ContentProviderConnection conn = app.conProviders.get(i);
16725                conn.provider.connections.remove(conn);
16726                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16727                        conn.provider.name);
16728            }
16729            app.conProviders.clear();
16730        }
16731
16732        // At this point there may be remaining entries in mLaunchingProviders
16733        // where we were the only one waiting, so they are no longer of use.
16734        // Look for these and clean up if found.
16735        // XXX Commented out for now.  Trying to figure out a way to reproduce
16736        // the actual situation to identify what is actually going on.
16737        if (false) {
16738            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16739                ContentProviderRecord cpr = mLaunchingProviders.get(i);
16740                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16741                    synchronized (cpr) {
16742                        cpr.launchingApp = null;
16743                        cpr.notifyAll();
16744                    }
16745                }
16746            }
16747        }
16748
16749        skipCurrentReceiverLocked(app);
16750
16751        // Unregister any receivers.
16752        for (int i = app.receivers.size() - 1; i >= 0; i--) {
16753            removeReceiverLocked(app.receivers.valueAt(i));
16754        }
16755        app.receivers.clear();
16756
16757        // If the app is undergoing backup, tell the backup manager about it
16758        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16759            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16760                    + mBackupTarget.appInfo + " died during backup");
16761            try {
16762                IBackupManager bm = IBackupManager.Stub.asInterface(
16763                        ServiceManager.getService(Context.BACKUP_SERVICE));
16764                bm.agentDisconnected(app.info.packageName);
16765            } catch (RemoteException e) {
16766                // can't happen; backup manager is local
16767            }
16768        }
16769
16770        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16771            ProcessChangeItem item = mPendingProcessChanges.get(i);
16772            if (item.pid == app.pid) {
16773                mPendingProcessChanges.remove(i);
16774                mAvailProcessChanges.add(item);
16775            }
16776        }
16777        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16778                null).sendToTarget();
16779
16780        // If the caller is restarting this app, then leave it in its
16781        // current lists and let the caller take care of it.
16782        if (restarting) {
16783            return false;
16784        }
16785
16786        if (!app.persistent || app.isolated) {
16787            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16788                    "Removing non-persistent process during cleanup: " + app);
16789            removeProcessNameLocked(app.processName, app.uid);
16790            if (mHeavyWeightProcess == app) {
16791                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16792                        mHeavyWeightProcess.userId, 0));
16793                mHeavyWeightProcess = null;
16794            }
16795        } else if (!app.removed) {
16796            // This app is persistent, so we need to keep its record around.
16797            // If it is not already on the pending app list, add it there
16798            // and start a new process for it.
16799            if (mPersistentStartingProcesses.indexOf(app) < 0) {
16800                mPersistentStartingProcesses.add(app);
16801                restart = true;
16802            }
16803        }
16804        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16805                TAG_CLEANUP, "Clean-up removing on hold: " + app);
16806        mProcessesOnHold.remove(app);
16807
16808        if (app == mHomeProcess) {
16809            mHomeProcess = null;
16810        }
16811        if (app == mPreviousProcess) {
16812            mPreviousProcess = null;
16813        }
16814
16815        if (restart && !app.isolated) {
16816            // We have components that still need to be running in the
16817            // process, so re-launch it.
16818            if (index < 0) {
16819                ProcessList.remove(app.pid);
16820            }
16821            addProcessNameLocked(app);
16822            startProcessLocked(app, "restart", app.processName);
16823            return true;
16824        } else if (app.pid > 0 && app.pid != MY_PID) {
16825            // Goodbye!
16826            boolean removed;
16827            synchronized (mPidsSelfLocked) {
16828                mPidsSelfLocked.remove(app.pid);
16829                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16830            }
16831            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16832            if (app.isolated) {
16833                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16834            }
16835            app.setPid(0);
16836        }
16837        return false;
16838    }
16839
16840    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16841        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16842            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16843            if (cpr.launchingApp == app) {
16844                return true;
16845            }
16846        }
16847        return false;
16848    }
16849
16850    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16851        // Look through the content providers we are waiting to have launched,
16852        // and if any run in this process then either schedule a restart of
16853        // the process or kill the client waiting for it if this process has
16854        // gone bad.
16855        boolean restart = false;
16856        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16857            ContentProviderRecord cpr = mLaunchingProviders.get(i);
16858            if (cpr.launchingApp == app) {
16859                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16860                    restart = true;
16861                } else {
16862                    removeDyingProviderLocked(app, cpr, true);
16863                }
16864            }
16865        }
16866        return restart;
16867    }
16868
16869    // =========================================================
16870    // SERVICES
16871    // =========================================================
16872
16873    @Override
16874    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16875            int flags) {
16876        enforceNotIsolatedCaller("getServices");
16877        synchronized (this) {
16878            return mServices.getRunningServiceInfoLocked(maxNum, flags);
16879        }
16880    }
16881
16882    @Override
16883    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16884        enforceNotIsolatedCaller("getRunningServiceControlPanel");
16885        synchronized (this) {
16886            return mServices.getRunningServiceControlPanelLocked(name);
16887        }
16888    }
16889
16890    @Override
16891    public ComponentName startService(IApplicationThread caller, Intent service,
16892            String resolvedType, String callingPackage, int userId)
16893            throws TransactionTooLargeException {
16894        enforceNotIsolatedCaller("startService");
16895        // Refuse possible leaked file descriptors
16896        if (service != null && service.hasFileDescriptors() == true) {
16897            throw new IllegalArgumentException("File descriptors passed in Intent");
16898        }
16899
16900        if (callingPackage == null) {
16901            throw new IllegalArgumentException("callingPackage cannot be null");
16902        }
16903
16904        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16905                "startService: " + service + " type=" + resolvedType);
16906        synchronized(this) {
16907            final int callingPid = Binder.getCallingPid();
16908            final int callingUid = Binder.getCallingUid();
16909            final long origId = Binder.clearCallingIdentity();
16910            ComponentName res = mServices.startServiceLocked(caller, service,
16911                    resolvedType, callingPid, callingUid, callingPackage, userId);
16912            Binder.restoreCallingIdentity(origId);
16913            return res;
16914        }
16915    }
16916
16917    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16918            String callingPackage, int userId)
16919            throws TransactionTooLargeException {
16920        synchronized(this) {
16921            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16922                    "startServiceInPackage: " + service + " type=" + resolvedType);
16923            final long origId = Binder.clearCallingIdentity();
16924            ComponentName res = mServices.startServiceLocked(null, service,
16925                    resolvedType, -1, uid, callingPackage, userId);
16926            Binder.restoreCallingIdentity(origId);
16927            return res;
16928        }
16929    }
16930
16931    @Override
16932    public int stopService(IApplicationThread caller, Intent service,
16933            String resolvedType, int userId) {
16934        enforceNotIsolatedCaller("stopService");
16935        // Refuse possible leaked file descriptors
16936        if (service != null && service.hasFileDescriptors() == true) {
16937            throw new IllegalArgumentException("File descriptors passed in Intent");
16938        }
16939
16940        synchronized(this) {
16941            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16942        }
16943    }
16944
16945    @Override
16946    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16947        enforceNotIsolatedCaller("peekService");
16948        // Refuse possible leaked file descriptors
16949        if (service != null && service.hasFileDescriptors() == true) {
16950            throw new IllegalArgumentException("File descriptors passed in Intent");
16951        }
16952
16953        if (callingPackage == null) {
16954            throw new IllegalArgumentException("callingPackage cannot be null");
16955        }
16956
16957        synchronized(this) {
16958            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16959        }
16960    }
16961
16962    @Override
16963    public boolean stopServiceToken(ComponentName className, IBinder token,
16964            int startId) {
16965        synchronized(this) {
16966            return mServices.stopServiceTokenLocked(className, token, startId);
16967        }
16968    }
16969
16970    @Override
16971    public void setServiceForeground(ComponentName className, IBinder token,
16972            int id, Notification notification, int flags) {
16973        synchronized(this) {
16974            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16975        }
16976    }
16977
16978    @Override
16979    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16980            boolean requireFull, String name, String callerPackage) {
16981        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16982                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16983    }
16984
16985    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16986            String className, int flags) {
16987        boolean result = false;
16988        // For apps that don't have pre-defined UIDs, check for permission
16989        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16990            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16991                if (ActivityManager.checkUidPermission(
16992                        INTERACT_ACROSS_USERS,
16993                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16994                    ComponentName comp = new ComponentName(aInfo.packageName, className);
16995                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
16996                            + " requests FLAG_SINGLE_USER, but app does not hold "
16997                            + INTERACT_ACROSS_USERS;
16998                    Slog.w(TAG, msg);
16999                    throw new SecurityException(msg);
17000                }
17001                // Permission passed
17002                result = true;
17003            }
17004        } else if ("system".equals(componentProcessName)) {
17005            result = true;
17006        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17007            // Phone app and persistent apps are allowed to export singleuser providers.
17008            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17009                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17010        }
17011        if (DEBUG_MU) Slog.v(TAG_MU,
17012                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17013                + Integer.toHexString(flags) + ") = " + result);
17014        return result;
17015    }
17016
17017    /**
17018     * Checks to see if the caller is in the same app as the singleton
17019     * component, or the component is in a special app. It allows special apps
17020     * to export singleton components but prevents exporting singleton
17021     * components for regular apps.
17022     */
17023    boolean isValidSingletonCall(int callingUid, int componentUid) {
17024        int componentAppId = UserHandle.getAppId(componentUid);
17025        return UserHandle.isSameApp(callingUid, componentUid)
17026                || componentAppId == Process.SYSTEM_UID
17027                || componentAppId == Process.PHONE_UID
17028                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17029                        == PackageManager.PERMISSION_GRANTED;
17030    }
17031
17032    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17033            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17034            int userId) throws TransactionTooLargeException {
17035        enforceNotIsolatedCaller("bindService");
17036
17037        // Refuse possible leaked file descriptors
17038        if (service != null && service.hasFileDescriptors() == true) {
17039            throw new IllegalArgumentException("File descriptors passed in Intent");
17040        }
17041
17042        if (callingPackage == null) {
17043            throw new IllegalArgumentException("callingPackage cannot be null");
17044        }
17045
17046        synchronized(this) {
17047            return mServices.bindServiceLocked(caller, token, service,
17048                    resolvedType, connection, flags, callingPackage, userId);
17049        }
17050    }
17051
17052    public boolean unbindService(IServiceConnection connection) {
17053        synchronized (this) {
17054            return mServices.unbindServiceLocked(connection);
17055        }
17056    }
17057
17058    public void publishService(IBinder token, Intent intent, IBinder service) {
17059        // Refuse possible leaked file descriptors
17060        if (intent != null && intent.hasFileDescriptors() == true) {
17061            throw new IllegalArgumentException("File descriptors passed in Intent");
17062        }
17063
17064        synchronized(this) {
17065            if (!(token instanceof ServiceRecord)) {
17066                throw new IllegalArgumentException("Invalid service token");
17067            }
17068            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17069        }
17070    }
17071
17072    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17073        // Refuse possible leaked file descriptors
17074        if (intent != null && intent.hasFileDescriptors() == true) {
17075            throw new IllegalArgumentException("File descriptors passed in Intent");
17076        }
17077
17078        synchronized(this) {
17079            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17080        }
17081    }
17082
17083    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17084        synchronized(this) {
17085            if (!(token instanceof ServiceRecord)) {
17086                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17087                throw new IllegalArgumentException("Invalid service token");
17088            }
17089            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17090        }
17091    }
17092
17093    // =========================================================
17094    // BACKUP AND RESTORE
17095    // =========================================================
17096
17097    // Cause the target app to be launched if necessary and its backup agent
17098    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17099    // activity manager to announce its creation.
17100    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17101        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17102        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17103
17104        IPackageManager pm = AppGlobals.getPackageManager();
17105        ApplicationInfo app = null;
17106        try {
17107            app = pm.getApplicationInfo(packageName, 0, userId);
17108        } catch (RemoteException e) {
17109            // can't happen; package manager is process-local
17110        }
17111        if (app == null) {
17112            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17113            return false;
17114        }
17115
17116        synchronized(this) {
17117            // !!! TODO: currently no check here that we're already bound
17118            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17119            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17120            synchronized (stats) {
17121                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17122            }
17123
17124            // Backup agent is now in use, its package can't be stopped.
17125            try {
17126                AppGlobals.getPackageManager().setPackageStoppedState(
17127                        app.packageName, false, UserHandle.getUserId(app.uid));
17128            } catch (RemoteException e) {
17129            } catch (IllegalArgumentException e) {
17130                Slog.w(TAG, "Failed trying to unstop package "
17131                        + app.packageName + ": " + e);
17132            }
17133
17134            BackupRecord r = new BackupRecord(ss, app, backupMode);
17135            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17136                    ? new ComponentName(app.packageName, app.backupAgentName)
17137                    : new ComponentName("android", "FullBackupAgent");
17138            // startProcessLocked() returns existing proc's record if it's already running
17139            ProcessRecord proc = startProcessLocked(app.processName, app,
17140                    false, 0, "backup", hostingName, false, false, false);
17141            if (proc == null) {
17142                Slog.e(TAG, "Unable to start backup agent process " + r);
17143                return false;
17144            }
17145
17146            // If the app is a regular app (uid >= 10000) and not the system server or phone
17147            // process, etc, then mark it as being in full backup so that certain calls to the
17148            // process can be blocked. This is not reset to false anywhere because we kill the
17149            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17150            if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17151                proc.inFullBackup = true;
17152            }
17153            r.app = proc;
17154            mBackupTarget = r;
17155            mBackupAppName = app.packageName;
17156
17157            // Try not to kill the process during backup
17158            updateOomAdjLocked(proc);
17159
17160            // If the process is already attached, schedule the creation of the backup agent now.
17161            // If it is not yet live, this will be done when it attaches to the framework.
17162            if (proc.thread != null) {
17163                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17164                try {
17165                    proc.thread.scheduleCreateBackupAgent(app,
17166                            compatibilityInfoForPackageLocked(app), backupMode);
17167                } catch (RemoteException e) {
17168                    // Will time out on the backup manager side
17169                }
17170            } else {
17171                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17172            }
17173            // Invariants: at this point, the target app process exists and the application
17174            // is either already running or in the process of coming up.  mBackupTarget and
17175            // mBackupAppName describe the app, so that when it binds back to the AM we
17176            // know that it's scheduled for a backup-agent operation.
17177        }
17178
17179        return true;
17180    }
17181
17182    @Override
17183    public void clearPendingBackup() {
17184        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17185        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17186
17187        synchronized (this) {
17188            mBackupTarget = null;
17189            mBackupAppName = null;
17190        }
17191    }
17192
17193    // A backup agent has just come up
17194    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17195        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17196                + " = " + agent);
17197
17198        synchronized(this) {
17199            if (!agentPackageName.equals(mBackupAppName)) {
17200                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17201                return;
17202            }
17203        }
17204
17205        long oldIdent = Binder.clearCallingIdentity();
17206        try {
17207            IBackupManager bm = IBackupManager.Stub.asInterface(
17208                    ServiceManager.getService(Context.BACKUP_SERVICE));
17209            bm.agentConnected(agentPackageName, agent);
17210        } catch (RemoteException e) {
17211            // can't happen; the backup manager service is local
17212        } catch (Exception e) {
17213            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17214            e.printStackTrace();
17215        } finally {
17216            Binder.restoreCallingIdentity(oldIdent);
17217        }
17218    }
17219
17220    // done with this agent
17221    public void unbindBackupAgent(ApplicationInfo appInfo) {
17222        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17223        if (appInfo == null) {
17224            Slog.w(TAG, "unbind backup agent for null app");
17225            return;
17226        }
17227
17228        synchronized(this) {
17229            try {
17230                if (mBackupAppName == null) {
17231                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17232                    return;
17233                }
17234
17235                if (!mBackupAppName.equals(appInfo.packageName)) {
17236                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17237                    return;
17238                }
17239
17240                // Not backing this app up any more; reset its OOM adjustment
17241                final ProcessRecord proc = mBackupTarget.app;
17242                updateOomAdjLocked(proc);
17243
17244                // If the app crashed during backup, 'thread' will be null here
17245                if (proc.thread != null) {
17246                    try {
17247                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17248                                compatibilityInfoForPackageLocked(appInfo));
17249                    } catch (Exception e) {
17250                        Slog.e(TAG, "Exception when unbinding backup agent:");
17251                        e.printStackTrace();
17252                    }
17253                }
17254            } finally {
17255                mBackupTarget = null;
17256                mBackupAppName = null;
17257            }
17258        }
17259    }
17260    // =========================================================
17261    // BROADCASTS
17262    // =========================================================
17263
17264    boolean isPendingBroadcastProcessLocked(int pid) {
17265        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17266                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17267    }
17268
17269    void skipPendingBroadcastLocked(int pid) {
17270            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17271            for (BroadcastQueue queue : mBroadcastQueues) {
17272                queue.skipPendingBroadcastLocked(pid);
17273            }
17274    }
17275
17276    // The app just attached; send any pending broadcasts that it should receive
17277    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17278        boolean didSomething = false;
17279        for (BroadcastQueue queue : mBroadcastQueues) {
17280            didSomething |= queue.sendPendingBroadcastsLocked(app);
17281        }
17282        return didSomething;
17283    }
17284
17285    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17286            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17287        enforceNotIsolatedCaller("registerReceiver");
17288        ArrayList<Intent> stickyIntents = null;
17289        ProcessRecord callerApp = null;
17290        int callingUid;
17291        int callingPid;
17292        synchronized(this) {
17293            if (caller != null) {
17294                callerApp = getRecordForAppLocked(caller);
17295                if (callerApp == null) {
17296                    throw new SecurityException(
17297                            "Unable to find app for caller " + caller
17298                            + " (pid=" + Binder.getCallingPid()
17299                            + ") when registering receiver " + receiver);
17300                }
17301                if (callerApp.info.uid != Process.SYSTEM_UID &&
17302                        !callerApp.pkgList.containsKey(callerPackage) &&
17303                        !"android".equals(callerPackage)) {
17304                    throw new SecurityException("Given caller package " + callerPackage
17305                            + " is not running in process " + callerApp);
17306                }
17307                callingUid = callerApp.info.uid;
17308                callingPid = callerApp.pid;
17309            } else {
17310                callerPackage = null;
17311                callingUid = Binder.getCallingUid();
17312                callingPid = Binder.getCallingPid();
17313            }
17314
17315            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17316                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17317
17318            Iterator<String> actions = filter.actionsIterator();
17319            if (actions == null) {
17320                ArrayList<String> noAction = new ArrayList<String>(1);
17321                noAction.add(null);
17322                actions = noAction.iterator();
17323            }
17324
17325            // Collect stickies of users
17326            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17327            while (actions.hasNext()) {
17328                String action = actions.next();
17329                for (int id : userIds) {
17330                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17331                    if (stickies != null) {
17332                        ArrayList<Intent> intents = stickies.get(action);
17333                        if (intents != null) {
17334                            if (stickyIntents == null) {
17335                                stickyIntents = new ArrayList<Intent>();
17336                            }
17337                            stickyIntents.addAll(intents);
17338                        }
17339                    }
17340                }
17341            }
17342        }
17343
17344        ArrayList<Intent> allSticky = null;
17345        if (stickyIntents != null) {
17346            final ContentResolver resolver = mContext.getContentResolver();
17347            // Look for any matching sticky broadcasts...
17348            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17349                Intent intent = stickyIntents.get(i);
17350                // If intent has scheme "content", it will need to acccess
17351                // provider that needs to lock mProviderMap in ActivityThread
17352                // and also it may need to wait application response, so we
17353                // cannot lock ActivityManagerService here.
17354                if (filter.match(resolver, intent, true, TAG) >= 0) {
17355                    if (allSticky == null) {
17356                        allSticky = new ArrayList<Intent>();
17357                    }
17358                    allSticky.add(intent);
17359                }
17360            }
17361        }
17362
17363        // The first sticky in the list is returned directly back to the client.
17364        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17365        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17366        if (receiver == null) {
17367            return sticky;
17368        }
17369
17370        synchronized (this) {
17371            if (callerApp != null && (callerApp.thread == null
17372                    || callerApp.thread.asBinder() != caller.asBinder())) {
17373                // Original caller already died
17374                return null;
17375            }
17376            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17377            if (rl == null) {
17378                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17379                        userId, receiver);
17380                if (rl.app != null) {
17381                    rl.app.receivers.add(rl);
17382                } else {
17383                    try {
17384                        receiver.asBinder().linkToDeath(rl, 0);
17385                    } catch (RemoteException e) {
17386                        return sticky;
17387                    }
17388                    rl.linkedToDeath = true;
17389                }
17390                mRegisteredReceivers.put(receiver.asBinder(), rl);
17391            } else if (rl.uid != callingUid) {
17392                throw new IllegalArgumentException(
17393                        "Receiver requested to register for uid " + callingUid
17394                        + " was previously registered for uid " + rl.uid);
17395            } else if (rl.pid != callingPid) {
17396                throw new IllegalArgumentException(
17397                        "Receiver requested to register for pid " + callingPid
17398                        + " was previously registered for pid " + rl.pid);
17399            } else if (rl.userId != userId) {
17400                throw new IllegalArgumentException(
17401                        "Receiver requested to register for user " + userId
17402                        + " was previously registered for user " + rl.userId);
17403            }
17404            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17405                    permission, callingUid, userId);
17406            rl.add(bf);
17407            if (!bf.debugCheck()) {
17408                Slog.w(TAG, "==> For Dynamic broadcast");
17409            }
17410            mReceiverResolver.addFilter(bf);
17411
17412            // Enqueue broadcasts for all existing stickies that match
17413            // this filter.
17414            if (allSticky != null) {
17415                ArrayList receivers = new ArrayList();
17416                receivers.add(bf);
17417
17418                final int stickyCount = allSticky.size();
17419                for (int i = 0; i < stickyCount; i++) {
17420                    Intent intent = allSticky.get(i);
17421                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17422                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17423                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17424                            null, 0, null, null, false, true, true, -1);
17425                    queue.enqueueParallelBroadcastLocked(r);
17426                    queue.scheduleBroadcastsLocked();
17427                }
17428            }
17429
17430            return sticky;
17431        }
17432    }
17433
17434    public void unregisterReceiver(IIntentReceiver receiver) {
17435        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17436
17437        final long origId = Binder.clearCallingIdentity();
17438        try {
17439            boolean doTrim = false;
17440
17441            synchronized(this) {
17442                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17443                if (rl != null) {
17444                    final BroadcastRecord r = rl.curBroadcast;
17445                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17446                        final boolean doNext = r.queue.finishReceiverLocked(
17447                                r, r.resultCode, r.resultData, r.resultExtras,
17448                                r.resultAbort, false);
17449                        if (doNext) {
17450                            doTrim = true;
17451                            r.queue.processNextBroadcast(false);
17452                        }
17453                    }
17454
17455                    if (rl.app != null) {
17456                        rl.app.receivers.remove(rl);
17457                    }
17458                    removeReceiverLocked(rl);
17459                    if (rl.linkedToDeath) {
17460                        rl.linkedToDeath = false;
17461                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17462                    }
17463                }
17464            }
17465
17466            // If we actually concluded any broadcasts, we might now be able
17467            // to trim the recipients' apps from our working set
17468            if (doTrim) {
17469                trimApplications();
17470                return;
17471            }
17472
17473        } finally {
17474            Binder.restoreCallingIdentity(origId);
17475        }
17476    }
17477
17478    void removeReceiverLocked(ReceiverList rl) {
17479        mRegisteredReceivers.remove(rl.receiver.asBinder());
17480        for (int i = rl.size() - 1; i >= 0; i--) {
17481            mReceiverResolver.removeFilter(rl.get(i));
17482        }
17483    }
17484
17485    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17486        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17487            ProcessRecord r = mLruProcesses.get(i);
17488            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17489                try {
17490                    r.thread.dispatchPackageBroadcast(cmd, packages);
17491                } catch (RemoteException ex) {
17492                }
17493            }
17494        }
17495    }
17496
17497    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17498            int callingUid, int[] users) {
17499        // TODO: come back and remove this assumption to triage all broadcasts
17500        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17501
17502        List<ResolveInfo> receivers = null;
17503        try {
17504            HashSet<ComponentName> singleUserReceivers = null;
17505            boolean scannedFirstReceivers = false;
17506            for (int user : users) {
17507                // Skip users that have Shell restrictions, with exception of always permitted
17508                // Shell broadcasts
17509                if (callingUid == Process.SHELL_UID
17510                        && mUserController.hasUserRestriction(
17511                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17512                        && !isPermittedShellBroadcast(intent)) {
17513                    continue;
17514                }
17515                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17516                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17517                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17518                    // If this is not the system user, we need to check for
17519                    // any receivers that should be filtered out.
17520                    for (int i=0; i<newReceivers.size(); i++) {
17521                        ResolveInfo ri = newReceivers.get(i);
17522                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17523                            newReceivers.remove(i);
17524                            i--;
17525                        }
17526                    }
17527                }
17528                if (newReceivers != null && newReceivers.size() == 0) {
17529                    newReceivers = null;
17530                }
17531                if (receivers == null) {
17532                    receivers = newReceivers;
17533                } else if (newReceivers != null) {
17534                    // We need to concatenate the additional receivers
17535                    // found with what we have do far.  This would be easy,
17536                    // but we also need to de-dup any receivers that are
17537                    // singleUser.
17538                    if (!scannedFirstReceivers) {
17539                        // Collect any single user receivers we had already retrieved.
17540                        scannedFirstReceivers = true;
17541                        for (int i=0; i<receivers.size(); i++) {
17542                            ResolveInfo ri = receivers.get(i);
17543                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17544                                ComponentName cn = new ComponentName(
17545                                        ri.activityInfo.packageName, ri.activityInfo.name);
17546                                if (singleUserReceivers == null) {
17547                                    singleUserReceivers = new HashSet<ComponentName>();
17548                                }
17549                                singleUserReceivers.add(cn);
17550                            }
17551                        }
17552                    }
17553                    // Add the new results to the existing results, tracking
17554                    // and de-dupping single user receivers.
17555                    for (int i=0; i<newReceivers.size(); i++) {
17556                        ResolveInfo ri = newReceivers.get(i);
17557                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17558                            ComponentName cn = new ComponentName(
17559                                    ri.activityInfo.packageName, ri.activityInfo.name);
17560                            if (singleUserReceivers == null) {
17561                                singleUserReceivers = new HashSet<ComponentName>();
17562                            }
17563                            if (!singleUserReceivers.contains(cn)) {
17564                                singleUserReceivers.add(cn);
17565                                receivers.add(ri);
17566                            }
17567                        } else {
17568                            receivers.add(ri);
17569                        }
17570                    }
17571                }
17572            }
17573        } catch (RemoteException ex) {
17574            // pm is in same process, this will never happen.
17575        }
17576        return receivers;
17577    }
17578
17579    private boolean isPermittedShellBroadcast(Intent intent) {
17580        // remote bugreport should always be allowed to be taken
17581        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17582    }
17583
17584    final int broadcastIntentLocked(ProcessRecord callerApp,
17585            String callerPackage, Intent intent, String resolvedType,
17586            IIntentReceiver resultTo, int resultCode, String resultData,
17587            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17588            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17589        intent = new Intent(intent);
17590
17591        // By default broadcasts do not go to stopped apps.
17592        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17593
17594        // If we have not finished booting, don't allow this to launch new processes.
17595        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17596            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17597        }
17598
17599        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17600                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17601                + " ordered=" + ordered + " userid=" + userId);
17602        if ((resultTo != null) && !ordered) {
17603            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17604        }
17605
17606        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17607                ALLOW_NON_FULL, "broadcast", callerPackage);
17608
17609        // Make sure that the user who is receiving this broadcast is running.
17610        // If not, we will just skip it. Make an exception for shutdown broadcasts
17611        // and upgrade steps.
17612
17613        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17614            if ((callingUid != Process.SYSTEM_UID
17615                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17616                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17617                Slog.w(TAG, "Skipping broadcast of " + intent
17618                        + ": user " + userId + " is stopped");
17619                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17620            }
17621        }
17622
17623        BroadcastOptions brOptions = null;
17624        if (bOptions != null) {
17625            brOptions = new BroadcastOptions(bOptions);
17626            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17627                // See if the caller is allowed to do this.  Note we are checking against
17628                // the actual real caller (not whoever provided the operation as say a
17629                // PendingIntent), because that who is actually supplied the arguments.
17630                if (checkComponentPermission(
17631                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17632                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17633                        != PackageManager.PERMISSION_GRANTED) {
17634                    String msg = "Permission Denial: " + intent.getAction()
17635                            + " broadcast from " + callerPackage + " (pid=" + callingPid
17636                            + ", uid=" + callingUid + ")"
17637                            + " requires "
17638                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17639                    Slog.w(TAG, msg);
17640                    throw new SecurityException(msg);
17641                }
17642            }
17643        }
17644
17645        // Verify that protected broadcasts are only being sent by system code,
17646        // and that system code is only sending protected broadcasts.
17647        final String action = intent.getAction();
17648        final boolean isProtectedBroadcast;
17649        try {
17650            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17651        } catch (RemoteException e) {
17652            Slog.w(TAG, "Remote exception", e);
17653            return ActivityManager.BROADCAST_SUCCESS;
17654        }
17655
17656        final boolean isCallerSystem;
17657        switch (UserHandle.getAppId(callingUid)) {
17658            case Process.ROOT_UID:
17659            case Process.SYSTEM_UID:
17660            case Process.PHONE_UID:
17661            case Process.BLUETOOTH_UID:
17662            case Process.NFC_UID:
17663                isCallerSystem = true;
17664                break;
17665            default:
17666                isCallerSystem = (callerApp != null) && callerApp.persistent;
17667                break;
17668        }
17669
17670        if (isCallerSystem) {
17671            if (isProtectedBroadcast
17672                    || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17673                    || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17674                    || Intent.ACTION_MEDIA_BUTTON.equals(action)
17675                    || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17676                    || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17677                    || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17678                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17679                    || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17680                    || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17681                    || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17682                // Broadcast is either protected, or it's a public action that
17683                // we've relaxed, so it's fine for system internals to send.
17684            } else {
17685                // The vast majority of broadcasts sent from system internals
17686                // should be protected to avoid security holes, so yell loudly
17687                // to ensure we examine these cases.
17688                if (callerApp != null) {
17689                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17690                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17691                            new Throwable());
17692                } else {
17693                    Log.wtf(TAG, "Sending non-protected broadcast " + action
17694                            + " from system uid " + UserHandle.formatUid(callingUid)
17695                            + " pkg " + callerPackage,
17696                            new Throwable());
17697                }
17698            }
17699
17700        } else {
17701            if (isProtectedBroadcast) {
17702                String msg = "Permission Denial: not allowed to send broadcast "
17703                        + action + " from pid="
17704                        + callingPid + ", uid=" + callingUid;
17705                Slog.w(TAG, msg);
17706                throw new SecurityException(msg);
17707
17708            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17709                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17710                // Special case for compatibility: we don't want apps to send this,
17711                // but historically it has not been protected and apps may be using it
17712                // to poke their own app widget.  So, instead of making it protected,
17713                // just limit it to the caller.
17714                if (callerPackage == null) {
17715                    String msg = "Permission Denial: not allowed to send broadcast "
17716                            + action + " from unknown caller.";
17717                    Slog.w(TAG, msg);
17718                    throw new SecurityException(msg);
17719                } else if (intent.getComponent() != null) {
17720                    // They are good enough to send to an explicit component...  verify
17721                    // it is being sent to the calling app.
17722                    if (!intent.getComponent().getPackageName().equals(
17723                            callerPackage)) {
17724                        String msg = "Permission Denial: not allowed to send broadcast "
17725                                + action + " to "
17726                                + intent.getComponent().getPackageName() + " from "
17727                                + callerPackage;
17728                        Slog.w(TAG, msg);
17729                        throw new SecurityException(msg);
17730                    }
17731                } else {
17732                    // Limit broadcast to their own package.
17733                    intent.setPackage(callerPackage);
17734                }
17735            }
17736        }
17737
17738        if (action != null) {
17739            switch (action) {
17740                case Intent.ACTION_UID_REMOVED:
17741                case Intent.ACTION_PACKAGE_REMOVED:
17742                case Intent.ACTION_PACKAGE_CHANGED:
17743                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17744                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17745                case Intent.ACTION_PACKAGES_SUSPENDED:
17746                case Intent.ACTION_PACKAGES_UNSUSPENDED:
17747                    // Handle special intents: if this broadcast is from the package
17748                    // manager about a package being removed, we need to remove all of
17749                    // its activities from the history stack.
17750                    if (checkComponentPermission(
17751                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17752                            callingPid, callingUid, -1, true)
17753                            != PackageManager.PERMISSION_GRANTED) {
17754                        String msg = "Permission Denial: " + intent.getAction()
17755                                + " broadcast from " + callerPackage + " (pid=" + callingPid
17756                                + ", uid=" + callingUid + ")"
17757                                + " requires "
17758                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17759                        Slog.w(TAG, msg);
17760                        throw new SecurityException(msg);
17761                    }
17762                    switch (action) {
17763                        case Intent.ACTION_UID_REMOVED:
17764                            final Bundle intentExtras = intent.getExtras();
17765                            final int uid = intentExtras != null
17766                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17767                            if (uid >= 0) {
17768                                mBatteryStatsService.removeUid(uid);
17769                                mAppOpsService.uidRemoved(uid);
17770                            }
17771                            break;
17772                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17773                            // If resources are unavailable just force stop all those packages
17774                            // and flush the attribute cache as well.
17775                            String list[] =
17776                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17777                            if (list != null && list.length > 0) {
17778                                for (int i = 0; i < list.length; i++) {
17779                                    forceStopPackageLocked(list[i], -1, false, true, true,
17780                                            false, false, userId, "storage unmount");
17781                                }
17782                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17783                                sendPackageBroadcastLocked(
17784                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17785                                        userId);
17786                            }
17787                            break;
17788                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17789                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17790                            break;
17791                        case Intent.ACTION_PACKAGE_REMOVED:
17792                        case Intent.ACTION_PACKAGE_CHANGED:
17793                            Uri data = intent.getData();
17794                            String ssp;
17795                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17796                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17797                                final boolean replacing =
17798                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17799                                final boolean killProcess =
17800                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17801                                final boolean fullUninstall = removed && !replacing;
17802                                if (removed) {
17803                                    if (killProcess) {
17804                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
17805                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17806                                                false, true, true, false, fullUninstall, userId,
17807                                                removed ? "pkg removed" : "pkg changed");
17808                                    }
17809                                    final int cmd = killProcess
17810                                            ? IApplicationThread.PACKAGE_REMOVED
17811                                            : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17812                                    sendPackageBroadcastLocked(cmd,
17813                                            new String[] {ssp}, userId);
17814                                    if (fullUninstall) {
17815                                        mAppOpsService.packageRemoved(
17816                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17817
17818                                        // Remove all permissions granted from/to this package
17819                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
17820
17821                                        removeTasksByPackageNameLocked(ssp, userId);
17822
17823                                        // Hide the "unsupported display" dialog if necessary.
17824                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17825                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17826                                            mUnsupportedDisplaySizeDialog.dismiss();
17827                                            mUnsupportedDisplaySizeDialog = null;
17828                                        }
17829                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
17830                                        mBatteryStatsService.notePackageUninstalled(ssp);
17831                                    }
17832                                } else {
17833                                    if (killProcess) {
17834                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
17835                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
17836                                                userId, ProcessList.INVALID_ADJ,
17837                                                false, true, true, false, "change " + ssp);
17838                                    }
17839                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17840                                            intent.getStringArrayExtra(
17841                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17842                                }
17843                            }
17844                            break;
17845                        case Intent.ACTION_PACKAGES_SUSPENDED:
17846                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
17847                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17848                                    intent.getAction());
17849                            final String[] packageNames = intent.getStringArrayExtra(
17850                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
17851                            final int userHandle = intent.getIntExtra(
17852                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17853
17854                            synchronized(ActivityManagerService.this) {
17855                                mRecentTasks.onPackagesSuspendedChanged(
17856                                        packageNames, suspended, userHandle);
17857                            }
17858                            break;
17859                    }
17860                    break;
17861                case Intent.ACTION_PACKAGE_REPLACED:
17862                {
17863                    final Uri data = intent.getData();
17864                    final String ssp;
17865                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17866                        final ApplicationInfo aInfo =
17867                                getPackageManagerInternalLocked().getApplicationInfo(
17868                                        ssp,
17869                                        userId);
17870                        if (aInfo == null) {
17871                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17872                                    + " ssp=" + ssp + " data=" + data);
17873                            return ActivityManager.BROADCAST_SUCCESS;
17874                        }
17875                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17876                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17877                                new String[] {ssp}, userId);
17878                    }
17879                    break;
17880                }
17881                case Intent.ACTION_PACKAGE_ADDED:
17882                {
17883                    // Special case for adding a package: by default turn on compatibility mode.
17884                    Uri data = intent.getData();
17885                    String ssp;
17886                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17887                        final boolean replacing =
17888                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17889                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17890
17891                        try {
17892                            ApplicationInfo ai = AppGlobals.getPackageManager().
17893                                    getApplicationInfo(ssp, 0, 0);
17894                            mBatteryStatsService.notePackageInstalled(ssp,
17895                                    ai != null ? ai.versionCode : 0);
17896                        } catch (RemoteException e) {
17897                        }
17898                    }
17899                    break;
17900                }
17901                case Intent.ACTION_PACKAGE_DATA_CLEARED:
17902                {
17903                    Uri data = intent.getData();
17904                    String ssp;
17905                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17906                        // Hide the "unsupported display" dialog if necessary.
17907                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
17908                                mUnsupportedDisplaySizeDialog.getPackageName())) {
17909                            mUnsupportedDisplaySizeDialog.dismiss();
17910                            mUnsupportedDisplaySizeDialog = null;
17911                        }
17912                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
17913                    }
17914                    break;
17915                }
17916                case Intent.ACTION_TIMEZONE_CHANGED:
17917                    // If this is the time zone changed action, queue up a message that will reset
17918                    // the timezone of all currently running processes. This message will get
17919                    // queued up before the broadcast happens.
17920                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17921                    break;
17922                case Intent.ACTION_TIME_CHANGED:
17923                    // If the user set the time, let all running processes know.
17924                    final int is24Hour =
17925                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17926                                    : 0;
17927                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17928                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17929                    synchronized (stats) {
17930                        stats.noteCurrentTimeChangedLocked();
17931                    }
17932                    break;
17933                case Intent.ACTION_CLEAR_DNS_CACHE:
17934                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17935                    break;
17936                case Proxy.PROXY_CHANGE_ACTION:
17937                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17938                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17939                    break;
17940                case android.hardware.Camera.ACTION_NEW_PICTURE:
17941                case android.hardware.Camera.ACTION_NEW_VIDEO:
17942                    // These broadcasts are no longer allowed by the system, since they can
17943                    // cause significant thrashing at a crictical point (using the camera).
17944                    // Apps should use JobScehduler to monitor for media provider changes.
17945                    Slog.w(TAG, action + " no longer allowed; dropping from "
17946                            + UserHandle.formatUid(callingUid));
17947                    if (resultTo != null) {
17948                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
17949                        try {
17950                            queue.performReceiveLocked(callerApp, resultTo, intent,
17951                                    Activity.RESULT_CANCELED, null, null,
17952                                    false, false, userId);
17953                        } catch (RemoteException e) {
17954                            Slog.w(TAG, "Failure ["
17955                                    + queue.mQueueName + "] sending broadcast result of "
17956                                    + intent, e);
17957
17958                        }
17959                    }
17960                    // Lie; we don't want to crash the app.
17961                    return ActivityManager.BROADCAST_SUCCESS;
17962            }
17963        }
17964
17965        // Add to the sticky list if requested.
17966        if (sticky) {
17967            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17968                    callingPid, callingUid)
17969                    != PackageManager.PERMISSION_GRANTED) {
17970                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17971                        + callingPid + ", uid=" + callingUid
17972                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17973                Slog.w(TAG, msg);
17974                throw new SecurityException(msg);
17975            }
17976            if (requiredPermissions != null && requiredPermissions.length > 0) {
17977                Slog.w(TAG, "Can't broadcast sticky intent " + intent
17978                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
17979                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17980            }
17981            if (intent.getComponent() != null) {
17982                throw new SecurityException(
17983                        "Sticky broadcasts can't target a specific component");
17984            }
17985            // We use userId directly here, since the "all" target is maintained
17986            // as a separate set of sticky broadcasts.
17987            if (userId != UserHandle.USER_ALL) {
17988                // But first, if this is not a broadcast to all users, then
17989                // make sure it doesn't conflict with an existing broadcast to
17990                // all users.
17991                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17992                        UserHandle.USER_ALL);
17993                if (stickies != null) {
17994                    ArrayList<Intent> list = stickies.get(intent.getAction());
17995                    if (list != null) {
17996                        int N = list.size();
17997                        int i;
17998                        for (i=0; i<N; i++) {
17999                            if (intent.filterEquals(list.get(i))) {
18000                                throw new IllegalArgumentException(
18001                                        "Sticky broadcast " + intent + " for user "
18002                                        + userId + " conflicts with existing global broadcast");
18003                            }
18004                        }
18005                    }
18006                }
18007            }
18008            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18009            if (stickies == null) {
18010                stickies = new ArrayMap<>();
18011                mStickyBroadcasts.put(userId, stickies);
18012            }
18013            ArrayList<Intent> list = stickies.get(intent.getAction());
18014            if (list == null) {
18015                list = new ArrayList<>();
18016                stickies.put(intent.getAction(), list);
18017            }
18018            final int stickiesCount = list.size();
18019            int i;
18020            for (i = 0; i < stickiesCount; i++) {
18021                if (intent.filterEquals(list.get(i))) {
18022                    // This sticky already exists, replace it.
18023                    list.set(i, new Intent(intent));
18024                    break;
18025                }
18026            }
18027            if (i >= stickiesCount) {
18028                list.add(new Intent(intent));
18029            }
18030        }
18031
18032        int[] users;
18033        if (userId == UserHandle.USER_ALL) {
18034            // Caller wants broadcast to go to all started users.
18035            users = mUserController.getStartedUserArrayLocked();
18036        } else {
18037            // Caller wants broadcast to go to one specific user.
18038            users = new int[] {userId};
18039        }
18040
18041        // Figure out who all will receive this broadcast.
18042        List receivers = null;
18043        List<BroadcastFilter> registeredReceivers = null;
18044        // Need to resolve the intent to interested receivers...
18045        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18046                 == 0) {
18047            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18048        }
18049        if (intent.getComponent() == null) {
18050            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18051                // Query one target user at a time, excluding shell-restricted users
18052                for (int i = 0; i < users.length; i++) {
18053                    if (mUserController.hasUserRestriction(
18054                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18055                        continue;
18056                    }
18057                    List<BroadcastFilter> registeredReceiversForUser =
18058                            mReceiverResolver.queryIntent(intent,
18059                                    resolvedType, false, users[i]);
18060                    if (registeredReceivers == null) {
18061                        registeredReceivers = registeredReceiversForUser;
18062                    } else if (registeredReceiversForUser != null) {
18063                        registeredReceivers.addAll(registeredReceiversForUser);
18064                    }
18065                }
18066            } else {
18067                registeredReceivers = mReceiverResolver.queryIntent(intent,
18068                        resolvedType, false, userId);
18069            }
18070        }
18071
18072        final boolean replacePending =
18073                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18074
18075        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18076                + " replacePending=" + replacePending);
18077
18078        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18079        if (!ordered && NR > 0) {
18080            // If we are not serializing this broadcast, then send the
18081            // registered receivers separately so they don't wait for the
18082            // components to be launched.
18083            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18084            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18085                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18086                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18087                    resultExtras, ordered, sticky, false, userId);
18088            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18089            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18090            if (!replaced) {
18091                queue.enqueueParallelBroadcastLocked(r);
18092                queue.scheduleBroadcastsLocked();
18093            }
18094            registeredReceivers = null;
18095            NR = 0;
18096        }
18097
18098        // Merge into one list.
18099        int ir = 0;
18100        if (receivers != null) {
18101            // A special case for PACKAGE_ADDED: do not allow the package
18102            // being added to see this broadcast.  This prevents them from
18103            // using this as a back door to get run as soon as they are
18104            // installed.  Maybe in the future we want to have a special install
18105            // broadcast or such for apps, but we'd like to deliberately make
18106            // this decision.
18107            String skipPackages[] = null;
18108            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18109                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18110                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18111                Uri data = intent.getData();
18112                if (data != null) {
18113                    String pkgName = data.getSchemeSpecificPart();
18114                    if (pkgName != null) {
18115                        skipPackages = new String[] { pkgName };
18116                    }
18117                }
18118            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18119                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18120            }
18121            if (skipPackages != null && (skipPackages.length > 0)) {
18122                for (String skipPackage : skipPackages) {
18123                    if (skipPackage != null) {
18124                        int NT = receivers.size();
18125                        for (int it=0; it<NT; it++) {
18126                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18127                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18128                                receivers.remove(it);
18129                                it--;
18130                                NT--;
18131                            }
18132                        }
18133                    }
18134                }
18135            }
18136
18137            int NT = receivers != null ? receivers.size() : 0;
18138            int it = 0;
18139            ResolveInfo curt = null;
18140            BroadcastFilter curr = null;
18141            while (it < NT && ir < NR) {
18142                if (curt == null) {
18143                    curt = (ResolveInfo)receivers.get(it);
18144                }
18145                if (curr == null) {
18146                    curr = registeredReceivers.get(ir);
18147                }
18148                if (curr.getPriority() >= curt.priority) {
18149                    // Insert this broadcast record into the final list.
18150                    receivers.add(it, curr);
18151                    ir++;
18152                    curr = null;
18153                    it++;
18154                    NT++;
18155                } else {
18156                    // Skip to the next ResolveInfo in the final list.
18157                    it++;
18158                    curt = null;
18159                }
18160            }
18161        }
18162        while (ir < NR) {
18163            if (receivers == null) {
18164                receivers = new ArrayList();
18165            }
18166            receivers.add(registeredReceivers.get(ir));
18167            ir++;
18168        }
18169
18170        if ((receivers != null && receivers.size() > 0)
18171                || resultTo != null) {
18172            BroadcastQueue queue = broadcastQueueForIntent(intent);
18173            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18174                    callerPackage, callingPid, callingUid, resolvedType,
18175                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18176                    resultData, resultExtras, ordered, sticky, false, userId);
18177
18178            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18179                    + ": prev had " + queue.mOrderedBroadcasts.size());
18180            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18181                    "Enqueueing broadcast " + r.intent.getAction());
18182
18183            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18184            if (!replaced) {
18185                queue.enqueueOrderedBroadcastLocked(r);
18186                queue.scheduleBroadcastsLocked();
18187            }
18188        } else {
18189            // There was nobody interested in the broadcast, but we still want to record
18190            // that it happened.
18191            if (intent.getComponent() == null && intent.getPackage() == null
18192                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18193                // This was an implicit broadcast... let's record it for posterity.
18194                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18195            }
18196        }
18197
18198        return ActivityManager.BROADCAST_SUCCESS;
18199    }
18200
18201    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18202            int skipCount, long dispatchTime) {
18203        final long now = SystemClock.elapsedRealtime();
18204        if (mCurBroadcastStats == null ||
18205                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18206            mLastBroadcastStats = mCurBroadcastStats;
18207            if (mLastBroadcastStats != null) {
18208                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18209                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18210            }
18211            mCurBroadcastStats = new BroadcastStats();
18212        }
18213        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18214    }
18215
18216    final Intent verifyBroadcastLocked(Intent intent) {
18217        // Refuse possible leaked file descriptors
18218        if (intent != null && intent.hasFileDescriptors() == true) {
18219            throw new IllegalArgumentException("File descriptors passed in Intent");
18220        }
18221
18222        int flags = intent.getFlags();
18223
18224        if (!mProcessesReady) {
18225            // if the caller really truly claims to know what they're doing, go
18226            // ahead and allow the broadcast without launching any receivers
18227            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18228                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18229            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18230                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18231                        + " before boot completion");
18232                throw new IllegalStateException("Cannot broadcast before boot completed");
18233            }
18234        }
18235
18236        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18237            throw new IllegalArgumentException(
18238                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18239        }
18240
18241        return intent;
18242    }
18243
18244    public final int broadcastIntent(IApplicationThread caller,
18245            Intent intent, String resolvedType, IIntentReceiver resultTo,
18246            int resultCode, String resultData, Bundle resultExtras,
18247            String[] requiredPermissions, int appOp, Bundle bOptions,
18248            boolean serialized, boolean sticky, int userId) {
18249        enforceNotIsolatedCaller("broadcastIntent");
18250        synchronized(this) {
18251            intent = verifyBroadcastLocked(intent);
18252
18253            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18254            final int callingPid = Binder.getCallingPid();
18255            final int callingUid = Binder.getCallingUid();
18256            final long origId = Binder.clearCallingIdentity();
18257            int res = broadcastIntentLocked(callerApp,
18258                    callerApp != null ? callerApp.info.packageName : null,
18259                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18260                    requiredPermissions, appOp, bOptions, serialized, sticky,
18261                    callingPid, callingUid, userId);
18262            Binder.restoreCallingIdentity(origId);
18263            return res;
18264        }
18265    }
18266
18267
18268    int broadcastIntentInPackage(String packageName, int uid,
18269            Intent intent, String resolvedType, IIntentReceiver resultTo,
18270            int resultCode, String resultData, Bundle resultExtras,
18271            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18272            int userId) {
18273        synchronized(this) {
18274            intent = verifyBroadcastLocked(intent);
18275
18276            final long origId = Binder.clearCallingIdentity();
18277            String[] requiredPermissions = requiredPermission == null ? null
18278                    : new String[] {requiredPermission};
18279            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18280                    resultTo, resultCode, resultData, resultExtras,
18281                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18282                    sticky, -1, uid, userId);
18283            Binder.restoreCallingIdentity(origId);
18284            return res;
18285        }
18286    }
18287
18288    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18289        // Refuse possible leaked file descriptors
18290        if (intent != null && intent.hasFileDescriptors() == true) {
18291            throw new IllegalArgumentException("File descriptors passed in Intent");
18292        }
18293
18294        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18295                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18296
18297        synchronized(this) {
18298            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18299                    != PackageManager.PERMISSION_GRANTED) {
18300                String msg = "Permission Denial: unbroadcastIntent() from pid="
18301                        + Binder.getCallingPid()
18302                        + ", uid=" + Binder.getCallingUid()
18303                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18304                Slog.w(TAG, msg);
18305                throw new SecurityException(msg);
18306            }
18307            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18308            if (stickies != null) {
18309                ArrayList<Intent> list = stickies.get(intent.getAction());
18310                if (list != null) {
18311                    int N = list.size();
18312                    int i;
18313                    for (i=0; i<N; i++) {
18314                        if (intent.filterEquals(list.get(i))) {
18315                            list.remove(i);
18316                            break;
18317                        }
18318                    }
18319                    if (list.size() <= 0) {
18320                        stickies.remove(intent.getAction());
18321                    }
18322                }
18323                if (stickies.size() <= 0) {
18324                    mStickyBroadcasts.remove(userId);
18325                }
18326            }
18327        }
18328    }
18329
18330    void backgroundServicesFinishedLocked(int userId) {
18331        for (BroadcastQueue queue : mBroadcastQueues) {
18332            queue.backgroundServicesFinishedLocked(userId);
18333        }
18334    }
18335
18336    public void finishReceiver(IBinder who, int resultCode, String resultData,
18337            Bundle resultExtras, boolean resultAbort, int flags) {
18338        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18339
18340        // Refuse possible leaked file descriptors
18341        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18342            throw new IllegalArgumentException("File descriptors passed in Bundle");
18343        }
18344
18345        final long origId = Binder.clearCallingIdentity();
18346        try {
18347            boolean doNext = false;
18348            BroadcastRecord r;
18349
18350            synchronized(this) {
18351                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18352                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18353                r = queue.getMatchingOrderedReceiver(who);
18354                if (r != null) {
18355                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18356                        resultData, resultExtras, resultAbort, true);
18357                }
18358            }
18359
18360            if (doNext) {
18361                r.queue.processNextBroadcast(false);
18362            }
18363            trimApplications();
18364        } finally {
18365            Binder.restoreCallingIdentity(origId);
18366        }
18367    }
18368
18369    // =========================================================
18370    // INSTRUMENTATION
18371    // =========================================================
18372
18373    public boolean startInstrumentation(ComponentName className,
18374            String profileFile, int flags, Bundle arguments,
18375            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18376            int userId, String abiOverride) {
18377        enforceNotIsolatedCaller("startInstrumentation");
18378        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18379                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18380        // Refuse possible leaked file descriptors
18381        if (arguments != null && arguments.hasFileDescriptors()) {
18382            throw new IllegalArgumentException("File descriptors passed in Bundle");
18383        }
18384
18385        synchronized(this) {
18386            InstrumentationInfo ii = null;
18387            ApplicationInfo ai = null;
18388            try {
18389                ii = mContext.getPackageManager().getInstrumentationInfo(
18390                    className, STOCK_PM_FLAGS);
18391                ai = AppGlobals.getPackageManager().getApplicationInfo(
18392                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18393            } catch (PackageManager.NameNotFoundException e) {
18394            } catch (RemoteException e) {
18395            }
18396            if (ii == null) {
18397                reportStartInstrumentationFailureLocked(watcher, className,
18398                        "Unable to find instrumentation info for: " + className);
18399                return false;
18400            }
18401            if (ai == null) {
18402                reportStartInstrumentationFailureLocked(watcher, className,
18403                        "Unable to find instrumentation target package: " + ii.targetPackage);
18404                return false;
18405            }
18406            if (!ai.hasCode()) {
18407                reportStartInstrumentationFailureLocked(watcher, className,
18408                        "Instrumentation target has no code: " + ii.targetPackage);
18409                return false;
18410            }
18411
18412            int match = mContext.getPackageManager().checkSignatures(
18413                    ii.targetPackage, ii.packageName);
18414            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18415                String msg = "Permission Denial: starting instrumentation "
18416                        + className + " from pid="
18417                        + Binder.getCallingPid()
18418                        + ", uid=" + Binder.getCallingPid()
18419                        + " not allowed because package " + ii.packageName
18420                        + " does not have a signature matching the target "
18421                        + ii.targetPackage;
18422                reportStartInstrumentationFailureLocked(watcher, className, msg);
18423                throw new SecurityException(msg);
18424            }
18425
18426            final long origId = Binder.clearCallingIdentity();
18427            // Instrumentation can kill and relaunch even persistent processes
18428            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18429                    "start instr");
18430            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18431            app.instrumentationClass = className;
18432            app.instrumentationInfo = ai;
18433            app.instrumentationProfileFile = profileFile;
18434            app.instrumentationArguments = arguments;
18435            app.instrumentationWatcher = watcher;
18436            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18437            app.instrumentationResultClass = className;
18438            Binder.restoreCallingIdentity(origId);
18439        }
18440
18441        return true;
18442    }
18443
18444    /**
18445     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18446     * error to the logs, but if somebody is watching, send the report there too.  This enables
18447     * the "am" command to report errors with more information.
18448     *
18449     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18450     * @param cn The component name of the instrumentation.
18451     * @param report The error report.
18452     */
18453    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18454            ComponentName cn, String report) {
18455        Slog.w(TAG, report);
18456        if (watcher != null) {
18457            Bundle results = new Bundle();
18458            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18459            results.putString("Error", report);
18460            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18461        }
18462    }
18463
18464    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18465        if (app.instrumentationWatcher != null) {
18466            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18467                    app.instrumentationClass, resultCode, results);
18468        }
18469
18470        // Can't call out of the system process with a lock held, so post a message.
18471        if (app.instrumentationUiAutomationConnection != null) {
18472            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18473                    app.instrumentationUiAutomationConnection).sendToTarget();
18474        }
18475
18476        app.instrumentationWatcher = null;
18477        app.instrumentationUiAutomationConnection = null;
18478        app.instrumentationClass = null;
18479        app.instrumentationInfo = null;
18480        app.instrumentationProfileFile = null;
18481        app.instrumentationArguments = null;
18482
18483        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18484                "finished inst");
18485    }
18486
18487    public void finishInstrumentation(IApplicationThread target,
18488            int resultCode, Bundle results) {
18489        int userId = UserHandle.getCallingUserId();
18490        // Refuse possible leaked file descriptors
18491        if (results != null && results.hasFileDescriptors()) {
18492            throw new IllegalArgumentException("File descriptors passed in Intent");
18493        }
18494
18495        synchronized(this) {
18496            ProcessRecord app = getRecordForAppLocked(target);
18497            if (app == null) {
18498                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18499                return;
18500            }
18501            final long origId = Binder.clearCallingIdentity();
18502            finishInstrumentationLocked(app, resultCode, results);
18503            Binder.restoreCallingIdentity(origId);
18504        }
18505    }
18506
18507    // =========================================================
18508    // CONFIGURATION
18509    // =========================================================
18510
18511    public ConfigurationInfo getDeviceConfigurationInfo() {
18512        ConfigurationInfo config = new ConfigurationInfo();
18513        synchronized (this) {
18514            config.reqTouchScreen = mConfiguration.touchscreen;
18515            config.reqKeyboardType = mConfiguration.keyboard;
18516            config.reqNavigation = mConfiguration.navigation;
18517            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18518                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18519                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18520            }
18521            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18522                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18523                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18524            }
18525            config.reqGlEsVersion = GL_ES_VERSION;
18526        }
18527        return config;
18528    }
18529
18530    ActivityStack getFocusedStack() {
18531        return mStackSupervisor.getFocusedStack();
18532    }
18533
18534    @Override
18535    public int getFocusedStackId() throws RemoteException {
18536        ActivityStack focusedStack = getFocusedStack();
18537        if (focusedStack != null) {
18538            return focusedStack.getStackId();
18539        }
18540        return -1;
18541    }
18542
18543    public Configuration getConfiguration() {
18544        Configuration ci;
18545        synchronized(this) {
18546            ci = new Configuration(mConfiguration);
18547            ci.userSetLocale = false;
18548        }
18549        return ci;
18550    }
18551
18552    @Override
18553    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18554        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18555        synchronized (this) {
18556            mSuppressResizeConfigChanges = suppress;
18557        }
18558    }
18559
18560    @Override
18561    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18562        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18563        if (fromStackId == HOME_STACK_ID) {
18564            throw new IllegalArgumentException("You can't move tasks from the home stack.");
18565        }
18566        synchronized (this) {
18567            final long origId = Binder.clearCallingIdentity();
18568            try {
18569                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18570            } finally {
18571                Binder.restoreCallingIdentity(origId);
18572            }
18573        }
18574    }
18575
18576    @Override
18577    public void updatePersistentConfiguration(Configuration values) {
18578        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18579                "updateConfiguration()");
18580        enforceWriteSettingsPermission("updateConfiguration()");
18581        if (values == null) {
18582            throw new NullPointerException("Configuration must not be null");
18583        }
18584
18585        int userId = UserHandle.getCallingUserId();
18586
18587        synchronized(this) {
18588            final long origId = Binder.clearCallingIdentity();
18589            updateConfigurationLocked(values, null, false, true, userId);
18590            Binder.restoreCallingIdentity(origId);
18591        }
18592    }
18593
18594    private void updateFontScaleIfNeeded() {
18595        final int currentUserId;
18596        synchronized(this) {
18597            currentUserId = mUserController.getCurrentUserIdLocked();
18598        }
18599        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18600                FONT_SCALE, 1.0f, currentUserId);
18601        if (mConfiguration.fontScale != scaleFactor) {
18602            final Configuration configuration = mWindowManager.computeNewConfiguration();
18603            configuration.fontScale = scaleFactor;
18604            updatePersistentConfiguration(configuration);
18605        }
18606    }
18607
18608    private void enforceWriteSettingsPermission(String func) {
18609        int uid = Binder.getCallingUid();
18610        if (uid == Process.ROOT_UID) {
18611            return;
18612        }
18613
18614        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18615                Settings.getPackageNameForUid(mContext, uid), false)) {
18616            return;
18617        }
18618
18619        String msg = "Permission Denial: " + func + " from pid="
18620                + Binder.getCallingPid()
18621                + ", uid=" + uid
18622                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18623        Slog.w(TAG, msg);
18624        throw new SecurityException(msg);
18625    }
18626
18627    public void updateConfiguration(Configuration values) {
18628        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18629                "updateConfiguration()");
18630
18631        synchronized(this) {
18632            if (values == null && mWindowManager != null) {
18633                // sentinel: fetch the current configuration from the window manager
18634                values = mWindowManager.computeNewConfiguration();
18635            }
18636
18637            if (mWindowManager != null) {
18638                mProcessList.applyDisplaySize(mWindowManager);
18639            }
18640
18641            final long origId = Binder.clearCallingIdentity();
18642            if (values != null) {
18643                Settings.System.clearConfiguration(values);
18644            }
18645            updateConfigurationLocked(values, null, false);
18646            Binder.restoreCallingIdentity(origId);
18647        }
18648    }
18649
18650    void updateUserConfigurationLocked() {
18651        Configuration configuration = new Configuration(mConfiguration);
18652        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18653                mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18654        updateConfigurationLocked(configuration, null, false);
18655    }
18656
18657    boolean updateConfigurationLocked(Configuration values,
18658            ActivityRecord starting, boolean initLocale) {
18659        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18660        return updateConfigurationLocked(values, starting, initLocale, false,
18661                UserHandle.USER_NULL);
18662    }
18663
18664    // To cache the list of supported system locales
18665    private String[] mSupportedSystemLocales = null;
18666
18667    /**
18668     * Do either or both things: (1) change the current configuration, and (2)
18669     * make sure the given activity is running with the (now) current
18670     * configuration.  Returns true if the activity has been left running, or
18671     * false if <var>starting</var> is being destroyed to match the new
18672     * configuration.
18673     *
18674     * @param userId is only used when persistent parameter is set to true to persist configuration
18675     *               for that particular user
18676     */
18677    private boolean updateConfigurationLocked(Configuration values,
18678            ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18679        int changes = 0;
18680
18681        if (mWindowManager != null) {
18682            mWindowManager.deferSurfaceLayout();
18683        }
18684        if (values != null) {
18685            Configuration newConfig = new Configuration(mConfiguration);
18686            changes = newConfig.updateFrom(values);
18687            if (changes != 0) {
18688                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18689                        "Updating configuration to: " + values);
18690
18691                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18692
18693                if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18694                    final LocaleList locales = values.getLocales();
18695                    int bestLocaleIndex = 0;
18696                    if (locales.size() > 1) {
18697                        if (mSupportedSystemLocales == null) {
18698                            mSupportedSystemLocales =
18699                                    Resources.getSystem().getAssets().getLocales();
18700                        }
18701                        bestLocaleIndex = Math.max(0,
18702                                locales.getFirstMatchIndex(mSupportedSystemLocales));
18703                    }
18704                    SystemProperties.set("persist.sys.locale",
18705                            locales.get(bestLocaleIndex).toLanguageTag());
18706                    LocaleList.setDefault(locales, bestLocaleIndex);
18707                    mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18708                            locales.get(bestLocaleIndex)));
18709                }
18710
18711                mConfigurationSeq++;
18712                if (mConfigurationSeq <= 0) {
18713                    mConfigurationSeq = 1;
18714                }
18715                newConfig.seq = mConfigurationSeq;
18716                mConfiguration = newConfig;
18717                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18718                mUsageStatsService.reportConfigurationChange(newConfig,
18719                        mUserController.getCurrentUserIdLocked());
18720                //mUsageStatsService.noteStartConfig(newConfig);
18721
18722                final Configuration configCopy = new Configuration(mConfiguration);
18723
18724                // TODO: If our config changes, should we auto dismiss any currently
18725                // showing dialogs?
18726                mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18727
18728                AttributeCache ac = AttributeCache.instance();
18729                if (ac != null) {
18730                    ac.updateConfiguration(configCopy);
18731                }
18732
18733                // Make sure all resources in our process are updated
18734                // right now, so that anyone who is going to retrieve
18735                // resource values after we return will be sure to get
18736                // the new ones.  This is especially important during
18737                // boot, where the first config change needs to guarantee
18738                // all resources have that config before following boot
18739                // code is executed.
18740                mSystemThread.applyConfigurationToResources(configCopy);
18741
18742                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18743                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18744                    msg.obj = new Configuration(configCopy);
18745                    msg.arg1 = userId;
18746                    mHandler.sendMessage(msg);
18747                }
18748
18749                final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18750                if (isDensityChange) {
18751                    // Reset the unsupported display size dialog.
18752                    mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
18753
18754                    killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18755                            ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18756                }
18757
18758                for (int i=mLruProcesses.size()-1; i>=0; i--) {
18759                    ProcessRecord app = mLruProcesses.get(i);
18760                    try {
18761                        if (app.thread != null) {
18762                            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18763                                    + app.processName + " new config " + mConfiguration);
18764                            app.thread.scheduleConfigurationChanged(configCopy);
18765                        }
18766                    } catch (Exception e) {
18767                    }
18768                }
18769                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18770                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18771                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
18772                        | Intent.FLAG_RECEIVER_FOREGROUND);
18773                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18774                        null, AppOpsManager.OP_NONE, null, false, false,
18775                        MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18776                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18777                    // Tell the shortcut manager that the system locale changed.  It needs to know
18778                    // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18779                    // we "push" from here, rather than having the service listen to the broadcast.
18780                    final ShortcutServiceInternal shortcutService =
18781                            LocalServices.getService(ShortcutServiceInternal.class);
18782                    if (shortcutService != null) {
18783                        shortcutService.onSystemLocaleChangedNoLock();
18784                    }
18785
18786                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18787                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18788                    if (!mProcessesReady) {
18789                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18790                    }
18791                    broadcastIntentLocked(null, null, intent,
18792                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18793                            null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18794                }
18795            }
18796            // Update the configuration with WM first and check if any of the stacks need to be
18797            // resized due to the configuration change. If so, resize the stacks now and do any
18798            // relaunches if necessary. This way we don't need to relaunch again below in
18799            // ensureActivityConfigurationLocked().
18800            if (mWindowManager != null) {
18801                final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18802                if (resizedStacks != null) {
18803                    for (int stackId : resizedStacks) {
18804                        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18805                        mStackSupervisor.resizeStackLocked(
18806                                stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18807                    }
18808                }
18809            }
18810        }
18811
18812        boolean kept = true;
18813        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18814        // mainStack is null during startup.
18815        if (mainStack != null) {
18816            if (changes != 0 && starting == null) {
18817                // If the configuration changed, and the caller is not already
18818                // in the process of starting an activity, then find the top
18819                // activity to check if its configuration needs to change.
18820                starting = mainStack.topRunningActivityLocked();
18821            }
18822
18823            if (starting != null) {
18824                kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18825                // And we need to make sure at this point that all other activities
18826                // are made visible with the correct configuration.
18827                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18828                        !PRESERVE_WINDOWS);
18829            }
18830        }
18831        if (mWindowManager != null) {
18832            mWindowManager.continueSurfaceLayout();
18833        }
18834        return kept;
18835    }
18836
18837    /**
18838     * Decide based on the configuration whether we should shouw the ANR,
18839     * crash, etc dialogs.  The idea is that if there is no affordence to
18840     * press the on-screen buttons, or the user experience would be more
18841     * greatly impacted than the crash itself, we shouldn't show the dialog.
18842     *
18843     * A thought: SystemUI might also want to get told about this, the Power
18844     * dialog / global actions also might want different behaviors.
18845     */
18846    private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18847        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18848                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18849                                   && config.navigation == Configuration.NAVIGATION_NONAV);
18850        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
18851        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
18852                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
18853        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
18854    }
18855
18856    @Override
18857    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18858        synchronized (this) {
18859            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18860            if (srec != null) {
18861                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18862            }
18863        }
18864        return false;
18865    }
18866
18867    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18868            Intent resultData) {
18869
18870        synchronized (this) {
18871            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18872            if (r != null) {
18873                return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18874            }
18875            return false;
18876        }
18877    }
18878
18879    public int getLaunchedFromUid(IBinder activityToken) {
18880        ActivityRecord srec;
18881        synchronized (this) {
18882            srec = ActivityRecord.forTokenLocked(activityToken);
18883        }
18884        if (srec == null) {
18885            return -1;
18886        }
18887        return srec.launchedFromUid;
18888    }
18889
18890    public String getLaunchedFromPackage(IBinder activityToken) {
18891        ActivityRecord srec;
18892        synchronized (this) {
18893            srec = ActivityRecord.forTokenLocked(activityToken);
18894        }
18895        if (srec == null) {
18896            return null;
18897        }
18898        return srec.launchedFromPackage;
18899    }
18900
18901    // =========================================================
18902    // LIFETIME MANAGEMENT
18903    // =========================================================
18904
18905    // Returns which broadcast queue the app is the current [or imminent] receiver
18906    // on, or 'null' if the app is not an active broadcast recipient.
18907    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18908        BroadcastRecord r = app.curReceiver;
18909        if (r != null) {
18910            return r.queue;
18911        }
18912
18913        // It's not the current receiver, but it might be starting up to become one
18914        synchronized (this) {
18915            for (BroadcastQueue queue : mBroadcastQueues) {
18916                r = queue.mPendingBroadcast;
18917                if (r != null && r.curApp == app) {
18918                    // found it; report which queue it's in
18919                    return queue;
18920                }
18921            }
18922        }
18923
18924        return null;
18925    }
18926
18927    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18928            int targetUid, ComponentName targetComponent, String targetProcess) {
18929        if (!mTrackingAssociations) {
18930            return null;
18931        }
18932        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18933                = mAssociations.get(targetUid);
18934        if (components == null) {
18935            components = new ArrayMap<>();
18936            mAssociations.put(targetUid, components);
18937        }
18938        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18939        if (sourceUids == null) {
18940            sourceUids = new SparseArray<>();
18941            components.put(targetComponent, sourceUids);
18942        }
18943        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18944        if (sourceProcesses == null) {
18945            sourceProcesses = new ArrayMap<>();
18946            sourceUids.put(sourceUid, sourceProcesses);
18947        }
18948        Association ass = sourceProcesses.get(sourceProcess);
18949        if (ass == null) {
18950            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18951                    targetProcess);
18952            sourceProcesses.put(sourceProcess, ass);
18953        }
18954        ass.mCount++;
18955        ass.mNesting++;
18956        if (ass.mNesting == 1) {
18957            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18958            ass.mLastState = sourceState;
18959        }
18960        return ass;
18961    }
18962
18963    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18964            ComponentName targetComponent) {
18965        if (!mTrackingAssociations) {
18966            return;
18967        }
18968        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18969                = mAssociations.get(targetUid);
18970        if (components == null) {
18971            return;
18972        }
18973        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18974        if (sourceUids == null) {
18975            return;
18976        }
18977        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18978        if (sourceProcesses == null) {
18979            return;
18980        }
18981        Association ass = sourceProcesses.get(sourceProcess);
18982        if (ass == null || ass.mNesting <= 0) {
18983            return;
18984        }
18985        ass.mNesting--;
18986        if (ass.mNesting == 0) {
18987            long uptime = SystemClock.uptimeMillis();
18988            ass.mTime += uptime - ass.mStartTime;
18989            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18990                    += uptime - ass.mLastStateUptime;
18991            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18992        }
18993    }
18994
18995    private void noteUidProcessState(final int uid, final int state) {
18996        mBatteryStatsService.noteUidProcessState(uid, state);
18997        if (mTrackingAssociations) {
18998            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18999                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19000                        = mAssociations.valueAt(i1);
19001                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19002                    SparseArray<ArrayMap<String, Association>> sourceUids
19003                            = targetComponents.valueAt(i2);
19004                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19005                    if (sourceProcesses != null) {
19006                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19007                            Association ass = sourceProcesses.valueAt(i4);
19008                            if (ass.mNesting >= 1) {
19009                                // currently associated
19010                                long uptime = SystemClock.uptimeMillis();
19011                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19012                                        += uptime - ass.mLastStateUptime;
19013                                ass.mLastState = state;
19014                                ass.mLastStateUptime = uptime;
19015                            }
19016                        }
19017                    }
19018                }
19019            }
19020        }
19021    }
19022
19023    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19024            boolean doingAll, long now) {
19025        if (mAdjSeq == app.adjSeq) {
19026            // This adjustment has already been computed.
19027            return app.curRawAdj;
19028        }
19029
19030        if (app.thread == null) {
19031            app.adjSeq = mAdjSeq;
19032            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19033            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19034            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19035        }
19036
19037        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19038        app.adjSource = null;
19039        app.adjTarget = null;
19040        app.empty = false;
19041        app.cached = false;
19042
19043        final int activitiesSize = app.activities.size();
19044
19045        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19046            // The max adjustment doesn't allow this app to be anything
19047            // below foreground, so it is not worth doing work for it.
19048            app.adjType = "fixed";
19049            app.adjSeq = mAdjSeq;
19050            app.curRawAdj = app.maxAdj;
19051            app.foregroundActivities = false;
19052            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19053            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19054            // System processes can do UI, and when they do we want to have
19055            // them trim their memory after the user leaves the UI.  To
19056            // facilitate this, here we need to determine whether or not it
19057            // is currently showing UI.
19058            app.systemNoUi = true;
19059            if (app == TOP_APP) {
19060                app.systemNoUi = false;
19061                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19062                app.adjType = "pers-top-activity";
19063            } else if (activitiesSize > 0) {
19064                for (int j = 0; j < activitiesSize; j++) {
19065                    final ActivityRecord r = app.activities.get(j);
19066                    if (r.visible) {
19067                        app.systemNoUi = false;
19068                    }
19069                }
19070            }
19071            if (!app.systemNoUi) {
19072                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19073            }
19074            return (app.curAdj=app.maxAdj);
19075        }
19076
19077        app.systemNoUi = false;
19078
19079        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19080
19081        // Determine the importance of the process, starting with most
19082        // important to least, and assign an appropriate OOM adjustment.
19083        int adj;
19084        int schedGroup;
19085        int procState;
19086        boolean foregroundActivities = false;
19087        BroadcastQueue queue;
19088        if (app == TOP_APP) {
19089            // The last app on the list is the foreground app.
19090            adj = ProcessList.FOREGROUND_APP_ADJ;
19091            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19092            app.adjType = "top-activity";
19093            foregroundActivities = true;
19094            procState = PROCESS_STATE_CUR_TOP;
19095        } else if (app.instrumentationClass != null) {
19096            // Don't want to kill running instrumentation.
19097            adj = ProcessList.FOREGROUND_APP_ADJ;
19098            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19099            app.adjType = "instrumentation";
19100            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19101        } else if ((queue = isReceivingBroadcast(app)) != null) {
19102            // An app that is currently receiving a broadcast also
19103            // counts as being in the foreground for OOM killer purposes.
19104            // It's placed in a sched group based on the nature of the
19105            // broadcast as reflected by which queue it's active in.
19106            adj = ProcessList.FOREGROUND_APP_ADJ;
19107            schedGroup = (queue == mFgBroadcastQueue)
19108                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19109            app.adjType = "broadcast";
19110            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19111        } else if (app.executingServices.size() > 0) {
19112            // An app that is currently executing a service callback also
19113            // counts as being in the foreground.
19114            adj = ProcessList.FOREGROUND_APP_ADJ;
19115            schedGroup = app.execServicesFg ?
19116                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19117            app.adjType = "exec-service";
19118            procState = ActivityManager.PROCESS_STATE_SERVICE;
19119            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19120        } else {
19121            // As far as we know the process is empty.  We may change our mind later.
19122            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19123            // At this point we don't actually know the adjustment.  Use the cached adj
19124            // value that the caller wants us to.
19125            adj = cachedAdj;
19126            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19127            app.cached = true;
19128            app.empty = true;
19129            app.adjType = "cch-empty";
19130        }
19131
19132        // Examine all activities if not already foreground.
19133        if (!foregroundActivities && activitiesSize > 0) {
19134            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19135            for (int j = 0; j < activitiesSize; j++) {
19136                final ActivityRecord r = app.activities.get(j);
19137                if (r.app != app) {
19138                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19139                            + " instead of expected " + app);
19140                    if (r.app == null || (r.app.uid == app.uid)) {
19141                        // Only fix things up when they look sane
19142                        r.app = app;
19143                    } else {
19144                        continue;
19145                    }
19146                }
19147                if (r.visible) {
19148                    // App has a visible activity; only upgrade adjustment.
19149                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19150                        adj = ProcessList.VISIBLE_APP_ADJ;
19151                        app.adjType = "visible";
19152                    }
19153                    if (procState > PROCESS_STATE_CUR_TOP) {
19154                        procState = PROCESS_STATE_CUR_TOP;
19155                    }
19156                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19157                    app.cached = false;
19158                    app.empty = false;
19159                    foregroundActivities = true;
19160                    if (r.task != null && minLayer > 0) {
19161                        final int layer = r.task.mLayerRank;
19162                        if (layer >= 0 && minLayer > layer) {
19163                            minLayer = layer;
19164                        }
19165                    }
19166                    break;
19167                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19168                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19169                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19170                        app.adjType = "pausing";
19171                    }
19172                    if (procState > PROCESS_STATE_CUR_TOP) {
19173                        procState = PROCESS_STATE_CUR_TOP;
19174                    }
19175                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19176                    app.cached = false;
19177                    app.empty = false;
19178                    foregroundActivities = true;
19179                } else if (r.state == ActivityState.STOPPING) {
19180                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19181                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19182                        app.adjType = "stopping";
19183                    }
19184                    // For the process state, we will at this point consider the
19185                    // process to be cached.  It will be cached either as an activity
19186                    // or empty depending on whether the activity is finishing.  We do
19187                    // this so that we can treat the process as cached for purposes of
19188                    // memory trimming (determing current memory level, trim command to
19189                    // send to process) since there can be an arbitrary number of stopping
19190                    // processes and they should soon all go into the cached state.
19191                    if (!r.finishing) {
19192                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19193                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19194                        }
19195                    }
19196                    app.cached = false;
19197                    app.empty = false;
19198                    foregroundActivities = true;
19199                } else {
19200                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19201                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19202                        app.adjType = "cch-act";
19203                    }
19204                }
19205            }
19206            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19207                adj += minLayer;
19208            }
19209        }
19210
19211        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19212                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19213            if (app.foregroundServices) {
19214                // The user is aware of this app, so make it visible.
19215                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19216                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19217                app.cached = false;
19218                app.adjType = "fg-service";
19219                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19220            } else if (app.forcingToForeground != null) {
19221                // The user is aware of this app, so make it visible.
19222                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19223                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19224                app.cached = false;
19225                app.adjType = "force-fg";
19226                app.adjSource = app.forcingToForeground;
19227                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19228            }
19229        }
19230
19231        if (app == mHeavyWeightProcess) {
19232            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19233                // We don't want to kill the current heavy-weight process.
19234                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19235                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19236                app.cached = false;
19237                app.adjType = "heavy";
19238            }
19239            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19240                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19241            }
19242        }
19243
19244        if (app == mHomeProcess) {
19245            if (adj > ProcessList.HOME_APP_ADJ) {
19246                // This process is hosting what we currently consider to be the
19247                // home app, so we don't want to let it go into the background.
19248                adj = ProcessList.HOME_APP_ADJ;
19249                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19250                app.cached = false;
19251                app.adjType = "home";
19252            }
19253            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19254                procState = ActivityManager.PROCESS_STATE_HOME;
19255            }
19256        }
19257
19258        if (app == mPreviousProcess && app.activities.size() > 0) {
19259            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19260                // This was the previous process that showed UI to the user.
19261                // We want to try to keep it around more aggressively, to give
19262                // a good experience around switching between two apps.
19263                adj = ProcessList.PREVIOUS_APP_ADJ;
19264                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19265                app.cached = false;
19266                app.adjType = "previous";
19267            }
19268            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19269                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19270            }
19271        }
19272
19273        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19274                + " reason=" + app.adjType);
19275
19276        // By default, we use the computed adjustment.  It may be changed if
19277        // there are applications dependent on our services or providers, but
19278        // this gives us a baseline and makes sure we don't get into an
19279        // infinite recursion.
19280        app.adjSeq = mAdjSeq;
19281        app.curRawAdj = adj;
19282        app.hasStartedServices = false;
19283
19284        if (mBackupTarget != null && app == mBackupTarget.app) {
19285            // If possible we want to avoid killing apps while they're being backed up
19286            if (adj > ProcessList.BACKUP_APP_ADJ) {
19287                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19288                adj = ProcessList.BACKUP_APP_ADJ;
19289                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19290                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19291                }
19292                app.adjType = "backup";
19293                app.cached = false;
19294            }
19295            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19296                procState = ActivityManager.PROCESS_STATE_BACKUP;
19297            }
19298        }
19299
19300        boolean mayBeTop = false;
19301
19302        for (int is = app.services.size()-1;
19303                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19304                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19305                        || procState > ActivityManager.PROCESS_STATE_TOP);
19306                is--) {
19307            ServiceRecord s = app.services.valueAt(is);
19308            if (s.startRequested) {
19309                app.hasStartedServices = true;
19310                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19311                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19312                }
19313                if (app.hasShownUi && app != mHomeProcess) {
19314                    // If this process has shown some UI, let it immediately
19315                    // go to the LRU list because it may be pretty heavy with
19316                    // UI stuff.  We'll tag it with a label just to help
19317                    // debug and understand what is going on.
19318                    if (adj > ProcessList.SERVICE_ADJ) {
19319                        app.adjType = "cch-started-ui-services";
19320                    }
19321                } else {
19322                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19323                        // This service has seen some activity within
19324                        // recent memory, so we will keep its process ahead
19325                        // of the background processes.
19326                        if (adj > ProcessList.SERVICE_ADJ) {
19327                            adj = ProcessList.SERVICE_ADJ;
19328                            app.adjType = "started-services";
19329                            app.cached = false;
19330                        }
19331                    }
19332                    // If we have let the service slide into the background
19333                    // state, still have some text describing what it is doing
19334                    // even though the service no longer has an impact.
19335                    if (adj > ProcessList.SERVICE_ADJ) {
19336                        app.adjType = "cch-started-services";
19337                    }
19338                }
19339            }
19340
19341            for (int conni = s.connections.size()-1;
19342                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19343                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19344                            || procState > ActivityManager.PROCESS_STATE_TOP);
19345                    conni--) {
19346                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19347                for (int i = 0;
19348                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19349                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19350                                || procState > ActivityManager.PROCESS_STATE_TOP);
19351                        i++) {
19352                    // XXX should compute this based on the max of
19353                    // all connected clients.
19354                    ConnectionRecord cr = clist.get(i);
19355                    if (cr.binding.client == app) {
19356                        // Binding to ourself is not interesting.
19357                        continue;
19358                    }
19359
19360                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19361                        ProcessRecord client = cr.binding.client;
19362                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
19363                                TOP_APP, doingAll, now);
19364                        int clientProcState = client.curProcState;
19365                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19366                            // If the other app is cached for any reason, for purposes here
19367                            // we are going to consider it empty.  The specific cached state
19368                            // doesn't propagate except under certain conditions.
19369                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19370                        }
19371                        String adjType = null;
19372                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19373                            // Not doing bind OOM management, so treat
19374                            // this guy more like a started service.
19375                            if (app.hasShownUi && app != mHomeProcess) {
19376                                // If this process has shown some UI, let it immediately
19377                                // go to the LRU list because it may be pretty heavy with
19378                                // UI stuff.  We'll tag it with a label just to help
19379                                // debug and understand what is going on.
19380                                if (adj > clientAdj) {
19381                                    adjType = "cch-bound-ui-services";
19382                                }
19383                                app.cached = false;
19384                                clientAdj = adj;
19385                                clientProcState = procState;
19386                            } else {
19387                                if (now >= (s.lastActivity
19388                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19389                                    // This service has not seen activity within
19390                                    // recent memory, so allow it to drop to the
19391                                    // LRU list if there is no other reason to keep
19392                                    // it around.  We'll also tag it with a label just
19393                                    // to help debug and undertand what is going on.
19394                                    if (adj > clientAdj) {
19395                                        adjType = "cch-bound-services";
19396                                    }
19397                                    clientAdj = adj;
19398                                }
19399                            }
19400                        }
19401                        if (adj > clientAdj) {
19402                            // If this process has recently shown UI, and
19403                            // the process that is binding to it is less
19404                            // important than being visible, then we don't
19405                            // care about the binding as much as we care
19406                            // about letting this process get into the LRU
19407                            // list to be killed and restarted if needed for
19408                            // memory.
19409                            if (app.hasShownUi && app != mHomeProcess
19410                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19411                                adjType = "cch-bound-ui-services";
19412                            } else {
19413                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19414                                        |Context.BIND_IMPORTANT)) != 0) {
19415                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19416                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19417                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19418                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19419                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19420                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19421                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19422                                    adj = clientAdj;
19423                                } else {
19424                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19425                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19426                                    }
19427                                }
19428                                if (!client.cached) {
19429                                    app.cached = false;
19430                                }
19431                                adjType = "service";
19432                            }
19433                        }
19434                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19435                            // This will treat important bound services identically to
19436                            // the top app, which may behave differently than generic
19437                            // foreground work.
19438                            if (client.curSchedGroup > schedGroup) {
19439                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19440                                    schedGroup = client.curSchedGroup;
19441                                } else {
19442                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19443                                }
19444                            }
19445                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19446                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19447                                    // Special handling of clients who are in the top state.
19448                                    // We *may* want to consider this process to be in the
19449                                    // top state as well, but only if there is not another
19450                                    // reason for it to be running.  Being on the top is a
19451                                    // special state, meaning you are specifically running
19452                                    // for the current top app.  If the process is already
19453                                    // running in the background for some other reason, it
19454                                    // is more important to continue considering it to be
19455                                    // in the background state.
19456                                    mayBeTop = true;
19457                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19458                                } else {
19459                                    // Special handling for above-top states (persistent
19460                                    // processes).  These should not bring the current process
19461                                    // into the top state, since they are not on top.  Instead
19462                                    // give them the best state after that.
19463                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19464                                        clientProcState =
19465                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19466                                    } else if (mWakefulness
19467                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19468                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19469                                                    != 0) {
19470                                        clientProcState =
19471                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19472                                    } else {
19473                                        clientProcState =
19474                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19475                                    }
19476                                }
19477                            }
19478                        } else {
19479                            if (clientProcState <
19480                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19481                                clientProcState =
19482                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19483                            }
19484                        }
19485                        if (procState > clientProcState) {
19486                            procState = clientProcState;
19487                        }
19488                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19489                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19490                            app.pendingUiClean = true;
19491                        }
19492                        if (adjType != null) {
19493                            app.adjType = adjType;
19494                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19495                                    .REASON_SERVICE_IN_USE;
19496                            app.adjSource = cr.binding.client;
19497                            app.adjSourceProcState = clientProcState;
19498                            app.adjTarget = s.name;
19499                        }
19500                    }
19501                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19502                        app.treatLikeActivity = true;
19503                    }
19504                    final ActivityRecord a = cr.activity;
19505                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19506                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19507                            (a.visible || a.state == ActivityState.RESUMED ||
19508                             a.state == ActivityState.PAUSING)) {
19509                            adj = ProcessList.FOREGROUND_APP_ADJ;
19510                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19511                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19512                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19513                                } else {
19514                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19515                                }
19516                            }
19517                            app.cached = false;
19518                            app.adjType = "service";
19519                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19520                                    .REASON_SERVICE_IN_USE;
19521                            app.adjSource = a;
19522                            app.adjSourceProcState = procState;
19523                            app.adjTarget = s.name;
19524                        }
19525                    }
19526                }
19527            }
19528        }
19529
19530        for (int provi = app.pubProviders.size()-1;
19531                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19532                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19533                        || procState > ActivityManager.PROCESS_STATE_TOP);
19534                provi--) {
19535            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19536            for (int i = cpr.connections.size()-1;
19537                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19538                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19539                            || procState > ActivityManager.PROCESS_STATE_TOP);
19540                    i--) {
19541                ContentProviderConnection conn = cpr.connections.get(i);
19542                ProcessRecord client = conn.client;
19543                if (client == app) {
19544                    // Being our own client is not interesting.
19545                    continue;
19546                }
19547                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19548                int clientProcState = client.curProcState;
19549                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19550                    // If the other app is cached for any reason, for purposes here
19551                    // we are going to consider it empty.
19552                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19553                }
19554                if (adj > clientAdj) {
19555                    if (app.hasShownUi && app != mHomeProcess
19556                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19557                        app.adjType = "cch-ui-provider";
19558                    } else {
19559                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19560                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19561                        app.adjType = "provider";
19562                    }
19563                    app.cached &= client.cached;
19564                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19565                            .REASON_PROVIDER_IN_USE;
19566                    app.adjSource = client;
19567                    app.adjSourceProcState = clientProcState;
19568                    app.adjTarget = cpr.name;
19569                }
19570                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19571                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19572                        // Special handling of clients who are in the top state.
19573                        // We *may* want to consider this process to be in the
19574                        // top state as well, but only if there is not another
19575                        // reason for it to be running.  Being on the top is a
19576                        // special state, meaning you are specifically running
19577                        // for the current top app.  If the process is already
19578                        // running in the background for some other reason, it
19579                        // is more important to continue considering it to be
19580                        // in the background state.
19581                        mayBeTop = true;
19582                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19583                    } else {
19584                        // Special handling for above-top states (persistent
19585                        // processes).  These should not bring the current process
19586                        // into the top state, since they are not on top.  Instead
19587                        // give them the best state after that.
19588                        clientProcState =
19589                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19590                    }
19591                }
19592                if (procState > clientProcState) {
19593                    procState = clientProcState;
19594                }
19595                if (client.curSchedGroup > schedGroup) {
19596                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19597                }
19598            }
19599            // If the provider has external (non-framework) process
19600            // dependencies, ensure that its adjustment is at least
19601            // FOREGROUND_APP_ADJ.
19602            if (cpr.hasExternalProcessHandles()) {
19603                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19604                    adj = ProcessList.FOREGROUND_APP_ADJ;
19605                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19606                    app.cached = false;
19607                    app.adjType = "provider";
19608                    app.adjTarget = cpr.name;
19609                }
19610                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19611                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19612                }
19613            }
19614        }
19615
19616        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19617            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19618                adj = ProcessList.PREVIOUS_APP_ADJ;
19619                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19620                app.cached = false;
19621                app.adjType = "provider";
19622            }
19623            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19624                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19625            }
19626        }
19627
19628        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19629            // A client of one of our services or providers is in the top state.  We
19630            // *may* want to be in the top state, but not if we are already running in
19631            // the background for some other reason.  For the decision here, we are going
19632            // to pick out a few specific states that we want to remain in when a client
19633            // is top (states that tend to be longer-term) and otherwise allow it to go
19634            // to the top state.
19635            switch (procState) {
19636                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19637                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19638                case ActivityManager.PROCESS_STATE_SERVICE:
19639                    // These all are longer-term states, so pull them up to the top
19640                    // of the background states, but not all the way to the top state.
19641                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19642                    break;
19643                default:
19644                    // Otherwise, top is a better choice, so take it.
19645                    procState = ActivityManager.PROCESS_STATE_TOP;
19646                    break;
19647            }
19648        }
19649
19650        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19651            if (app.hasClientActivities) {
19652                // This is a cached process, but with client activities.  Mark it so.
19653                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19654                app.adjType = "cch-client-act";
19655            } else if (app.treatLikeActivity) {
19656                // This is a cached process, but somebody wants us to treat it like it has
19657                // an activity, okay!
19658                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19659                app.adjType = "cch-as-act";
19660            }
19661        }
19662
19663        if (adj == ProcessList.SERVICE_ADJ) {
19664            if (doingAll) {
19665                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19666                mNewNumServiceProcs++;
19667                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19668                if (!app.serviceb) {
19669                    // This service isn't far enough down on the LRU list to
19670                    // normally be a B service, but if we are low on RAM and it
19671                    // is large we want to force it down since we would prefer to
19672                    // keep launcher over it.
19673                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19674                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19675                        app.serviceHighRam = true;
19676                        app.serviceb = true;
19677                        //Slog.i(TAG, "ADJ " + app + " high ram!");
19678                    } else {
19679                        mNewNumAServiceProcs++;
19680                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
19681                    }
19682                } else {
19683                    app.serviceHighRam = false;
19684                }
19685            }
19686            if (app.serviceb) {
19687                adj = ProcessList.SERVICE_B_ADJ;
19688            }
19689        }
19690
19691        app.curRawAdj = adj;
19692
19693        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19694        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19695        if (adj > app.maxAdj) {
19696            adj = app.maxAdj;
19697            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19698                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19699            }
19700        }
19701
19702        // Do final modification to adj.  Everything we do between here and applying
19703        // the final setAdj must be done in this function, because we will also use
19704        // it when computing the final cached adj later.  Note that we don't need to
19705        // worry about this for max adj above, since max adj will always be used to
19706        // keep it out of the cached vaues.
19707        app.curAdj = app.modifyRawOomAdj(adj);
19708        app.curSchedGroup = schedGroup;
19709        app.curProcState = procState;
19710        app.foregroundActivities = foregroundActivities;
19711
19712        return app.curRawAdj;
19713    }
19714
19715    /**
19716     * Record new PSS sample for a process.
19717     */
19718    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19719            long now) {
19720        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19721                swapPss * 1024);
19722        proc.lastPssTime = now;
19723        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19724        if (DEBUG_PSS) Slog.d(TAG_PSS,
19725                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19726                + " state=" + ProcessList.makeProcStateString(procState));
19727        if (proc.initialIdlePss == 0) {
19728            proc.initialIdlePss = pss;
19729        }
19730        proc.lastPss = pss;
19731        proc.lastSwapPss = swapPss;
19732        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19733            proc.lastCachedPss = pss;
19734            proc.lastCachedSwapPss = swapPss;
19735        }
19736
19737        final SparseArray<Pair<Long, String>> watchUids
19738                = mMemWatchProcesses.getMap().get(proc.processName);
19739        Long check = null;
19740        if (watchUids != null) {
19741            Pair<Long, String> val = watchUids.get(proc.uid);
19742            if (val == null) {
19743                val = watchUids.get(0);
19744            }
19745            if (val != null) {
19746                check = val.first;
19747            }
19748        }
19749        if (check != null) {
19750            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19751                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19752                if (!isDebuggable) {
19753                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19754                        isDebuggable = true;
19755                    }
19756                }
19757                if (isDebuggable) {
19758                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19759                    final ProcessRecord myProc = proc;
19760                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
19761                    mMemWatchDumpProcName = proc.processName;
19762                    mMemWatchDumpFile = heapdumpFile.toString();
19763                    mMemWatchDumpPid = proc.pid;
19764                    mMemWatchDumpUid = proc.uid;
19765                    BackgroundThread.getHandler().post(new Runnable() {
19766                        @Override
19767                        public void run() {
19768                            revokeUriPermission(ActivityThread.currentActivityThread()
19769                                            .getApplicationThread(),
19770                                    DumpHeapActivity.JAVA_URI,
19771                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
19772                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19773                                    UserHandle.myUserId());
19774                            ParcelFileDescriptor fd = null;
19775                            try {
19776                                heapdumpFile.delete();
19777                                fd = ParcelFileDescriptor.open(heapdumpFile,
19778                                        ParcelFileDescriptor.MODE_CREATE |
19779                                                ParcelFileDescriptor.MODE_TRUNCATE |
19780                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
19781                                                ParcelFileDescriptor.MODE_APPEND);
19782                                IApplicationThread thread = myProc.thread;
19783                                if (thread != null) {
19784                                    try {
19785                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
19786                                                "Requesting dump heap from "
19787                                                + myProc + " to " + heapdumpFile);
19788                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
19789                                    } catch (RemoteException e) {
19790                                    }
19791                                }
19792                            } catch (FileNotFoundException e) {
19793                                e.printStackTrace();
19794                            } finally {
19795                                if (fd != null) {
19796                                    try {
19797                                        fd.close();
19798                                    } catch (IOException e) {
19799                                    }
19800                                }
19801                            }
19802                        }
19803                    });
19804                } else {
19805                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19806                            + ", but debugging not enabled");
19807                }
19808            }
19809        }
19810    }
19811
19812    /**
19813     * Schedule PSS collection of a process.
19814     */
19815    void requestPssLocked(ProcessRecord proc, int procState) {
19816        if (mPendingPssProcesses.contains(proc)) {
19817            return;
19818        }
19819        if (mPendingPssProcesses.size() == 0) {
19820            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19821        }
19822        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19823        proc.pssProcState = procState;
19824        mPendingPssProcesses.add(proc);
19825    }
19826
19827    /**
19828     * Schedule PSS collection of all processes.
19829     */
19830    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19831        if (!always) {
19832            if (now < (mLastFullPssTime +
19833                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19834                return;
19835            }
19836        }
19837        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
19838        mLastFullPssTime = now;
19839        mFullPssPending = true;
19840        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19841        mPendingPssProcesses.clear();
19842        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19843            ProcessRecord app = mLruProcesses.get(i);
19844            if (app.thread == null
19845                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19846                continue;
19847            }
19848            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19849                app.pssProcState = app.setProcState;
19850                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19851                        mTestPssMode, isSleepingLocked(), now);
19852                mPendingPssProcesses.add(app);
19853            }
19854        }
19855        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19856    }
19857
19858    public void setTestPssMode(boolean enabled) {
19859        synchronized (this) {
19860            mTestPssMode = enabled;
19861            if (enabled) {
19862                // Whenever we enable the mode, we want to take a snapshot all of current
19863                // process mem use.
19864                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19865            }
19866        }
19867    }
19868
19869    /**
19870     * Ask a given process to GC right now.
19871     */
19872    final void performAppGcLocked(ProcessRecord app) {
19873        try {
19874            app.lastRequestedGc = SystemClock.uptimeMillis();
19875            if (app.thread != null) {
19876                if (app.reportLowMemory) {
19877                    app.reportLowMemory = false;
19878                    app.thread.scheduleLowMemory();
19879                } else {
19880                    app.thread.processInBackground();
19881                }
19882            }
19883        } catch (Exception e) {
19884            // whatever.
19885        }
19886    }
19887
19888    /**
19889     * Returns true if things are idle enough to perform GCs.
19890     */
19891    private final boolean canGcNowLocked() {
19892        boolean processingBroadcasts = false;
19893        for (BroadcastQueue q : mBroadcastQueues) {
19894            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19895                processingBroadcasts = true;
19896            }
19897        }
19898        return !processingBroadcasts
19899                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
19900    }
19901
19902    /**
19903     * Perform GCs on all processes that are waiting for it, but only
19904     * if things are idle.
19905     */
19906    final void performAppGcsLocked() {
19907        final int N = mProcessesToGc.size();
19908        if (N <= 0) {
19909            return;
19910        }
19911        if (canGcNowLocked()) {
19912            while (mProcessesToGc.size() > 0) {
19913                ProcessRecord proc = mProcessesToGc.remove(0);
19914                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19915                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19916                            <= SystemClock.uptimeMillis()) {
19917                        // To avoid spamming the system, we will GC processes one
19918                        // at a time, waiting a few seconds between each.
19919                        performAppGcLocked(proc);
19920                        scheduleAppGcsLocked();
19921                        return;
19922                    } else {
19923                        // It hasn't been long enough since we last GCed this
19924                        // process...  put it in the list to wait for its time.
19925                        addProcessToGcListLocked(proc);
19926                        break;
19927                    }
19928                }
19929            }
19930
19931            scheduleAppGcsLocked();
19932        }
19933    }
19934
19935    /**
19936     * If all looks good, perform GCs on all processes waiting for them.
19937     */
19938    final void performAppGcsIfAppropriateLocked() {
19939        if (canGcNowLocked()) {
19940            performAppGcsLocked();
19941            return;
19942        }
19943        // Still not idle, wait some more.
19944        scheduleAppGcsLocked();
19945    }
19946
19947    /**
19948     * Schedule the execution of all pending app GCs.
19949     */
19950    final void scheduleAppGcsLocked() {
19951        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19952
19953        if (mProcessesToGc.size() > 0) {
19954            // Schedule a GC for the time to the next process.
19955            ProcessRecord proc = mProcessesToGc.get(0);
19956            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19957
19958            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19959            long now = SystemClock.uptimeMillis();
19960            if (when < (now+GC_TIMEOUT)) {
19961                when = now + GC_TIMEOUT;
19962            }
19963            mHandler.sendMessageAtTime(msg, when);
19964        }
19965    }
19966
19967    /**
19968     * Add a process to the array of processes waiting to be GCed.  Keeps the
19969     * list in sorted order by the last GC time.  The process can't already be
19970     * on the list.
19971     */
19972    final void addProcessToGcListLocked(ProcessRecord proc) {
19973        boolean added = false;
19974        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19975            if (mProcessesToGc.get(i).lastRequestedGc <
19976                    proc.lastRequestedGc) {
19977                added = true;
19978                mProcessesToGc.add(i+1, proc);
19979                break;
19980            }
19981        }
19982        if (!added) {
19983            mProcessesToGc.add(0, proc);
19984        }
19985    }
19986
19987    /**
19988     * Set up to ask a process to GC itself.  This will either do it
19989     * immediately, or put it on the list of processes to gc the next
19990     * time things are idle.
19991     */
19992    final void scheduleAppGcLocked(ProcessRecord app) {
19993        long now = SystemClock.uptimeMillis();
19994        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19995            return;
19996        }
19997        if (!mProcessesToGc.contains(app)) {
19998            addProcessToGcListLocked(app);
19999            scheduleAppGcsLocked();
20000        }
20001    }
20002
20003    final void checkExcessivePowerUsageLocked(boolean doKills) {
20004        updateCpuStatsNow();
20005
20006        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20007        boolean doWakeKills = doKills;
20008        boolean doCpuKills = doKills;
20009        if (mLastPowerCheckRealtime == 0) {
20010            doWakeKills = false;
20011        }
20012        if (mLastPowerCheckUptime == 0) {
20013            doCpuKills = false;
20014        }
20015        if (stats.isScreenOn()) {
20016            doWakeKills = false;
20017        }
20018        final long curRealtime = SystemClock.elapsedRealtime();
20019        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20020        final long curUptime = SystemClock.uptimeMillis();
20021        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20022        mLastPowerCheckRealtime = curRealtime;
20023        mLastPowerCheckUptime = curUptime;
20024        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20025            doWakeKills = false;
20026        }
20027        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20028            doCpuKills = false;
20029        }
20030        int i = mLruProcesses.size();
20031        while (i > 0) {
20032            i--;
20033            ProcessRecord app = mLruProcesses.get(i);
20034            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20035                long wtime;
20036                synchronized (stats) {
20037                    wtime = stats.getProcessWakeTime(app.info.uid,
20038                            app.pid, curRealtime);
20039                }
20040                long wtimeUsed = wtime - app.lastWakeTime;
20041                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20042                if (DEBUG_POWER) {
20043                    StringBuilder sb = new StringBuilder(128);
20044                    sb.append("Wake for ");
20045                    app.toShortString(sb);
20046                    sb.append(": over ");
20047                    TimeUtils.formatDuration(realtimeSince, sb);
20048                    sb.append(" used ");
20049                    TimeUtils.formatDuration(wtimeUsed, sb);
20050                    sb.append(" (");
20051                    sb.append((wtimeUsed*100)/realtimeSince);
20052                    sb.append("%)");
20053                    Slog.i(TAG_POWER, sb.toString());
20054                    sb.setLength(0);
20055                    sb.append("CPU for ");
20056                    app.toShortString(sb);
20057                    sb.append(": over ");
20058                    TimeUtils.formatDuration(uptimeSince, sb);
20059                    sb.append(" used ");
20060                    TimeUtils.formatDuration(cputimeUsed, sb);
20061                    sb.append(" (");
20062                    sb.append((cputimeUsed*100)/uptimeSince);
20063                    sb.append("%)");
20064                    Slog.i(TAG_POWER, sb.toString());
20065                }
20066                // If a process has held a wake lock for more
20067                // than 50% of the time during this period,
20068                // that sounds bad.  Kill!
20069                if (doWakeKills && realtimeSince > 0
20070                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20071                    synchronized (stats) {
20072                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20073                                realtimeSince, wtimeUsed);
20074                    }
20075                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20076                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20077                } else if (doCpuKills && uptimeSince > 0
20078                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20079                    synchronized (stats) {
20080                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20081                                uptimeSince, cputimeUsed);
20082                    }
20083                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20084                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20085                } else {
20086                    app.lastWakeTime = wtime;
20087                    app.lastCpuTime = app.curCpuTime;
20088                }
20089            }
20090        }
20091    }
20092
20093    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20094            long nowElapsed) {
20095        boolean success = true;
20096
20097        if (app.curRawAdj != app.setRawAdj) {
20098            app.setRawAdj = app.curRawAdj;
20099        }
20100
20101        int changes = 0;
20102
20103        if (app.curAdj != app.setAdj) {
20104            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20105            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20106                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20107                    + app.adjType);
20108            app.setAdj = app.curAdj;
20109            app.verifiedAdj = ProcessList.INVALID_ADJ;
20110        }
20111
20112        if (app.setSchedGroup != app.curSchedGroup) {
20113            app.setSchedGroup = app.curSchedGroup;
20114            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20115                    "Setting sched group of " + app.processName
20116                    + " to " + app.curSchedGroup);
20117            if (app.waitingToKill != null && app.curReceiver == null
20118                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20119                app.kill(app.waitingToKill, true);
20120                success = false;
20121            } else {
20122                int processGroup;
20123                switch (app.curSchedGroup) {
20124                    case ProcessList.SCHED_GROUP_BACKGROUND:
20125                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20126                        break;
20127                    case ProcessList.SCHED_GROUP_TOP_APP:
20128                        processGroup = Process.THREAD_GROUP_TOP_APP;
20129                        break;
20130                    default:
20131                        processGroup = Process.THREAD_GROUP_DEFAULT;
20132                        break;
20133                }
20134                if (true) {
20135                    long oldId = Binder.clearCallingIdentity();
20136                    try {
20137                        Process.setProcessGroup(app.pid, processGroup);
20138                    } catch (Exception e) {
20139                        Slog.w(TAG, "Failed setting process group of " + app.pid
20140                                + " to " + app.curSchedGroup);
20141                        e.printStackTrace();
20142                    } finally {
20143                        Binder.restoreCallingIdentity(oldId);
20144                    }
20145                } else {
20146                    if (app.thread != null) {
20147                        try {
20148                            app.thread.setSchedulingGroup(processGroup);
20149                        } catch (RemoteException e) {
20150                        }
20151                    }
20152                }
20153            }
20154        }
20155        if (app.repForegroundActivities != app.foregroundActivities) {
20156            app.repForegroundActivities = app.foregroundActivities;
20157            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20158        }
20159        if (app.repProcState != app.curProcState) {
20160            app.repProcState = app.curProcState;
20161            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20162            if (app.thread != null) {
20163                try {
20164                    if (false) {
20165                        //RuntimeException h = new RuntimeException("here");
20166                        Slog.i(TAG, "Sending new process state " + app.repProcState
20167                                + " to " + app /*, h*/);
20168                    }
20169                    app.thread.setProcessState(app.repProcState);
20170                } catch (RemoteException e) {
20171                }
20172            }
20173        }
20174        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20175                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20176            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20177                // Experimental code to more aggressively collect pss while
20178                // running test...  the problem is that this tends to collect
20179                // the data right when a process is transitioning between process
20180                // states, which well tend to give noisy data.
20181                long start = SystemClock.uptimeMillis();
20182                long pss = Debug.getPss(app.pid, mTmpLong, null);
20183                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20184                mPendingPssProcesses.remove(app);
20185                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20186                        + " to " + app.curProcState + ": "
20187                        + (SystemClock.uptimeMillis()-start) + "ms");
20188            }
20189            app.lastStateTime = now;
20190            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20191                    mTestPssMode, isSleepingLocked(), now);
20192            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20193                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20194                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20195                    + (app.nextPssTime-now) + ": " + app);
20196        } else {
20197            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20198                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20199                    mTestPssMode)))) {
20200                requestPssLocked(app, app.setProcState);
20201                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20202                        mTestPssMode, isSleepingLocked(), now);
20203            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20204                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20205        }
20206        if (app.setProcState != app.curProcState) {
20207            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20208                    "Proc state change of " + app.processName
20209                            + " to " + app.curProcState);
20210            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20211            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20212            if (setImportant && !curImportant) {
20213                // This app is no longer something we consider important enough to allow to
20214                // use arbitrary amounts of battery power.  Note
20215                // its current wake lock time to later know to kill it if
20216                // it is not behaving well.
20217                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20218                synchronized (stats) {
20219                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20220                            app.pid, nowElapsed);
20221                }
20222                app.lastCpuTime = app.curCpuTime;
20223
20224            }
20225            // Inform UsageStats of important process state change
20226            // Must be called before updating setProcState
20227            maybeUpdateUsageStatsLocked(app, nowElapsed);
20228
20229            app.setProcState = app.curProcState;
20230            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20231                app.notCachedSinceIdle = false;
20232            }
20233            if (!doingAll) {
20234                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20235            } else {
20236                app.procStateChanged = true;
20237            }
20238        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20239                > USAGE_STATS_INTERACTION_INTERVAL) {
20240            // For apps that sit around for a long time in the interactive state, we need
20241            // to report this at least once a day so they don't go idle.
20242            maybeUpdateUsageStatsLocked(app, nowElapsed);
20243        }
20244
20245        if (changes != 0) {
20246            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20247                    "Changes in " + app + ": " + changes);
20248            int i = mPendingProcessChanges.size()-1;
20249            ProcessChangeItem item = null;
20250            while (i >= 0) {
20251                item = mPendingProcessChanges.get(i);
20252                if (item.pid == app.pid) {
20253                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20254                            "Re-using existing item: " + item);
20255                    break;
20256                }
20257                i--;
20258            }
20259            if (i < 0) {
20260                // No existing item in pending changes; need a new one.
20261                final int NA = mAvailProcessChanges.size();
20262                if (NA > 0) {
20263                    item = mAvailProcessChanges.remove(NA-1);
20264                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20265                            "Retrieving available item: " + item);
20266                } else {
20267                    item = new ProcessChangeItem();
20268                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20269                            "Allocating new item: " + item);
20270                }
20271                item.changes = 0;
20272                item.pid = app.pid;
20273                item.uid = app.info.uid;
20274                if (mPendingProcessChanges.size() == 0) {
20275                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20276                            "*** Enqueueing dispatch processes changed!");
20277                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20278                }
20279                mPendingProcessChanges.add(item);
20280            }
20281            item.changes |= changes;
20282            item.processState = app.repProcState;
20283            item.foregroundActivities = app.repForegroundActivities;
20284            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20285                    "Item " + Integer.toHexString(System.identityHashCode(item))
20286                    + " " + app.toShortString() + ": changes=" + item.changes
20287                    + " procState=" + item.processState
20288                    + " foreground=" + item.foregroundActivities
20289                    + " type=" + app.adjType + " source=" + app.adjSource
20290                    + " target=" + app.adjTarget);
20291        }
20292
20293        return success;
20294    }
20295
20296    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20297        final UidRecord.ChangeItem pendingChange;
20298        if (uidRec == null || uidRec.pendingChange == null) {
20299            if (mPendingUidChanges.size() == 0) {
20300                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20301                        "*** Enqueueing dispatch uid changed!");
20302                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20303            }
20304            final int NA = mAvailUidChanges.size();
20305            if (NA > 0) {
20306                pendingChange = mAvailUidChanges.remove(NA-1);
20307                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20308                        "Retrieving available item: " + pendingChange);
20309            } else {
20310                pendingChange = new UidRecord.ChangeItem();
20311                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20312                        "Allocating new item: " + pendingChange);
20313            }
20314            if (uidRec != null) {
20315                uidRec.pendingChange = pendingChange;
20316                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20317                    // If this uid is going away, and we haven't yet reported it is gone,
20318                    // then do so now.
20319                    change = UidRecord.CHANGE_GONE_IDLE;
20320                }
20321            } else if (uid < 0) {
20322                throw new IllegalArgumentException("No UidRecord or uid");
20323            }
20324            pendingChange.uidRecord = uidRec;
20325            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20326            mPendingUidChanges.add(pendingChange);
20327        } else {
20328            pendingChange = uidRec.pendingChange;
20329            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20330                change = UidRecord.CHANGE_GONE_IDLE;
20331            }
20332        }
20333        pendingChange.change = change;
20334        pendingChange.processState = uidRec != null
20335                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20336    }
20337
20338    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20339            String authority) {
20340        if (app == null) return;
20341        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20342            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20343            if (userState == null) return;
20344            final long now = SystemClock.elapsedRealtime();
20345            Long lastReported = userState.mProviderLastReportedFg.get(authority);
20346            if (lastReported == null || lastReported < now - 60 * 1000L) {
20347                mUsageStatsService.reportContentProviderUsage(
20348                        authority, providerPkgName, app.userId);
20349                userState.mProviderLastReportedFg.put(authority, now);
20350            }
20351        }
20352    }
20353
20354    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20355        if (DEBUG_USAGE_STATS) {
20356            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20357                    + "] state changes: old = " + app.setProcState + ", new = "
20358                    + app.curProcState);
20359        }
20360        if (mUsageStatsService == null) {
20361            return;
20362        }
20363        boolean isInteraction;
20364        // To avoid some abuse patterns, we are going to be careful about what we consider
20365        // to be an app interaction.  Being the top activity doesn't count while the display
20366        // is sleeping, nor do short foreground services.
20367        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20368            isInteraction = true;
20369            app.fgInteractionTime = 0;
20370        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20371            if (app.fgInteractionTime == 0) {
20372                app.fgInteractionTime = nowElapsed;
20373                isInteraction = false;
20374            } else {
20375                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20376            }
20377        } else {
20378            isInteraction = app.curProcState
20379                    <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20380            app.fgInteractionTime = 0;
20381        }
20382        if (isInteraction && (!app.reportedInteraction
20383                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20384            app.interactionEventTime = nowElapsed;
20385            String[] packages = app.getPackageList();
20386            if (packages != null) {
20387                for (int i = 0; i < packages.length; i++) {
20388                    mUsageStatsService.reportEvent(packages[i], app.userId,
20389                            UsageEvents.Event.SYSTEM_INTERACTION);
20390                }
20391            }
20392        }
20393        app.reportedInteraction = isInteraction;
20394        if (!isInteraction) {
20395            app.interactionEventTime = 0;
20396        }
20397    }
20398
20399    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20400        if (proc.thread != null) {
20401            if (proc.baseProcessTracker != null) {
20402                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20403            }
20404        }
20405    }
20406
20407    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20408            ProcessRecord TOP_APP, boolean doingAll, long now) {
20409        if (app.thread == null) {
20410            return false;
20411        }
20412
20413        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20414
20415        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20416    }
20417
20418    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20419            boolean oomAdj) {
20420        if (isForeground != proc.foregroundServices) {
20421            proc.foregroundServices = isForeground;
20422            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20423                    proc.info.uid);
20424            if (isForeground) {
20425                if (curProcs == null) {
20426                    curProcs = new ArrayList<ProcessRecord>();
20427                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20428                }
20429                if (!curProcs.contains(proc)) {
20430                    curProcs.add(proc);
20431                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20432                            proc.info.packageName, proc.info.uid);
20433                }
20434            } else {
20435                if (curProcs != null) {
20436                    if (curProcs.remove(proc)) {
20437                        mBatteryStatsService.noteEvent(
20438                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20439                                proc.info.packageName, proc.info.uid);
20440                        if (curProcs.size() <= 0) {
20441                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20442                        }
20443                    }
20444                }
20445            }
20446            if (oomAdj) {
20447                updateOomAdjLocked();
20448            }
20449        }
20450    }
20451
20452    private final ActivityRecord resumedAppLocked() {
20453        ActivityRecord act = mStackSupervisor.resumedAppLocked();
20454        String pkg;
20455        int uid;
20456        if (act != null) {
20457            pkg = act.packageName;
20458            uid = act.info.applicationInfo.uid;
20459        } else {
20460            pkg = null;
20461            uid = -1;
20462        }
20463        // Has the UID or resumed package name changed?
20464        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20465                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20466            if (mCurResumedPackage != null) {
20467                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20468                        mCurResumedPackage, mCurResumedUid);
20469            }
20470            mCurResumedPackage = pkg;
20471            mCurResumedUid = uid;
20472            if (mCurResumedPackage != null) {
20473                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20474                        mCurResumedPackage, mCurResumedUid);
20475            }
20476        }
20477        return act;
20478    }
20479
20480    final boolean updateOomAdjLocked(ProcessRecord app) {
20481        final ActivityRecord TOP_ACT = resumedAppLocked();
20482        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20483        final boolean wasCached = app.cached;
20484
20485        mAdjSeq++;
20486
20487        // This is the desired cached adjusment we want to tell it to use.
20488        // If our app is currently cached, we know it, and that is it.  Otherwise,
20489        // we don't know it yet, and it needs to now be cached we will then
20490        // need to do a complete oom adj.
20491        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20492                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20493        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20494                SystemClock.uptimeMillis());
20495        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20496            // Changed to/from cached state, so apps after it in the LRU
20497            // list may also be changed.
20498            updateOomAdjLocked();
20499        }
20500        return success;
20501    }
20502
20503    final void updateOomAdjLocked() {
20504        final ActivityRecord TOP_ACT = resumedAppLocked();
20505        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20506        final long now = SystemClock.uptimeMillis();
20507        final long nowElapsed = SystemClock.elapsedRealtime();
20508        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20509        final int N = mLruProcesses.size();
20510
20511        if (false) {
20512            RuntimeException e = new RuntimeException();
20513            e.fillInStackTrace();
20514            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20515        }
20516
20517        // Reset state in all uid records.
20518        for (int i=mActiveUids.size()-1; i>=0; i--) {
20519            final UidRecord uidRec = mActiveUids.valueAt(i);
20520            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20521                    "Starting update of " + uidRec);
20522            uidRec.reset();
20523        }
20524
20525        mStackSupervisor.rankTaskLayersIfNeeded();
20526
20527        mAdjSeq++;
20528        mNewNumServiceProcs = 0;
20529        mNewNumAServiceProcs = 0;
20530
20531        final int emptyProcessLimit;
20532        final int cachedProcessLimit;
20533        if (mProcessLimit <= 0) {
20534            emptyProcessLimit = cachedProcessLimit = 0;
20535        } else if (mProcessLimit == 1) {
20536            emptyProcessLimit = 1;
20537            cachedProcessLimit = 0;
20538        } else {
20539            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20540            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20541        }
20542
20543        // Let's determine how many processes we have running vs.
20544        // how many slots we have for background processes; we may want
20545        // to put multiple processes in a slot of there are enough of
20546        // them.
20547        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20548                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20549        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20550        if (numEmptyProcs > cachedProcessLimit) {
20551            // If there are more empty processes than our limit on cached
20552            // processes, then use the cached process limit for the factor.
20553            // This ensures that the really old empty processes get pushed
20554            // down to the bottom, so if we are running low on memory we will
20555            // have a better chance at keeping around more cached processes
20556            // instead of a gazillion empty processes.
20557            numEmptyProcs = cachedProcessLimit;
20558        }
20559        int emptyFactor = numEmptyProcs/numSlots;
20560        if (emptyFactor < 1) emptyFactor = 1;
20561        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20562        if (cachedFactor < 1) cachedFactor = 1;
20563        int stepCached = 0;
20564        int stepEmpty = 0;
20565        int numCached = 0;
20566        int numEmpty = 0;
20567        int numTrimming = 0;
20568
20569        mNumNonCachedProcs = 0;
20570        mNumCachedHiddenProcs = 0;
20571
20572        // First update the OOM adjustment for each of the
20573        // application processes based on their current state.
20574        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20575        int nextCachedAdj = curCachedAdj+1;
20576        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20577        int nextEmptyAdj = curEmptyAdj+2;
20578        for (int i=N-1; i>=0; i--) {
20579            ProcessRecord app = mLruProcesses.get(i);
20580            if (!app.killedByAm && app.thread != null) {
20581                app.procStateChanged = false;
20582                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20583
20584                // If we haven't yet assigned the final cached adj
20585                // to the process, do that now.
20586                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20587                    switch (app.curProcState) {
20588                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20589                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20590                            // This process is a cached process holding activities...
20591                            // assign it the next cached value for that type, and then
20592                            // step that cached level.
20593                            app.curRawAdj = curCachedAdj;
20594                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20595                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20596                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20597                                    + ")");
20598                            if (curCachedAdj != nextCachedAdj) {
20599                                stepCached++;
20600                                if (stepCached >= cachedFactor) {
20601                                    stepCached = 0;
20602                                    curCachedAdj = nextCachedAdj;
20603                                    nextCachedAdj += 2;
20604                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20605                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20606                                    }
20607                                }
20608                            }
20609                            break;
20610                        default:
20611                            // For everything else, assign next empty cached process
20612                            // level and bump that up.  Note that this means that
20613                            // long-running services that have dropped down to the
20614                            // cached level will be treated as empty (since their process
20615                            // state is still as a service), which is what we want.
20616                            app.curRawAdj = curEmptyAdj;
20617                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20618                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20619                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20620                                    + ")");
20621                            if (curEmptyAdj != nextEmptyAdj) {
20622                                stepEmpty++;
20623                                if (stepEmpty >= emptyFactor) {
20624                                    stepEmpty = 0;
20625                                    curEmptyAdj = nextEmptyAdj;
20626                                    nextEmptyAdj += 2;
20627                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20628                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20629                                    }
20630                                }
20631                            }
20632                            break;
20633                    }
20634                }
20635
20636                applyOomAdjLocked(app, true, now, nowElapsed);
20637
20638                // Count the number of process types.
20639                switch (app.curProcState) {
20640                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20641                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20642                        mNumCachedHiddenProcs++;
20643                        numCached++;
20644                        if (numCached > cachedProcessLimit) {
20645                            app.kill("cached #" + numCached, true);
20646                        }
20647                        break;
20648                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20649                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20650                                && app.lastActivityTime < oldTime) {
20651                            app.kill("empty for "
20652                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20653                                    / 1000) + "s", true);
20654                        } else {
20655                            numEmpty++;
20656                            if (numEmpty > emptyProcessLimit) {
20657                                app.kill("empty #" + numEmpty, true);
20658                            }
20659                        }
20660                        break;
20661                    default:
20662                        mNumNonCachedProcs++;
20663                        break;
20664                }
20665
20666                if (app.isolated && app.services.size() <= 0) {
20667                    // If this is an isolated process, and there are no
20668                    // services running in it, then the process is no longer
20669                    // needed.  We agressively kill these because we can by
20670                    // definition not re-use the same process again, and it is
20671                    // good to avoid having whatever code was running in them
20672                    // left sitting around after no longer needed.
20673                    app.kill("isolated not needed", true);
20674                } else {
20675                    // Keeping this process, update its uid.
20676                    final UidRecord uidRec = app.uidRecord;
20677                    if (uidRec != null && uidRec.curProcState > app.curProcState) {
20678                        uidRec.curProcState = app.curProcState;
20679                    }
20680                }
20681
20682                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20683                        && !app.killedByAm) {
20684                    numTrimming++;
20685                }
20686            }
20687        }
20688
20689        mNumServiceProcs = mNewNumServiceProcs;
20690
20691        // Now determine the memory trimming level of background processes.
20692        // Unfortunately we need to start at the back of the list to do this
20693        // properly.  We only do this if the number of background apps we
20694        // are managing to keep around is less than half the maximum we desire;
20695        // if we are keeping a good number around, we'll let them use whatever
20696        // memory they want.
20697        final int numCachedAndEmpty = numCached + numEmpty;
20698        int memFactor;
20699        if (numCached <= ProcessList.TRIM_CACHED_APPS
20700                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20701            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20702                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20703            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20704                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20705            } else {
20706                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20707            }
20708        } else {
20709            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20710        }
20711        // We always allow the memory level to go up (better).  We only allow it to go
20712        // down if we are in a state where that is allowed, *and* the total number of processes
20713        // has gone down since last time.
20714        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20715                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20716                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20717        if (memFactor > mLastMemoryLevel) {
20718            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20719                memFactor = mLastMemoryLevel;
20720                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20721            }
20722        }
20723        if (memFactor != mLastMemoryLevel) {
20724            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20725        }
20726        mLastMemoryLevel = memFactor;
20727        mLastNumProcesses = mLruProcesses.size();
20728        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
20729        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20730        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20731            if (mLowRamStartTime == 0) {
20732                mLowRamStartTime = now;
20733            }
20734            int step = 0;
20735            int fgTrimLevel;
20736            switch (memFactor) {
20737                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20738                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20739                    break;
20740                case ProcessStats.ADJ_MEM_FACTOR_LOW:
20741                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20742                    break;
20743                default:
20744                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20745                    break;
20746            }
20747            int factor = numTrimming/3;
20748            int minFactor = 2;
20749            if (mHomeProcess != null) minFactor++;
20750            if (mPreviousProcess != null) minFactor++;
20751            if (factor < minFactor) factor = minFactor;
20752            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20753            for (int i=N-1; i>=0; i--) {
20754                ProcessRecord app = mLruProcesses.get(i);
20755                if (allChanged || app.procStateChanged) {
20756                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20757                    app.procStateChanged = false;
20758                }
20759                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20760                        && !app.killedByAm) {
20761                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
20762                        try {
20763                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20764                                    "Trimming memory of " + app.processName + " to " + curLevel);
20765                            app.thread.scheduleTrimMemory(curLevel);
20766                        } catch (RemoteException e) {
20767                        }
20768                        if (false) {
20769                            // For now we won't do this; our memory trimming seems
20770                            // to be good enough at this point that destroying
20771                            // activities causes more harm than good.
20772                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20773                                    && app != mHomeProcess && app != mPreviousProcess) {
20774                                // Need to do this on its own message because the stack may not
20775                                // be in a consistent state at this point.
20776                                // For these apps we will also finish their activities
20777                                // to help them free memory.
20778                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20779                            }
20780                        }
20781                    }
20782                    app.trimMemoryLevel = curLevel;
20783                    step++;
20784                    if (step >= factor) {
20785                        step = 0;
20786                        switch (curLevel) {
20787                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20788                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20789                                break;
20790                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20791                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20792                                break;
20793                        }
20794                    }
20795                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20796                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20797                            && app.thread != null) {
20798                        try {
20799                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20800                                    "Trimming memory of heavy-weight " + app.processName
20801                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20802                            app.thread.scheduleTrimMemory(
20803                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20804                        } catch (RemoteException e) {
20805                        }
20806                    }
20807                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20808                } else {
20809                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20810                            || app.systemNoUi) && app.pendingUiClean) {
20811                        // If this application is now in the background and it
20812                        // had done UI, then give it the special trim level to
20813                        // have it free UI resources.
20814                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20815                        if (app.trimMemoryLevel < level && app.thread != null) {
20816                            try {
20817                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20818                                        "Trimming memory of bg-ui " + app.processName
20819                                        + " to " + level);
20820                                app.thread.scheduleTrimMemory(level);
20821                            } catch (RemoteException e) {
20822                            }
20823                        }
20824                        app.pendingUiClean = false;
20825                    }
20826                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20827                        try {
20828                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20829                                    "Trimming memory of fg " + app.processName
20830                                    + " to " + fgTrimLevel);
20831                            app.thread.scheduleTrimMemory(fgTrimLevel);
20832                        } catch (RemoteException e) {
20833                        }
20834                    }
20835                    app.trimMemoryLevel = fgTrimLevel;
20836                }
20837            }
20838        } else {
20839            if (mLowRamStartTime != 0) {
20840                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20841                mLowRamStartTime = 0;
20842            }
20843            for (int i=N-1; i>=0; i--) {
20844                ProcessRecord app = mLruProcesses.get(i);
20845                if (allChanged || app.procStateChanged) {
20846                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
20847                    app.procStateChanged = false;
20848                }
20849                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20850                        || app.systemNoUi) && app.pendingUiClean) {
20851                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20852                            && app.thread != null) {
20853                        try {
20854                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20855                                    "Trimming memory of ui hidden " + app.processName
20856                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20857                            app.thread.scheduleTrimMemory(
20858                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20859                        } catch (RemoteException e) {
20860                        }
20861                    }
20862                    app.pendingUiClean = false;
20863                }
20864                app.trimMemoryLevel = 0;
20865            }
20866        }
20867
20868        if (mAlwaysFinishActivities) {
20869            // Need to do this on its own message because the stack may not
20870            // be in a consistent state at this point.
20871            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20872        }
20873
20874        if (allChanged) {
20875            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20876        }
20877
20878        // Update from any uid changes.
20879        for (int i=mActiveUids.size()-1; i>=0; i--) {
20880            final UidRecord uidRec = mActiveUids.valueAt(i);
20881            int uidChange = UidRecord.CHANGE_PROCSTATE;
20882            if (uidRec.setProcState != uidRec.curProcState) {
20883                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20884                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20885                        + " to " + uidRec.curProcState);
20886                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20887                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20888                        uidRec.lastBackgroundTime = nowElapsed;
20889                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20890                            // Note: the background settle time is in elapsed realtime, while
20891                            // the handler time base is uptime.  All this means is that we may
20892                            // stop background uids later than we had intended, but that only
20893                            // happens because the device was sleeping so we are okay anyway.
20894                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20895                        }
20896                    }
20897                } else {
20898                    if (uidRec.idle) {
20899                        uidChange = UidRecord.CHANGE_ACTIVE;
20900                        uidRec.idle = false;
20901                    }
20902                    uidRec.lastBackgroundTime = 0;
20903                }
20904                uidRec.setProcState = uidRec.curProcState;
20905                enqueueUidChangeLocked(uidRec, -1, uidChange);
20906                noteUidProcessState(uidRec.uid, uidRec.curProcState);
20907            }
20908        }
20909
20910        if (mProcessStats.shouldWriteNowLocked(now)) {
20911            mHandler.post(new Runnable() {
20912                @Override public void run() {
20913                    synchronized (ActivityManagerService.this) {
20914                        mProcessStats.writeStateAsyncLocked();
20915                    }
20916                }
20917            });
20918        }
20919
20920        if (DEBUG_OOM_ADJ) {
20921            final long duration = SystemClock.uptimeMillis() - now;
20922            if (false) {
20923                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20924                        new RuntimeException("here").fillInStackTrace());
20925            } else {
20926                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20927            }
20928        }
20929    }
20930
20931    final void idleUids() {
20932        synchronized (this) {
20933            final long nowElapsed = SystemClock.elapsedRealtime();
20934            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20935            long nextTime = 0;
20936            for (int i=mActiveUids.size()-1; i>=0; i--) {
20937                final UidRecord uidRec = mActiveUids.valueAt(i);
20938                final long bgTime = uidRec.lastBackgroundTime;
20939                if (bgTime > 0 && !uidRec.idle) {
20940                    if (bgTime <= maxBgTime) {
20941                        uidRec.idle = true;
20942                        doStopUidLocked(uidRec.uid, uidRec);
20943                    } else {
20944                        if (nextTime == 0 || nextTime > bgTime) {
20945                            nextTime = bgTime;
20946                        }
20947                    }
20948                }
20949            }
20950            if (nextTime > 0) {
20951                mHandler.removeMessages(IDLE_UIDS_MSG);
20952                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20953                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20954            }
20955        }
20956    }
20957
20958    final void runInBackgroundDisabled(int uid) {
20959        synchronized (this) {
20960            UidRecord uidRec = mActiveUids.get(uid);
20961            if (uidRec != null) {
20962                // This uid is actually running...  should it be considered background now?
20963                if (uidRec.idle) {
20964                    doStopUidLocked(uidRec.uid, uidRec);
20965                }
20966            } else {
20967                // This uid isn't actually running...  still send a report about it being "stopped".
20968                doStopUidLocked(uid, null);
20969            }
20970        }
20971    }
20972
20973    final void doStopUidLocked(int uid, final UidRecord uidRec) {
20974        mServices.stopInBackgroundLocked(uid);
20975        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20976    }
20977
20978    final void trimApplications() {
20979        synchronized (this) {
20980            int i;
20981
20982            // First remove any unused application processes whose package
20983            // has been removed.
20984            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20985                final ProcessRecord app = mRemovedProcesses.get(i);
20986                if (app.activities.size() == 0
20987                        && app.curReceiver == null && app.services.size() == 0) {
20988                    Slog.i(
20989                        TAG, "Exiting empty application process "
20990                        + app.toShortString() + " ("
20991                        + (app.thread != null ? app.thread.asBinder() : null)
20992                        + ")\n");
20993                    if (app.pid > 0 && app.pid != MY_PID) {
20994                        app.kill("empty", false);
20995                    } else {
20996                        try {
20997                            app.thread.scheduleExit();
20998                        } catch (Exception e) {
20999                            // Ignore exceptions.
21000                        }
21001                    }
21002                    cleanUpApplicationRecordLocked(app, false, true, -1);
21003                    mRemovedProcesses.remove(i);
21004
21005                    if (app.persistent) {
21006                        addAppLocked(app.info, false, null /* ABI override */);
21007                    }
21008                }
21009            }
21010
21011            // Now update the oom adj for all processes.
21012            updateOomAdjLocked();
21013        }
21014    }
21015
21016    /** This method sends the specified signal to each of the persistent apps */
21017    public void signalPersistentProcesses(int sig) throws RemoteException {
21018        if (sig != Process.SIGNAL_USR1) {
21019            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21020        }
21021
21022        synchronized (this) {
21023            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21024                    != PackageManager.PERMISSION_GRANTED) {
21025                throw new SecurityException("Requires permission "
21026                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21027            }
21028
21029            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21030                ProcessRecord r = mLruProcesses.get(i);
21031                if (r.thread != null && r.persistent) {
21032                    Process.sendSignal(r.pid, sig);
21033                }
21034            }
21035        }
21036    }
21037
21038    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21039        if (proc == null || proc == mProfileProc) {
21040            proc = mProfileProc;
21041            profileType = mProfileType;
21042            clearProfilerLocked();
21043        }
21044        if (proc == null) {
21045            return;
21046        }
21047        try {
21048            proc.thread.profilerControl(false, null, profileType);
21049        } catch (RemoteException e) {
21050            throw new IllegalStateException("Process disappeared");
21051        }
21052    }
21053
21054    private void clearProfilerLocked() {
21055        if (mProfileFd != null) {
21056            try {
21057                mProfileFd.close();
21058            } catch (IOException e) {
21059            }
21060        }
21061        mProfileApp = null;
21062        mProfileProc = null;
21063        mProfileFile = null;
21064        mProfileType = 0;
21065        mAutoStopProfiler = false;
21066        mSamplingInterval = 0;
21067    }
21068
21069    public boolean profileControl(String process, int userId, boolean start,
21070            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21071
21072        try {
21073            synchronized (this) {
21074                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21075                // its own permission.
21076                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21077                        != PackageManager.PERMISSION_GRANTED) {
21078                    throw new SecurityException("Requires permission "
21079                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21080                }
21081
21082                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21083                    throw new IllegalArgumentException("null profile info or fd");
21084                }
21085
21086                ProcessRecord proc = null;
21087                if (process != null) {
21088                    proc = findProcessLocked(process, userId, "profileControl");
21089                }
21090
21091                if (start && (proc == null || proc.thread == null)) {
21092                    throw new IllegalArgumentException("Unknown process: " + process);
21093                }
21094
21095                if (start) {
21096                    stopProfilerLocked(null, 0);
21097                    setProfileApp(proc.info, proc.processName, profilerInfo);
21098                    mProfileProc = proc;
21099                    mProfileType = profileType;
21100                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21101                    try {
21102                        fd = fd.dup();
21103                    } catch (IOException e) {
21104                        fd = null;
21105                    }
21106                    profilerInfo.profileFd = fd;
21107                    proc.thread.profilerControl(start, profilerInfo, profileType);
21108                    fd = null;
21109                    mProfileFd = null;
21110                } else {
21111                    stopProfilerLocked(proc, profileType);
21112                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21113                        try {
21114                            profilerInfo.profileFd.close();
21115                        } catch (IOException e) {
21116                        }
21117                    }
21118                }
21119
21120                return true;
21121            }
21122        } catch (RemoteException e) {
21123            throw new IllegalStateException("Process disappeared");
21124        } finally {
21125            if (profilerInfo != null && profilerInfo.profileFd != null) {
21126                try {
21127                    profilerInfo.profileFd.close();
21128                } catch (IOException e) {
21129                }
21130            }
21131        }
21132    }
21133
21134    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21135        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21136                userId, true, ALLOW_FULL_ONLY, callName, null);
21137        ProcessRecord proc = null;
21138        try {
21139            int pid = Integer.parseInt(process);
21140            synchronized (mPidsSelfLocked) {
21141                proc = mPidsSelfLocked.get(pid);
21142            }
21143        } catch (NumberFormatException e) {
21144        }
21145
21146        if (proc == null) {
21147            ArrayMap<String, SparseArray<ProcessRecord>> all
21148                    = mProcessNames.getMap();
21149            SparseArray<ProcessRecord> procs = all.get(process);
21150            if (procs != null && procs.size() > 0) {
21151                proc = procs.valueAt(0);
21152                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21153                    for (int i=1; i<procs.size(); i++) {
21154                        ProcessRecord thisProc = procs.valueAt(i);
21155                        if (thisProc.userId == userId) {
21156                            proc = thisProc;
21157                            break;
21158                        }
21159                    }
21160                }
21161            }
21162        }
21163
21164        return proc;
21165    }
21166
21167    public boolean dumpHeap(String process, int userId, boolean managed,
21168            String path, ParcelFileDescriptor fd) throws RemoteException {
21169
21170        try {
21171            synchronized (this) {
21172                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21173                // its own permission (same as profileControl).
21174                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21175                        != PackageManager.PERMISSION_GRANTED) {
21176                    throw new SecurityException("Requires permission "
21177                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21178                }
21179
21180                if (fd == null) {
21181                    throw new IllegalArgumentException("null fd");
21182                }
21183
21184                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21185                if (proc == null || proc.thread == null) {
21186                    throw new IllegalArgumentException("Unknown process: " + process);
21187                }
21188
21189                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21190                if (!isDebuggable) {
21191                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21192                        throw new SecurityException("Process not debuggable: " + proc);
21193                    }
21194                }
21195
21196                proc.thread.dumpHeap(managed, path, fd);
21197                fd = null;
21198                return true;
21199            }
21200        } catch (RemoteException e) {
21201            throw new IllegalStateException("Process disappeared");
21202        } finally {
21203            if (fd != null) {
21204                try {
21205                    fd.close();
21206                } catch (IOException e) {
21207                }
21208            }
21209        }
21210    }
21211
21212    @Override
21213    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21214            String reportPackage) {
21215        if (processName != null) {
21216            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21217                    "setDumpHeapDebugLimit()");
21218        } else {
21219            synchronized (mPidsSelfLocked) {
21220                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21221                if (proc == null) {
21222                    throw new SecurityException("No process found for calling pid "
21223                            + Binder.getCallingPid());
21224                }
21225                if (!Build.IS_DEBUGGABLE
21226                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21227                    throw new SecurityException("Not running a debuggable build");
21228                }
21229                processName = proc.processName;
21230                uid = proc.uid;
21231                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21232                    throw new SecurityException("Package " + reportPackage + " is not running in "
21233                            + proc);
21234                }
21235            }
21236        }
21237        synchronized (this) {
21238            if (maxMemSize > 0) {
21239                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21240            } else {
21241                if (uid != 0) {
21242                    mMemWatchProcesses.remove(processName, uid);
21243                } else {
21244                    mMemWatchProcesses.getMap().remove(processName);
21245                }
21246            }
21247        }
21248    }
21249
21250    @Override
21251    public void dumpHeapFinished(String path) {
21252        synchronized (this) {
21253            if (Binder.getCallingPid() != mMemWatchDumpPid) {
21254                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21255                        + " does not match last pid " + mMemWatchDumpPid);
21256                return;
21257            }
21258            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21259                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21260                        + " does not match last path " + mMemWatchDumpFile);
21261                return;
21262            }
21263            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21264            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21265        }
21266    }
21267
21268    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21269    public void monitor() {
21270        synchronized (this) { }
21271    }
21272
21273    void onCoreSettingsChange(Bundle settings) {
21274        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21275            ProcessRecord processRecord = mLruProcesses.get(i);
21276            try {
21277                if (processRecord.thread != null) {
21278                    processRecord.thread.setCoreSettings(settings);
21279                }
21280            } catch (RemoteException re) {
21281                /* ignore */
21282            }
21283        }
21284    }
21285
21286    // Multi-user methods
21287
21288    /**
21289     * Start user, if its not already running, but don't bring it to foreground.
21290     */
21291    @Override
21292    public boolean startUserInBackground(final int userId) {
21293        return mUserController.startUser(userId, /* foreground */ false);
21294    }
21295
21296    @Override
21297    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21298        return mUserController.unlockUser(userId, token, secret, listener);
21299    }
21300
21301    @Override
21302    public boolean switchUser(final int targetUserId) {
21303        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21304        UserInfo currentUserInfo;
21305        UserInfo targetUserInfo;
21306        synchronized (this) {
21307            int currentUserId = mUserController.getCurrentUserIdLocked();
21308            currentUserInfo = mUserController.getUserInfo(currentUserId);
21309            targetUserInfo = mUserController.getUserInfo(targetUserId);
21310            if (targetUserInfo == null) {
21311                Slog.w(TAG, "No user info for user #" + targetUserId);
21312                return false;
21313            }
21314            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21315                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21316                        + " when device is in demo mode");
21317                return false;
21318            }
21319            if (!targetUserInfo.supportsSwitchTo()) {
21320                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21321                return false;
21322            }
21323            if (targetUserInfo.isManagedProfile()) {
21324                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21325                return false;
21326            }
21327            mUserController.setTargetUserIdLocked(targetUserId);
21328        }
21329        Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21330        mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21331        mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21332        return true;
21333    }
21334
21335    void scheduleStartProfilesLocked() {
21336        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21337            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21338                    DateUtils.SECOND_IN_MILLIS);
21339        }
21340    }
21341
21342    @Override
21343    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21344        return mUserController.stopUser(userId, force, callback);
21345    }
21346
21347    @Override
21348    public UserInfo getCurrentUser() {
21349        return mUserController.getCurrentUser();
21350    }
21351
21352    @Override
21353    public boolean isUserRunning(int userId, int flags) {
21354        if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21355                INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21356            String msg = "Permission Denial: isUserRunning() from pid="
21357                    + Binder.getCallingPid()
21358                    + ", uid=" + Binder.getCallingUid()
21359                    + " requires " + INTERACT_ACROSS_USERS;
21360            Slog.w(TAG, msg);
21361            throw new SecurityException(msg);
21362        }
21363        synchronized (this) {
21364            return mUserController.isUserRunningLocked(userId, flags);
21365        }
21366    }
21367
21368    @Override
21369    public int[] getRunningUserIds() {
21370        if (checkCallingPermission(INTERACT_ACROSS_USERS)
21371                != PackageManager.PERMISSION_GRANTED) {
21372            String msg = "Permission Denial: isUserRunning() from pid="
21373                    + Binder.getCallingPid()
21374                    + ", uid=" + Binder.getCallingUid()
21375                    + " requires " + INTERACT_ACROSS_USERS;
21376            Slog.w(TAG, msg);
21377            throw new SecurityException(msg);
21378        }
21379        synchronized (this) {
21380            return mUserController.getStartedUserArrayLocked();
21381        }
21382    }
21383
21384    @Override
21385    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21386        mUserController.registerUserSwitchObserver(observer, name);
21387    }
21388
21389    @Override
21390    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21391        mUserController.unregisterUserSwitchObserver(observer);
21392    }
21393
21394    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21395        if (info == null) return null;
21396        ApplicationInfo newInfo = new ApplicationInfo(info);
21397        newInfo.initForUser(userId);
21398        return newInfo;
21399    }
21400
21401    public boolean isUserStopped(int userId) {
21402        synchronized (this) {
21403            return mUserController.getStartedUserStateLocked(userId) == null;
21404        }
21405    }
21406
21407    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21408        if (aInfo == null
21409                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21410            return aInfo;
21411        }
21412
21413        ActivityInfo info = new ActivityInfo(aInfo);
21414        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21415        return info;
21416    }
21417
21418    private boolean processSanityChecksLocked(ProcessRecord process) {
21419        if (process == null || process.thread == null) {
21420            return false;
21421        }
21422
21423        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21424        if (!isDebuggable) {
21425            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21426                return false;
21427            }
21428        }
21429
21430        return true;
21431    }
21432
21433    public boolean startBinderTracking() throws RemoteException {
21434        synchronized (this) {
21435            mBinderTransactionTrackingEnabled = true;
21436            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21437            // permission (same as profileControl).
21438            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21439                    != PackageManager.PERMISSION_GRANTED) {
21440                throw new SecurityException("Requires permission "
21441                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21442            }
21443
21444            for (int i = 0; i < mLruProcesses.size(); i++) {
21445                ProcessRecord process = mLruProcesses.get(i);
21446                if (!processSanityChecksLocked(process)) {
21447                    continue;
21448                }
21449                try {
21450                    process.thread.startBinderTracking();
21451                } catch (RemoteException e) {
21452                    Log.v(TAG, "Process disappared");
21453                }
21454            }
21455            return true;
21456        }
21457    }
21458
21459    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21460        try {
21461            synchronized (this) {
21462                mBinderTransactionTrackingEnabled = false;
21463                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21464                // permission (same as profileControl).
21465                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21466                        != PackageManager.PERMISSION_GRANTED) {
21467                    throw new SecurityException("Requires permission "
21468                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21469                }
21470
21471                if (fd == null) {
21472                    throw new IllegalArgumentException("null fd");
21473                }
21474
21475                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21476                pw.println("Binder transaction traces for all processes.\n");
21477                for (ProcessRecord process : mLruProcesses) {
21478                    if (!processSanityChecksLocked(process)) {
21479                        continue;
21480                    }
21481
21482                    pw.println("Traces for process: " + process.processName);
21483                    pw.flush();
21484                    try {
21485                        TransferPipe tp = new TransferPipe();
21486                        try {
21487                            process.thread.stopBinderTrackingAndDump(
21488                                    tp.getWriteFd().getFileDescriptor());
21489                            tp.go(fd.getFileDescriptor());
21490                        } finally {
21491                            tp.kill();
21492                        }
21493                    } catch (IOException e) {
21494                        pw.println("Failure while dumping IPC traces from " + process +
21495                                ".  Exception: " + e);
21496                        pw.flush();
21497                    } catch (RemoteException e) {
21498                        pw.println("Got a RemoteException while dumping IPC traces from " +
21499                                process + ".  Exception: " + e);
21500                        pw.flush();
21501                    }
21502                }
21503                fd = null;
21504                return true;
21505            }
21506        } finally {
21507            if (fd != null) {
21508                try {
21509                    fd.close();
21510                } catch (IOException e) {
21511                }
21512            }
21513        }
21514    }
21515
21516    private final class LocalService extends ActivityManagerInternal {
21517        @Override
21518        public void onWakefulnessChanged(int wakefulness) {
21519            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21520        }
21521
21522        @Override
21523        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21524                String processName, String abiOverride, int uid, Runnable crashHandler) {
21525            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21526                    processName, abiOverride, uid, crashHandler);
21527        }
21528
21529        @Override
21530        public SleepToken acquireSleepToken(String tag) {
21531            Preconditions.checkNotNull(tag);
21532
21533            ComponentName requestedVrService = null;
21534            ComponentName callingVrActivity = null;
21535            int userId = -1;
21536            synchronized (ActivityManagerService.this) {
21537                if (mFocusedActivity != null) {
21538                    requestedVrService = mFocusedActivity.requestedVrComponent;
21539                    callingVrActivity = mFocusedActivity.info.getComponentName();
21540                    userId = mFocusedActivity.userId;
21541                }
21542            }
21543
21544            if (requestedVrService != null) {
21545                applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21546            }
21547
21548            synchronized (ActivityManagerService.this) {
21549                SleepTokenImpl token = new SleepTokenImpl(tag);
21550                mSleepTokens.add(token);
21551                updateSleepIfNeededLocked();
21552                return token;
21553            }
21554        }
21555
21556        @Override
21557        public ComponentName getHomeActivityForUser(int userId) {
21558            synchronized (ActivityManagerService.this) {
21559                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21560                return homeActivity == null ? null : homeActivity.realActivity;
21561            }
21562        }
21563
21564        @Override
21565        public void onUserRemoved(int userId) {
21566            synchronized (ActivityManagerService.this) {
21567                ActivityManagerService.this.onUserStoppedLocked(userId);
21568            }
21569        }
21570
21571        @Override
21572        public void onLocalVoiceInteractionStarted(IBinder activity,
21573                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21574            synchronized (ActivityManagerService.this) {
21575                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21576                        voiceSession, voiceInteractor);
21577            }
21578        }
21579
21580        @Override
21581        public void notifyStartingWindowDrawn() {
21582            synchronized (ActivityManagerService.this) {
21583                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21584            }
21585        }
21586
21587        @Override
21588        public void notifyAppTransitionStarting(int reason) {
21589            synchronized (ActivityManagerService.this) {
21590                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21591            }
21592        }
21593
21594        @Override
21595        public void notifyAppTransitionFinished() {
21596            synchronized (ActivityManagerService.this) {
21597                mStackSupervisor.notifyAppTransitionDone();
21598            }
21599        }
21600
21601        @Override
21602        public void notifyAppTransitionCancelled() {
21603            synchronized (ActivityManagerService.this) {
21604                mStackSupervisor.notifyAppTransitionDone();
21605            }
21606        }
21607
21608        @Override
21609        public List<IBinder> getTopVisibleActivities() {
21610            synchronized (ActivityManagerService.this) {
21611                return mStackSupervisor.getTopVisibleActivities();
21612            }
21613        }
21614
21615        @Override
21616        public void notifyDockedStackMinimizedChanged(boolean minimized) {
21617            synchronized (ActivityManagerService.this) {
21618                mStackSupervisor.setDockedStackMinimized(minimized);
21619            }
21620        }
21621
21622        @Override
21623        public void killForegroundAppsForUser(int userHandle) {
21624            synchronized (ActivityManagerService.this) {
21625                final ArrayList<ProcessRecord> procs = new ArrayList<>();
21626                final int NP = mProcessNames.getMap().size();
21627                for (int ip = 0; ip < NP; ip++) {
21628                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21629                    final int NA = apps.size();
21630                    for (int ia = 0; ia < NA; ia++) {
21631                        final ProcessRecord app = apps.valueAt(ia);
21632                        if (app.persistent) {
21633                            // We don't kill persistent processes.
21634                            continue;
21635                        }
21636                        if (app.removed) {
21637                            procs.add(app);
21638                        } else if (app.userId == userHandle && app.foregroundActivities) {
21639                            app.removed = true;
21640                            procs.add(app);
21641                        }
21642                    }
21643                }
21644
21645                final int N = procs.size();
21646                for (int i = 0; i < N; i++) {
21647                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
21648                }
21649            }
21650        }
21651
21652        @Override
21653        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21654            if (!(target instanceof PendingIntentRecord)) {
21655                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21656                return;
21657            }
21658            ((PendingIntentRecord) target).setWhitelistDuration(duration);
21659        }
21660
21661        @Override
21662        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
21663                int userId) {
21664            Preconditions.checkNotNull(values, "Configuration must not be null");
21665            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
21666            synchronized (ActivityManagerService.this) {
21667                updateConfigurationLocked(values, null, false, true, userId);
21668            }
21669        }
21670    }
21671
21672    private final class SleepTokenImpl extends SleepToken {
21673        private final String mTag;
21674        private final long mAcquireTime;
21675
21676        public SleepTokenImpl(String tag) {
21677            mTag = tag;
21678            mAcquireTime = SystemClock.uptimeMillis();
21679        }
21680
21681        @Override
21682        public void release() {
21683            synchronized (ActivityManagerService.this) {
21684                if (mSleepTokens.remove(this)) {
21685                    updateSleepIfNeededLocked();
21686                }
21687            }
21688        }
21689
21690        @Override
21691        public String toString() {
21692            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21693        }
21694    }
21695
21696    /**
21697     * An implementation of IAppTask, that allows an app to manage its own tasks via
21698     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
21699     * only the process that calls getAppTasks() can call the AppTask methods.
21700     */
21701    class AppTaskImpl extends IAppTask.Stub {
21702        private int mTaskId;
21703        private int mCallingUid;
21704
21705        public AppTaskImpl(int taskId, int callingUid) {
21706            mTaskId = taskId;
21707            mCallingUid = callingUid;
21708        }
21709
21710        private void checkCaller() {
21711            if (mCallingUid != Binder.getCallingUid()) {
21712                throw new SecurityException("Caller " + mCallingUid
21713                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21714            }
21715        }
21716
21717        @Override
21718        public void finishAndRemoveTask() {
21719            checkCaller();
21720
21721            synchronized (ActivityManagerService.this) {
21722                long origId = Binder.clearCallingIdentity();
21723                try {
21724                    // We remove the task from recents to preserve backwards
21725                    if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21726                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21727                    }
21728                } finally {
21729                    Binder.restoreCallingIdentity(origId);
21730                }
21731            }
21732        }
21733
21734        @Override
21735        public ActivityManager.RecentTaskInfo getTaskInfo() {
21736            checkCaller();
21737
21738            synchronized (ActivityManagerService.this) {
21739                long origId = Binder.clearCallingIdentity();
21740                try {
21741                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21742                    if (tr == null) {
21743                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21744                    }
21745                    return createRecentTaskInfoFromTaskRecord(tr);
21746                } finally {
21747                    Binder.restoreCallingIdentity(origId);
21748                }
21749            }
21750        }
21751
21752        @Override
21753        public void moveToFront() {
21754            checkCaller();
21755            // Will bring task to front if it already has a root activity.
21756            final long origId = Binder.clearCallingIdentity();
21757            try {
21758                synchronized (this) {
21759                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21760                }
21761            } finally {
21762                Binder.restoreCallingIdentity(origId);
21763            }
21764        }
21765
21766        @Override
21767        public int startActivity(IBinder whoThread, String callingPackage,
21768                Intent intent, String resolvedType, Bundle bOptions) {
21769            checkCaller();
21770
21771            int callingUser = UserHandle.getCallingUserId();
21772            TaskRecord tr;
21773            IApplicationThread appThread;
21774            synchronized (ActivityManagerService.this) {
21775                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21776                if (tr == null) {
21777                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21778                }
21779                appThread = ApplicationThreadNative.asInterface(whoThread);
21780                if (appThread == null) {
21781                    throw new IllegalArgumentException("Bad app thread " + appThread);
21782                }
21783            }
21784            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21785                    resolvedType, null, null, null, null, 0, 0, null, null,
21786                    null, bOptions, false, callingUser, null, tr);
21787        }
21788
21789        @Override
21790        public void setExcludeFromRecents(boolean exclude) {
21791            checkCaller();
21792
21793            synchronized (ActivityManagerService.this) {
21794                long origId = Binder.clearCallingIdentity();
21795                try {
21796                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21797                    if (tr == null) {
21798                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21799                    }
21800                    Intent intent = tr.getBaseIntent();
21801                    if (exclude) {
21802                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21803                    } else {
21804                        intent.setFlags(intent.getFlags()
21805                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21806                    }
21807                } finally {
21808                    Binder.restoreCallingIdentity(origId);
21809                }
21810            }
21811        }
21812    }
21813
21814    /**
21815     * Kill processes for the user with id userId and that depend on the package named packageName
21816     */
21817    @Override
21818    public void killPackageDependents(String packageName, int userId) {
21819        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21820        if (packageName == null) {
21821            throw new NullPointerException(
21822                    "Cannot kill the dependents of a package without its name.");
21823        }
21824
21825        long callingId = Binder.clearCallingIdentity();
21826        IPackageManager pm = AppGlobals.getPackageManager();
21827        int pkgUid = -1;
21828        try {
21829            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21830        } catch (RemoteException e) {
21831        }
21832        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21833            throw new IllegalArgumentException(
21834                    "Cannot kill dependents of non-existing package " + packageName);
21835        }
21836        try {
21837            synchronized(this) {
21838                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21839                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21840                        "dep: " + packageName);
21841            }
21842        } finally {
21843            Binder.restoreCallingIdentity(callingId);
21844        }
21845    }
21846}
21847