ActivityManagerService.java revision 9e83cbbc10014b3ed560b3181f594868cd89f9ae
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 static android.Manifest.permission.CHANGE_CONFIGURATION;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS;
21import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
22import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
23import static android.Manifest.permission.READ_FRAME_BUFFER;
24import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
25import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
26import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
27import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
28import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
29import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
30import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
31import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
32import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
33import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
34import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
35import static android.content.pm.PackageManager.GET_PROVIDERS;
36import static android.content.pm.PackageManager.MATCH_ANY_USER;
37import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
38import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
39import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
40import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
41import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
42import static android.content.pm.PackageManager.PERMISSION_GRANTED;
43import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
44import static android.os.Build.VERSION_CODES.N;
45import static android.os.Process.PROC_CHAR;
46import static android.os.Process.PROC_OUT_LONG;
47import static android.os.Process.PROC_PARENS;
48import static android.os.Process.PROC_SPACE_TERM;
49import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
50import static android.provider.Settings.Global.DEBUG_APP;
51import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
52import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
53import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
54import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
55import static android.provider.Settings.System.FONT_SCALE;
56import static android.view.Display.DEFAULT_DISPLAY;
57import static com.android.internal.util.XmlUtils.readBooleanAttribute;
58import static com.android.internal.util.XmlUtils.readIntAttribute;
59import static com.android.internal.util.XmlUtils.readLongAttribute;
60import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
61import static com.android.internal.util.XmlUtils.writeIntAttribute;
62import static com.android.internal.util.XmlUtils.writeLongAttribute;
63import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
64import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
65import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
66import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
67import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
68import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
69import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
70import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
71import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
72import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
73import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
74import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
75import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
76import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
77import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
78import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
79import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
80import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
81import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
82import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
83import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
84import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
85import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
86import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
87import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
88import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
89import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
90import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
91import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
92import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
93import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
94import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
95import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
96import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
97import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
98import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
99import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
100import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
101import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
102import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
103import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
104import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
105import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
106import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
107import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
108import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
109import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
110import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
111import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
112import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
113import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
114import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
115import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
116import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
117import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
118import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
119import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
120import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
121import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
122import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
123import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
124import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
125import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
126import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
127import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
128import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
129import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
130import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
131import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
132import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
133import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
134import static com.android.server.wm.AppTransition.TRANSIT_NONE;
135import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
136import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
137import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
138import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
139import static org.xmlpull.v1.XmlPullParser.START_TAG;
140
141import android.Manifest;
142import android.Manifest.permission;
143import android.annotation.NonNull;
144import android.annotation.Nullable;
145import android.annotation.UserIdInt;
146import android.app.Activity;
147import android.app.ActivityManager;
148import android.app.ActivityManager.RunningTaskInfo;
149import android.app.ActivityManager.StackId;
150import android.app.ActivityManager.StackInfo;
151import android.app.ActivityManager.TaskSnapshot;
152import android.app.ActivityManager.TaskThumbnailInfo;
153import android.app.ActivityManagerInternal;
154import android.app.ActivityManagerInternal.PictureInPictureArguments;
155import android.app.ActivityManagerInternal.SleepToken;
156import android.app.ActivityOptions;
157import android.app.ActivityThread;
158import android.app.AlertDialog;
159import android.app.AppGlobals;
160import android.app.AppOpsManager;
161import android.app.ApplicationErrorReport;
162import android.app.ApplicationThreadConstants;
163import android.app.BroadcastOptions;
164import android.app.ContentProviderHolder;
165import android.app.Dialog;
166import android.app.IActivityContainer;
167import android.app.IActivityContainerCallback;
168import android.app.IActivityController;
169import android.app.IActivityManager;
170import android.app.IAppTask;
171import android.app.IApplicationThread;
172import android.app.IInstrumentationWatcher;
173import android.app.INotificationManager;
174import android.app.IProcessObserver;
175import android.app.IServiceConnection;
176import android.app.IStopUserCallback;
177import android.app.ITaskStackListener;
178import android.app.IUiAutomationConnection;
179import android.app.IUidObserver;
180import android.app.IUserSwitchObserver;
181import android.app.Instrumentation;
182import android.app.Notification;
183import android.app.NotificationManager;
184import android.app.PendingIntent;
185import android.app.ProfilerInfo;
186import android.app.RemoteAction;
187import android.app.WaitResult;
188import android.app.admin.DevicePolicyManager;
189import android.app.assist.AssistContent;
190import android.app.assist.AssistStructure;
191import android.app.backup.IBackupManager;
192import android.app.usage.UsageEvents;
193import android.app.usage.UsageStatsManagerInternal;
194import android.appwidget.AppWidgetManager;
195import android.content.ActivityNotFoundException;
196import android.content.BroadcastReceiver;
197import android.content.ClipData;
198import android.content.ComponentCallbacks2;
199import android.content.ComponentName;
200import android.content.ContentProvider;
201import android.content.ContentResolver;
202import android.content.Context;
203import android.content.DialogInterface;
204import android.content.IContentProvider;
205import android.content.IIntentReceiver;
206import android.content.IIntentSender;
207import android.content.Intent;
208import android.content.IntentFilter;
209import android.content.IntentSender;
210import android.content.pm.ActivityInfo;
211import android.content.pm.ApplicationInfo;
212import android.content.pm.ConfigurationInfo;
213import android.content.pm.IPackageDataObserver;
214import android.content.pm.IPackageManager;
215import android.content.pm.InstrumentationInfo;
216import android.content.pm.PackageInfo;
217import android.content.pm.PackageManager;
218import android.content.pm.PackageManager.NameNotFoundException;
219import android.content.pm.PackageManagerInternal;
220import android.content.pm.ParceledListSlice;
221import android.content.pm.PathPermission;
222import android.content.pm.PermissionInfo;
223import android.content.pm.ProviderInfo;
224import android.content.pm.ResolveInfo;
225import android.content.pm.ServiceInfo;
226import android.content.pm.UserInfo;
227import android.content.res.CompatibilityInfo;
228import android.content.res.Configuration;
229import android.content.res.Resources;
230import android.database.ContentObserver;
231import android.graphics.Bitmap;
232import android.graphics.GraphicBuffer;
233import android.graphics.Point;
234import android.graphics.Rect;
235import android.location.LocationManager;
236import android.net.Proxy;
237import android.net.ProxyInfo;
238import android.net.Uri;
239import android.os.BatteryStats;
240import android.os.Binder;
241import android.os.Build;
242import android.os.Bundle;
243import android.os.Debug;
244import android.os.DropBoxManager;
245import android.os.Environment;
246import android.os.FactoryTest;
247import android.os.FileObserver;
248import android.os.FileUtils;
249import android.os.Handler;
250import android.os.IBinder;
251import android.os.IDeviceIdentifiersPolicyService;
252import android.os.IPermissionController;
253import android.os.IProcessInfoService;
254import android.os.IProgressListener;
255import android.os.LocaleList;
256import android.os.Looper;
257import android.os.Message;
258import android.os.Parcel;
259import android.os.ParcelFileDescriptor;
260import android.os.PersistableBundle;
261import android.os.PowerManager;
262import android.os.PowerManagerInternal;
263import android.os.Process;
264import android.os.RemoteCallbackList;
265import android.os.RemoteException;
266import android.os.ResultReceiver;
267import android.os.ServiceManager;
268import android.os.ShellCallback;
269import android.os.StrictMode;
270import android.os.SystemClock;
271import android.os.SystemProperties;
272import android.os.Trace;
273import android.os.TransactionTooLargeException;
274import android.os.UpdateLock;
275import android.os.UserHandle;
276import android.os.UserManager;
277import android.os.WorkSource;
278import android.os.storage.IStorageManager;
279import android.os.storage.StorageManager;
280import android.os.storage.StorageManagerInternal;
281import android.provider.Downloads;
282import android.provider.Settings;
283import android.service.autofill.AutoFillService;
284import android.service.voice.IVoiceInteractionSession;
285import android.service.voice.VoiceInteractionManagerInternal;
286import android.service.voice.VoiceInteractionSession;
287import android.telecom.TelecomManager;
288import android.text.format.DateUtils;
289import android.text.format.Time;
290import android.text.style.SuggestionSpan;
291import android.util.ArrayMap;
292import android.util.ArraySet;
293import android.util.AtomicFile;
294import android.util.BootTimingsTraceLog;
295import android.util.DebugUtils;
296import android.util.DisplayMetrics;
297import android.util.EventLog;
298import android.util.Log;
299import android.util.Pair;
300import android.util.PrintWriterPrinter;
301import android.util.Slog;
302import android.util.SparseArray;
303import android.util.SparseIntArray;
304import android.util.TimeUtils;
305import android.util.Xml;
306import android.view.Gravity;
307import android.view.LayoutInflater;
308import android.view.View;
309import android.view.WindowManager;
310
311import com.google.android.collect.Lists;
312import com.google.android.collect.Maps;
313
314import com.android.internal.R;
315import com.android.internal.annotations.GuardedBy;
316import com.android.internal.app.AssistUtils;
317import com.android.internal.app.DumpHeapActivity;
318import com.android.internal.app.IAppOpsCallback;
319import com.android.internal.app.IAppOpsService;
320import com.android.internal.app.IVoiceInteractor;
321import com.android.internal.app.ProcessMap;
322import com.android.internal.app.SystemUserHomeActivity;
323import com.android.internal.app.procstats.ProcessStats;
324import com.android.internal.os.BackgroundThread;
325import com.android.internal.os.BatteryStatsImpl;
326import com.android.internal.os.IResultReceiver;
327import com.android.internal.os.ProcessCpuTracker;
328import com.android.internal.os.TransferPipe;
329import com.android.internal.os.Zygote;
330import com.android.internal.policy.IKeyguardDismissCallback;
331import com.android.internal.telephony.TelephonyIntents;
332import com.android.internal.util.ArrayUtils;
333import com.android.internal.util.FastPrintWriter;
334import com.android.internal.util.FastXmlSerializer;
335import com.android.internal.util.MemInfoReader;
336import com.android.internal.util.Preconditions;
337import com.android.server.AppOpsService;
338import com.android.server.AttributeCache;
339import com.android.server.DeviceIdleController;
340import com.android.server.IntentResolver;
341import com.android.server.LocalServices;
342import com.android.server.LockGuard;
343import com.android.server.ServiceThread;
344import com.android.server.SystemService;
345import com.android.server.SystemServiceManager;
346import com.android.server.Watchdog;
347import com.android.server.am.ActivityStack.ActivityState;
348import com.android.server.firewall.IntentFirewall;
349import com.android.server.pm.Installer;
350import com.android.server.pm.Installer.InstallerException;
351import com.android.server.statusbar.StatusBarManagerInternal;
352import com.android.server.vr.VrManagerInternal;
353import com.android.server.wm.WindowManagerService;
354
355import org.xmlpull.v1.XmlPullParser;
356import org.xmlpull.v1.XmlPullParserException;
357import org.xmlpull.v1.XmlSerializer;
358
359import java.io.File;
360import java.io.FileDescriptor;
361import java.io.FileInputStream;
362import java.io.FileNotFoundException;
363import java.io.FileOutputStream;
364import java.io.IOException;
365import java.io.InputStreamReader;
366import java.io.PrintWriter;
367import java.io.StringWriter;
368import java.lang.ref.WeakReference;
369import java.nio.charset.StandardCharsets;
370import java.util.ArrayList;
371import java.util.Arrays;
372import java.util.Collections;
373import java.util.Comparator;
374import java.util.HashMap;
375import java.util.HashSet;
376import java.util.Iterator;
377import java.util.List;
378import java.util.Locale;
379import java.util.Map;
380import java.util.Objects;
381import java.util.Set;
382import java.util.concurrent.CountDownLatch;
383import java.util.concurrent.atomic.AtomicBoolean;
384import java.util.concurrent.atomic.AtomicLong;
385
386import dalvik.system.VMRuntime;
387import libcore.io.IoUtils;
388import libcore.util.EmptyArray;
389
390import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
391public class ActivityManagerService extends IActivityManager.Stub
392        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
393
394    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
395    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
396    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
397    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
398    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
399    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
400    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
401    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
402    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
403    private static final String TAG_LRU = TAG + POSTFIX_LRU;
404    private static final String TAG_MU = TAG + POSTFIX_MU;
405    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
406    private static final String TAG_POWER = TAG + POSTFIX_POWER;
407    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
408    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
409    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
410    private static final String TAG_PSS = TAG + POSTFIX_PSS;
411    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
412    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
413    private static final String TAG_STACK = TAG + POSTFIX_STACK;
414    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
415    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
416    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
417    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
418    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
419
420    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
421    // here so that while the job scheduler can depend on AMS, the other way around
422    // need not be the case.
423    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
424
425    /** Control over CPU and battery monitoring */
426    // write battery stats every 30 minutes.
427    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
428    static final boolean MONITOR_CPU_USAGE = true;
429    // don't sample cpu less than every 5 seconds.
430    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
431    // wait possibly forever for next cpu sample.
432    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
433    static final boolean MONITOR_THREAD_CPU_USAGE = false;
434
435    // The flags that are set for all calls we make to the package manager.
436    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
437
438    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
439
440    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
441
442    // Amount of time after a call to stopAppSwitches() during which we will
443    // prevent further untrusted switches from happening.
444    static final long APP_SWITCH_DELAY_TIME = 5*1000;
445
446    // How long we wait for a launched process to attach to the activity manager
447    // before we decide it's never going to come up for real.
448    static final int PROC_START_TIMEOUT = 10*1000;
449    // How long we wait for an attached process to publish its content providers
450    // before we decide it must be hung.
451    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
452
453    // How long we will retain processes hosting content providers in the "last activity"
454    // state before allowing them to drop down to the regular cached LRU list.  This is
455    // to avoid thrashing of provider processes under low memory situations.
456    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
457
458    // How long we wait for a launched process to attach to the activity manager
459    // before we decide it's never going to come up for real, when the process was
460    // started with a wrapper for instrumentation (such as Valgrind) because it
461    // could take much longer than usual.
462    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
463
464    // How long to wait after going idle before forcing apps to GC.
465    static final int GC_TIMEOUT = 5*1000;
466
467    // The minimum amount of time between successive GC requests for a process.
468    static final int GC_MIN_INTERVAL = 60*1000;
469
470    // The minimum amount of time between successive PSS requests for a process.
471    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
472
473    // The minimum amount of time between successive PSS requests for a process
474    // when the request is due to the memory state being lowered.
475    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
476
477    // The rate at which we check for apps using excessive power -- 15 mins.
478    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
479
480    // The minimum sample duration we will allow before deciding we have
481    // enough data on wake locks to start killing things.
482    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
483
484    // The minimum sample duration we will allow before deciding we have
485    // enough data on CPU usage to start killing things.
486    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
487
488    // How long we allow a receiver to run before giving up on it.
489    static final int BROADCAST_FG_TIMEOUT = 10*1000;
490    static final int BROADCAST_BG_TIMEOUT = 60*1000;
491
492    // How long we wait until we timeout on key dispatching.
493    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
494
495    // How long we wait until we timeout on key dispatching during instrumentation.
496    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
497
498    // This is the amount of time an app needs to be running a foreground service before
499    // we will consider it to be doing interaction for usage stats.
500    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
501
502    // Maximum amount of time we will allow to elapse before re-reporting usage stats
503    // interaction with foreground processes.
504    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
505
506    // This is the amount of time we allow an app to settle after it goes into the background,
507    // before we start restricting what it can do.
508    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
509
510    // How long to wait in getAssistContextExtras for the activity and foreground services
511    // to respond with the result.
512    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
513
514    // How long top wait when going through the modern assist (which doesn't need to block
515    // on getting this result before starting to launch its UI).
516    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
517
518    // How long to wait in getAutoFillAssistStructure() for the activity to respond with the result.
519    static final int PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
520
521    // Maximum number of persisted Uri grants a package is allowed
522    static final int MAX_PERSISTED_URI_GRANTS = 128;
523
524    static final int MY_PID = Process.myPid();
525
526    static final String[] EMPTY_STRING_ARRAY = new String[0];
527
528    // How many bytes to write into the dropbox log before truncating
529    static final int DROPBOX_MAX_SIZE = 192 * 1024;
530    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
531    // as one line, but close enough for now.
532    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
533
534    // Access modes for handleIncomingUser.
535    static final int ALLOW_NON_FULL = 0;
536    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
537    static final int ALLOW_FULL_ONLY = 2;
538
539    // Necessary ApplicationInfo flags to mark an app as persistent
540    private static final int PERSISTENT_MASK =
541            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
542
543    // Intent sent when remote bugreport collection has been completed
544    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
545            "android.intent.action.REMOTE_BUGREPORT_FINISHED";
546
547    // Used to indicate that an app transition should be animated.
548    static final boolean ANIMATE = true;
549
550    // Determines whether to take full screen screenshots
551    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
552    public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
553
554    /** All system services */
555    SystemServiceManager mSystemServiceManager;
556
557    private Installer mInstaller;
558
559    /** Run all ActivityStacks through this */
560    final ActivityStackSupervisor mStackSupervisor;
561    private final KeyguardController mKeyguardController;
562
563    final ActivityStarter mActivityStarter;
564
565    final TaskChangeNotificationController mTaskChangeNotificationController;
566
567    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
568
569    public IntentFirewall mIntentFirewall;
570
571    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
572    // default action automatically.  Important for devices without direct input
573    // devices.
574    private boolean mShowDialogs = true;
575    private boolean mInVrMode = false;
576
577    // Whether we should use SCHED_FIFO for UI and RenderThreads.
578    private boolean mUseFifoUiScheduling = false;
579
580    BroadcastQueue mFgBroadcastQueue;
581    BroadcastQueue mBgBroadcastQueue;
582    // Convenient for easy iteration over the queues. Foreground is first
583    // so that dispatch of foreground broadcasts gets precedence.
584    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
585
586    BroadcastStats mLastBroadcastStats;
587    BroadcastStats mCurBroadcastStats;
588
589    BroadcastQueue broadcastQueueForIntent(Intent intent) {
590        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
591        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
592                "Broadcast intent " + intent + " on "
593                + (isFg ? "foreground" : "background") + " queue");
594        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
595    }
596
597    /**
598     * The last resumed activity. This is identical to the current resumed activity most
599     * of the time but could be different when we're pausing one activity before we resume
600     * another activity.
601     */
602    private ActivityRecord mLastResumedActivity;
603
604    /**
605     * If non-null, we are tracking the time the user spends in the currently focused app.
606     */
607    private AppTimeTracker mCurAppTimeTracker;
608
609    /**
610     * List of intents that were used to start the most recent tasks.
611     */
612    final RecentTasks mRecentTasks;
613
614    /**
615     * For addAppTask: cached of the last activity component that was added.
616     */
617    ComponentName mLastAddedTaskComponent;
618
619    /**
620     * For addAppTask: cached of the last activity uid that was added.
621     */
622    int mLastAddedTaskUid;
623
624    /**
625     * For addAppTask: cached of the last ActivityInfo that was added.
626     */
627    ActivityInfo mLastAddedTaskActivity;
628
629    /**
630     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
631     */
632    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
633
634    /**
635     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
636     */
637    String mDeviceOwnerName;
638
639    final UserController mUserController;
640
641    final AppErrors mAppErrors;
642
643    public boolean canShowErrorDialogs() {
644        return mShowDialogs && !mSleeping && !mShuttingDown
645                && !mKeyguardController.isKeyguardShowing();
646    }
647
648    private static final class PriorityState {
649        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
650        // the current thread is currently in. When it drops down to zero, we will no longer boost
651        // the thread's priority.
652        private int regionCounter = 0;
653
654        // The thread's previous priority before boosting.
655        private int prevPriority = Integer.MIN_VALUE;
656    }
657
658    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
659        @Override protected PriorityState initialValue() {
660            return new PriorityState();
661        }
662    };
663
664    static void boostPriorityForLockedSection() {
665        int tid = Process.myTid();
666        int prevPriority = Process.getThreadPriority(tid);
667        PriorityState state = sThreadPriorityState.get();
668        if (state.regionCounter == 0 && prevPriority > -2) {
669            state.prevPriority = prevPriority;
670            Process.setThreadPriority(tid, -2);
671        }
672        state.regionCounter++;
673    }
674
675    static void resetPriorityAfterLockedSection() {
676        PriorityState state = sThreadPriorityState.get();
677        state.regionCounter--;
678        if (state.regionCounter == 0 && state.prevPriority > -2) {
679            Process.setThreadPriority(Process.myTid(), state.prevPriority);
680        }
681    }
682
683    public class PendingAssistExtras extends Binder implements Runnable {
684        public final ActivityRecord activity;
685        public final Bundle extras;
686        public final Intent intent;
687        public final String hint;
688        public final IResultReceiver receiver;
689        public final int userHandle;
690        public boolean haveResult = false;
691        public Bundle result = null;
692        public AssistStructure structure = null;
693        public AssistContent content = null;
694        public Bundle receiverExtras;
695        public int resultCode;
696        public int flags;
697
698        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
699                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _resultCode,
700                int _userHandle, int _flags) {
701            activity = _activity;
702            extras = _extras;
703            intent = _intent;
704            hint = _hint;
705            receiver = _receiver;
706            receiverExtras = _receiverExtras;
707            resultCode = _resultCode;
708            userHandle = _userHandle;
709            flags = _flags;
710        }
711        @Override
712        public void run() {
713            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
714            synchronized (this) {
715                haveResult = true;
716                notifyAll();
717            }
718            pendingAssistExtrasTimedOut(this);
719        }
720    }
721
722    final ArrayList<PendingAssistExtras> mPendingAssistExtras
723            = new ArrayList<PendingAssistExtras>();
724
725    /**
726     * Process management.
727     */
728    final ProcessList mProcessList = new ProcessList();
729
730    /**
731     * All of the applications we currently have running organized by name.
732     * The keys are strings of the application package name (as
733     * returned by the package manager), and the keys are ApplicationRecord
734     * objects.
735     */
736    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
737
738    /**
739     * Tracking long-term execution of processes to look for abuse and other
740     * bad app behavior.
741     */
742    final ProcessStatsService mProcessStats;
743
744    /**
745     * The currently running isolated processes.
746     */
747    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
748
749    /**
750     * Counter for assigning isolated process uids, to avoid frequently reusing the
751     * same ones.
752     */
753    int mNextIsolatedProcessUid = 0;
754
755    /**
756     * The currently running heavy-weight process, if any.
757     */
758    ProcessRecord mHeavyWeightProcess = null;
759
760    /**
761     * All of the processes we currently have running organized by pid.
762     * The keys are the pid running the application.
763     *
764     * <p>NOTE: This object is protected by its own lock, NOT the global
765     * activity manager lock!
766     */
767    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
768
769    /**
770     * All of the processes that have been forced to be foreground.  The key
771     * is the pid of the caller who requested it (we hold a death
772     * link on it).
773     */
774    abstract class ForegroundToken implements IBinder.DeathRecipient {
775        int pid;
776        IBinder token;
777    }
778    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
779
780    /**
781     * List of records for processes that someone had tried to start before the
782     * system was ready.  We don't start them at that point, but ensure they
783     * are started by the time booting is complete.
784     */
785    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
786
787    /**
788     * List of persistent applications that are in the process
789     * of being started.
790     */
791    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
792
793    /**
794     * Processes that are being forcibly torn down.
795     */
796    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
797
798    /**
799     * List of running applications, sorted by recent usage.
800     * The first entry in the list is the least recently used.
801     */
802    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
803
804    /**
805     * Where in mLruProcesses that the processes hosting activities start.
806     */
807    int mLruProcessActivityStart = 0;
808
809    /**
810     * Where in mLruProcesses that the processes hosting services start.
811     * This is after (lower index) than mLruProcessesActivityStart.
812     */
813    int mLruProcessServiceStart = 0;
814
815    /**
816     * List of processes that should gc as soon as things are idle.
817     */
818    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
819
820    /**
821     * Processes we want to collect PSS data from.
822     */
823    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
824
825    private boolean mBinderTransactionTrackingEnabled = false;
826
827    /**
828     * Last time we requested PSS data of all processes.
829     */
830    long mLastFullPssTime = SystemClock.uptimeMillis();
831
832    /**
833     * If set, the next time we collect PSS data we should do a full collection
834     * with data from native processes and the kernel.
835     */
836    boolean mFullPssPending = false;
837
838    /**
839     * This is the process holding what we currently consider to be
840     * the "home" activity.
841     */
842    ProcessRecord mHomeProcess;
843
844    /**
845     * This is the process holding the activity the user last visited that
846     * is in a different process from the one they are currently in.
847     */
848    ProcessRecord mPreviousProcess;
849
850    /**
851     * The time at which the previous process was last visible.
852     */
853    long mPreviousProcessVisibleTime;
854
855    /**
856     * Track all uids that have actively running processes.
857     */
858    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
859
860    /**
861     * This is for verifying the UID report flow.
862     */
863    static final boolean VALIDATE_UID_STATES = true;
864    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
865
866    /**
867     * Packages that the user has asked to have run in screen size
868     * compatibility mode instead of filling the screen.
869     */
870    final CompatModePackages mCompatModePackages;
871
872    /**
873     * Set of IntentSenderRecord objects that are currently active.
874     */
875    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
876            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
877
878    /**
879     * Fingerprints (hashCode()) of stack traces that we've
880     * already logged DropBox entries for.  Guarded by itself.  If
881     * something (rogue user app) forces this over
882     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
883     */
884    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
885    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
886
887    /**
888     * Strict Mode background batched logging state.
889     *
890     * The string buffer is guarded by itself, and its lock is also
891     * used to determine if another batched write is already
892     * in-flight.
893     */
894    private final StringBuilder mStrictModeBuffer = new StringBuilder();
895
896    /**
897     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
898     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
899     */
900    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
901
902    /**
903     * Resolver for broadcast intents to registered receivers.
904     * Holds BroadcastFilter (subclass of IntentFilter).
905     */
906    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
907            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
908        @Override
909        protected boolean allowFilterResult(
910                BroadcastFilter filter, List<BroadcastFilter> dest) {
911            IBinder target = filter.receiverList.receiver.asBinder();
912            for (int i = dest.size() - 1; i >= 0; i--) {
913                if (dest.get(i).receiverList.receiver.asBinder() == target) {
914                    return false;
915                }
916            }
917            return true;
918        }
919
920        @Override
921        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
922            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
923                    || userId == filter.owningUserId) {
924                return super.newResult(filter, match, userId);
925            }
926            return null;
927        }
928
929        @Override
930        protected BroadcastFilter[] newArray(int size) {
931            return new BroadcastFilter[size];
932        }
933
934        @Override
935        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
936            return packageName.equals(filter.packageName);
937        }
938    };
939
940    /**
941     * State of all active sticky broadcasts per user.  Keys are the action of the
942     * sticky Intent, values are an ArrayList of all broadcasted intents with
943     * that action (which should usually be one).  The SparseArray is keyed
944     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
945     * for stickies that are sent to all users.
946     */
947    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
948            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
949
950    final ActiveServices mServices;
951
952    final static class Association {
953        final int mSourceUid;
954        final String mSourceProcess;
955        final int mTargetUid;
956        final ComponentName mTargetComponent;
957        final String mTargetProcess;
958
959        int mCount;
960        long mTime;
961
962        int mNesting;
963        long mStartTime;
964
965        // states of the source process when the bind occurred.
966        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
967        long mLastStateUptime;
968        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
969                - ActivityManager.MIN_PROCESS_STATE+1];
970
971        Association(int sourceUid, String sourceProcess, int targetUid,
972                ComponentName targetComponent, String targetProcess) {
973            mSourceUid = sourceUid;
974            mSourceProcess = sourceProcess;
975            mTargetUid = targetUid;
976            mTargetComponent = targetComponent;
977            mTargetProcess = targetProcess;
978        }
979    }
980
981    /**
982     * When service association tracking is enabled, this is all of the associations we
983     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
984     * -> association data.
985     */
986    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
987            mAssociations = new SparseArray<>();
988    boolean mTrackingAssociations;
989
990    /**
991     * Backup/restore process management
992     */
993    String mBackupAppName = null;
994    BackupRecord mBackupTarget = null;
995
996    final ProviderMap mProviderMap;
997
998    /**
999     * List of content providers who have clients waiting for them.  The
1000     * application is currently being launched and the provider will be
1001     * removed from this list once it is published.
1002     */
1003    final ArrayList<ContentProviderRecord> mLaunchingProviders
1004            = new ArrayList<ContentProviderRecord>();
1005
1006    /**
1007     * File storing persisted {@link #mGrantedUriPermissions}.
1008     */
1009    private final AtomicFile mGrantFile;
1010
1011    /** XML constants used in {@link #mGrantFile} */
1012    private static final String TAG_URI_GRANTS = "uri-grants";
1013    private static final String TAG_URI_GRANT = "uri-grant";
1014    private static final String ATTR_USER_HANDLE = "userHandle";
1015    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1016    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1017    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1018    private static final String ATTR_TARGET_PKG = "targetPkg";
1019    private static final String ATTR_URI = "uri";
1020    private static final String ATTR_MODE_FLAGS = "modeFlags";
1021    private static final String ATTR_CREATED_TIME = "createdTime";
1022    private static final String ATTR_PREFIX = "prefix";
1023
1024    /**
1025     * Global set of specific {@link Uri} permissions that have been granted.
1026     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1027     * to {@link UriPermission#uri} to {@link UriPermission}.
1028     */
1029    @GuardedBy("this")
1030    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1031            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1032
1033    public static class GrantUri {
1034        public final int sourceUserId;
1035        public final Uri uri;
1036        public boolean prefix;
1037
1038        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1039            this.sourceUserId = sourceUserId;
1040            this.uri = uri;
1041            this.prefix = prefix;
1042        }
1043
1044        @Override
1045        public int hashCode() {
1046            int hashCode = 1;
1047            hashCode = 31 * hashCode + sourceUserId;
1048            hashCode = 31 * hashCode + uri.hashCode();
1049            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1050            return hashCode;
1051        }
1052
1053        @Override
1054        public boolean equals(Object o) {
1055            if (o instanceof GrantUri) {
1056                GrantUri other = (GrantUri) o;
1057                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1058                        && prefix == other.prefix;
1059            }
1060            return false;
1061        }
1062
1063        @Override
1064        public String toString() {
1065            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1066            if (prefix) result += " [prefix]";
1067            return result;
1068        }
1069
1070        public String toSafeString() {
1071            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1072            if (prefix) result += " [prefix]";
1073            return result;
1074        }
1075
1076        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1077            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1078                    ContentProvider.getUriWithoutUserId(uri), false);
1079        }
1080    }
1081
1082    CoreSettingsObserver mCoreSettingsObserver;
1083
1084    FontScaleSettingObserver mFontScaleSettingObserver;
1085
1086    private final class FontScaleSettingObserver extends ContentObserver {
1087        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1088
1089        public FontScaleSettingObserver() {
1090            super(mHandler);
1091            ContentResolver resolver = mContext.getContentResolver();
1092            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1093        }
1094
1095        @Override
1096        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1097            if (mFontScaleUri.equals(uri)) {
1098                updateFontScaleIfNeeded(userId);
1099            }
1100        }
1101    }
1102
1103    /**
1104     * Thread-local storage used to carry caller permissions over through
1105     * indirect content-provider access.
1106     */
1107    private class Identity {
1108        public final IBinder token;
1109        public final int pid;
1110        public final int uid;
1111
1112        Identity(IBinder _token, int _pid, int _uid) {
1113            token = _token;
1114            pid = _pid;
1115            uid = _uid;
1116        }
1117    }
1118
1119    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1120
1121    /**
1122     * All information we have collected about the runtime performance of
1123     * any user id that can impact battery performance.
1124     */
1125    final BatteryStatsService mBatteryStatsService;
1126
1127    /**
1128     * Information about component usage
1129     */
1130    UsageStatsManagerInternal mUsageStatsService;
1131
1132    /**
1133     * Access to DeviceIdleController service.
1134     */
1135    DeviceIdleController.LocalService mLocalDeviceIdleController;
1136
1137    /**
1138     * Information about and control over application operations
1139     */
1140    final AppOpsService mAppOpsService;
1141
1142    /** Current sequencing integer of the configuration, for skipping old configurations. */
1143    private int mConfigurationSeq;
1144
1145    /**
1146     * Temp object used when global and/or display override configuration is updated. It is also
1147     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1148     * anyone...
1149     */
1150    private Configuration mTempConfig = new Configuration();
1151
1152    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1153            new UpdateConfigurationResult();
1154    private static final class UpdateConfigurationResult {
1155        // Configuration changes that were updated.
1156        int changes;
1157        // If the activity was relaunched to match the new configuration.
1158        boolean activityRelaunched;
1159
1160        void reset() {
1161            changes = 0;
1162            activityRelaunched = false;
1163        }
1164    }
1165
1166    boolean mSuppressResizeConfigChanges;
1167
1168    /**
1169     * Hardware-reported OpenGLES version.
1170     */
1171    final int GL_ES_VERSION;
1172
1173    /**
1174     * List of initialization arguments to pass to all processes when binding applications to them.
1175     * For example, references to the commonly used services.
1176     */
1177    HashMap<String, IBinder> mAppBindArgs;
1178    HashMap<String, IBinder> mIsolatedAppBindArgs;
1179
1180    /**
1181     * Temporary to avoid allocations.  Protected by main lock.
1182     */
1183    final StringBuilder mStringBuilder = new StringBuilder(256);
1184
1185    /**
1186     * Used to control how we initialize the service.
1187     */
1188    ComponentName mTopComponent;
1189    String mTopAction = Intent.ACTION_MAIN;
1190    String mTopData;
1191
1192    volatile boolean mProcessesReady = false;
1193    volatile boolean mSystemReady = false;
1194    volatile boolean mOnBattery = false;
1195    volatile int mFactoryTest;
1196
1197    @GuardedBy("this") boolean mBooting = false;
1198    @GuardedBy("this") boolean mCallFinishBooting = false;
1199    @GuardedBy("this") boolean mBootAnimationComplete = false;
1200    @GuardedBy("this") boolean mLaunchWarningShown = false;
1201    @GuardedBy("this") boolean mCheckedForSetup = false;
1202
1203    Context mContext;
1204
1205    /**
1206     * The time at which we will allow normal application switches again,
1207     * after a call to {@link #stopAppSwitches()}.
1208     */
1209    long mAppSwitchesAllowedTime;
1210
1211    /**
1212     * This is set to true after the first switch after mAppSwitchesAllowedTime
1213     * is set; any switches after that will clear the time.
1214     */
1215    boolean mDidAppSwitch;
1216
1217    /**
1218     * Last time (in realtime) at which we checked for power usage.
1219     */
1220    long mLastPowerCheckRealtime;
1221
1222    /**
1223     * Last time (in uptime) at which we checked for power usage.
1224     */
1225    long mLastPowerCheckUptime;
1226
1227    /**
1228     * Set while we are wanting to sleep, to prevent any
1229     * activities from being started/resumed.
1230     *
1231     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1232     *
1233     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1234     * while in the sleep state until there is a pending transition out of sleep, in which case
1235     * mSleeping is set to false, and remains false while awake.
1236     *
1237     * Whether mSleeping can quickly toggled between true/false without the device actually
1238     * display changing states is undefined.
1239     */
1240    private boolean mSleeping = false;
1241
1242    /**
1243     * The process state used for processes that are running the top activities.
1244     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1245     */
1246    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1247
1248    /**
1249     * Set while we are running a voice interaction.  This overrides
1250     * sleeping while it is active.
1251     */
1252    private IVoiceInteractionSession mRunningVoice;
1253
1254    /**
1255     * For some direct access we need to power manager.
1256     */
1257    PowerManagerInternal mLocalPowerManager;
1258
1259    /**
1260     * We want to hold a wake lock while running a voice interaction session, since
1261     * this may happen with the screen off and we need to keep the CPU running to
1262     * be able to continue to interact with the user.
1263     */
1264    PowerManager.WakeLock mVoiceWakeLock;
1265
1266    /**
1267     * State of external calls telling us if the device is awake or asleep.
1268     */
1269    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1270
1271    /**
1272     * A list of tokens that cause the top activity to be put to sleep.
1273     * They are used by components that may hide and block interaction with underlying
1274     * activities.
1275     */
1276    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1277
1278    /**
1279     * Set if we are shutting down the system, similar to sleeping.
1280     */
1281    boolean mShuttingDown = false;
1282
1283    /**
1284     * Current sequence id for oom_adj computation traversal.
1285     */
1286    int mAdjSeq = 0;
1287
1288    /**
1289     * Current sequence id for process LRU updating.
1290     */
1291    int mLruSeq = 0;
1292
1293    /**
1294     * Keep track of the non-cached/empty process we last found, to help
1295     * determine how to distribute cached/empty processes next time.
1296     */
1297    int mNumNonCachedProcs = 0;
1298
1299    /**
1300     * Keep track of the number of cached hidden procs, to balance oom adj
1301     * distribution between those and empty procs.
1302     */
1303    int mNumCachedHiddenProcs = 0;
1304
1305    /**
1306     * Keep track of the number of service processes we last found, to
1307     * determine on the next iteration which should be B services.
1308     */
1309    int mNumServiceProcs = 0;
1310    int mNewNumAServiceProcs = 0;
1311    int mNewNumServiceProcs = 0;
1312
1313    /**
1314     * Allow the current computed overall memory level of the system to go down?
1315     * This is set to false when we are killing processes for reasons other than
1316     * memory management, so that the now smaller process list will not be taken as
1317     * an indication that memory is tighter.
1318     */
1319    boolean mAllowLowerMemLevel = false;
1320
1321    /**
1322     * The last computed memory level, for holding when we are in a state that
1323     * processes are going away for other reasons.
1324     */
1325    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1326
1327    /**
1328     * The last total number of process we have, to determine if changes actually look
1329     * like a shrinking number of process due to lower RAM.
1330     */
1331    int mLastNumProcesses;
1332
1333    /**
1334     * The uptime of the last time we performed idle maintenance.
1335     */
1336    long mLastIdleTime = SystemClock.uptimeMillis();
1337
1338    /**
1339     * Total time spent with RAM that has been added in the past since the last idle time.
1340     */
1341    long mLowRamTimeSinceLastIdle = 0;
1342
1343    /**
1344     * If RAM is currently low, when that horrible situation started.
1345     */
1346    long mLowRamStartTime = 0;
1347
1348    /**
1349     * For reporting to battery stats the current top application.
1350     */
1351    private String mCurResumedPackage = null;
1352    private int mCurResumedUid = -1;
1353
1354    /**
1355     * For reporting to battery stats the apps currently running foreground
1356     * service.  The ProcessMap is package/uid tuples; each of these contain
1357     * an array of the currently foreground processes.
1358     */
1359    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1360            = new ProcessMap<ArrayList<ProcessRecord>>();
1361
1362    /**
1363     * This is set if we had to do a delayed dexopt of an app before launching
1364     * it, to increase the ANR timeouts in that case.
1365     */
1366    boolean mDidDexOpt;
1367
1368    /**
1369     * Set if the systemServer made a call to enterSafeMode.
1370     */
1371    boolean mSafeMode;
1372
1373    /**
1374     * If true, we are running under a test environment so will sample PSS from processes
1375     * much more rapidly to try to collect better data when the tests are rapidly
1376     * running through apps.
1377     */
1378    boolean mTestPssMode = false;
1379
1380    String mDebugApp = null;
1381    boolean mWaitForDebugger = false;
1382    boolean mDebugTransient = false;
1383    String mOrigDebugApp = null;
1384    boolean mOrigWaitForDebugger = false;
1385    boolean mAlwaysFinishActivities = false;
1386    boolean mForceResizableActivities;
1387    boolean mSupportsMultiWindow;
1388    boolean mSupportsSplitScreenMultiWindow;
1389    boolean mSupportsFreeformWindowManagement;
1390    boolean mSupportsPictureInPicture;
1391    boolean mSupportsLeanbackOnly;
1392    IActivityController mController = null;
1393    boolean mControllerIsAMonkey = false;
1394    String mProfileApp = null;
1395    ProcessRecord mProfileProc = null;
1396    String mProfileFile;
1397    ParcelFileDescriptor mProfileFd;
1398    int mSamplingInterval = 0;
1399    boolean mAutoStopProfiler = false;
1400    int mProfileType = 0;
1401    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1402    String mMemWatchDumpProcName;
1403    String mMemWatchDumpFile;
1404    int mMemWatchDumpPid;
1405    int mMemWatchDumpUid;
1406    String mTrackAllocationApp = null;
1407    String mNativeDebuggingApp = null;
1408
1409    final long[] mTmpLong = new long[2];
1410
1411    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1412
1413    static final class ProcessChangeItem {
1414        static final int CHANGE_ACTIVITIES = 1<<0;
1415        static final int CHANGE_PROCESS_STATE = 1<<1;
1416        int changes;
1417        int uid;
1418        int pid;
1419        int processState;
1420        boolean foregroundActivities;
1421    }
1422
1423    static final class UidObserverRegistration {
1424        final int uid;
1425        final String pkg;
1426        final int which;
1427        final int cutpoint;
1428
1429        final SparseIntArray lastProcStates;
1430
1431        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1432            uid = _uid;
1433            pkg = _pkg;
1434            which = _which;
1435            cutpoint = _cutpoint;
1436            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1437                lastProcStates = new SparseIntArray();
1438            } else {
1439                lastProcStates = null;
1440            }
1441        }
1442    }
1443
1444    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1445    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1446
1447    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1448    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1449
1450    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1451    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1452
1453    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1454    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1455
1456    /**
1457     * Runtime CPU use collection thread.  This object's lock is used to
1458     * perform synchronization with the thread (notifying it to run).
1459     */
1460    final Thread mProcessCpuThread;
1461
1462    /**
1463     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1464     * Must acquire this object's lock when accessing it.
1465     * NOTE: this lock will be held while doing long operations (trawling
1466     * through all processes in /proc), so it should never be acquired by
1467     * any critical paths such as when holding the main activity manager lock.
1468     */
1469    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1470            MONITOR_THREAD_CPU_USAGE);
1471    final AtomicLong mLastCpuTime = new AtomicLong(0);
1472    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1473    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1474
1475    long mLastWriteTime = 0;
1476
1477    /**
1478     * Used to retain an update lock when the foreground activity is in
1479     * immersive mode.
1480     */
1481    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1482
1483    /**
1484     * Set to true after the system has finished booting.
1485     */
1486    boolean mBooted = false;
1487
1488    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1489    int mProcessLimitOverride = -1;
1490
1491    WindowManagerService mWindowManager;
1492    final ActivityThread mSystemThread;
1493
1494    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1495        final ProcessRecord mApp;
1496        final int mPid;
1497        final IApplicationThread mAppThread;
1498
1499        AppDeathRecipient(ProcessRecord app, int pid,
1500                IApplicationThread thread) {
1501            if (DEBUG_ALL) Slog.v(
1502                TAG, "New death recipient " + this
1503                + " for thread " + thread.asBinder());
1504            mApp = app;
1505            mPid = pid;
1506            mAppThread = thread;
1507        }
1508
1509        @Override
1510        public void binderDied() {
1511            if (DEBUG_ALL) Slog.v(
1512                TAG, "Death received in " + this
1513                + " for thread " + mAppThread.asBinder());
1514            synchronized(ActivityManagerService.this) {
1515                appDiedLocked(mApp, mPid, mAppThread, true);
1516            }
1517        }
1518    }
1519
1520    static final int SHOW_ERROR_UI_MSG = 1;
1521    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1522    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1523    static final int UPDATE_CONFIGURATION_MSG = 4;
1524    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1525    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1526    static final int SERVICE_TIMEOUT_MSG = 12;
1527    static final int UPDATE_TIME_ZONE = 13;
1528    static final int SHOW_UID_ERROR_UI_MSG = 14;
1529    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1530    static final int PROC_START_TIMEOUT_MSG = 20;
1531    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1532    static final int KILL_APPLICATION_MSG = 22;
1533    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1534    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1535    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1536    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1537    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1538    static final int CLEAR_DNS_CACHE_MSG = 28;
1539    static final int UPDATE_HTTP_PROXY_MSG = 29;
1540    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1541    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1542    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1543    static final int REPORT_MEM_USAGE_MSG = 33;
1544    static final int REPORT_USER_SWITCH_MSG = 34;
1545    static final int CONTINUE_USER_SWITCH_MSG = 35;
1546    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1547    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1548    static final int PERSIST_URI_GRANTS_MSG = 38;
1549    static final int REQUEST_ALL_PSS_MSG = 39;
1550    static final int START_PROFILES_MSG = 40;
1551    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1552    static final int SYSTEM_USER_START_MSG = 42;
1553    static final int SYSTEM_USER_CURRENT_MSG = 43;
1554    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1555    static final int FINISH_BOOTING_MSG = 45;
1556    static final int START_USER_SWITCH_UI_MSG = 46;
1557    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1558    static final int DISMISS_DIALOG_UI_MSG = 48;
1559    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1560    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1561    static final int DELETE_DUMPHEAP_MSG = 51;
1562    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1563    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1564    static final int REPORT_TIME_TRACKER_MSG = 54;
1565    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1566    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1567    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1568    static final int IDLE_UIDS_MSG = 58;
1569    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1570    static final int LOG_STACK_STATE = 60;
1571    static final int VR_MODE_CHANGE_MSG = 61;
1572    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1573    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1574    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1575    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1576    static final int START_USER_SWITCH_FG_MSG = 712;
1577
1578    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1579    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1580    static final int FIRST_COMPAT_MODE_MSG = 300;
1581    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1582
1583    static ServiceThread sKillThread = null;
1584    static KillHandler sKillHandler = null;
1585
1586    CompatModeDialog mCompatModeDialog;
1587    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1588    long mLastMemUsageReportTime = 0;
1589
1590    /**
1591     * Flag whether the current user is a "monkey", i.e. whether
1592     * the UI is driven by a UI automation tool.
1593     */
1594    private boolean mUserIsMonkey;
1595
1596    /** Flag whether the device has a Recents UI */
1597    boolean mHasRecents;
1598
1599    /** The dimensions of the thumbnails in the Recents UI. */
1600    int mThumbnailWidth;
1601    int mThumbnailHeight;
1602    float mFullscreenThumbnailScale;
1603
1604    /** The aspect ratio bounds of the PIP. */
1605    float mMinPipAspectRatio;
1606    float mMaxPipAspectRatio;
1607
1608    final ServiceThread mHandlerThread;
1609    final MainHandler mHandler;
1610    final UiHandler mUiHandler;
1611
1612    PackageManagerInternal mPackageManagerInt;
1613
1614    // VoiceInteraction session ID that changes for each new request except when
1615    // being called for multiwindow assist in a single session.
1616    private int mViSessionId = 1000;
1617
1618    final boolean mPermissionReviewRequired;
1619
1620    /**
1621     * Current global configuration information. Contains general settings for the entire system,
1622     * also corresponds to the merged configuration of the default display.
1623     */
1624    Configuration getGlobalConfiguration() {
1625        return mStackSupervisor.getConfiguration();
1626    }
1627
1628    final class KillHandler extends Handler {
1629        static final int KILL_PROCESS_GROUP_MSG = 4000;
1630
1631        public KillHandler(Looper looper) {
1632            super(looper, null, true);
1633        }
1634
1635        @Override
1636        public void handleMessage(Message msg) {
1637            switch (msg.what) {
1638                case KILL_PROCESS_GROUP_MSG:
1639                {
1640                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1641                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1642                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1643                }
1644                break;
1645
1646                default:
1647                    super.handleMessage(msg);
1648            }
1649        }
1650    }
1651
1652    final class UiHandler extends Handler {
1653        public UiHandler() {
1654            super(com.android.server.UiThread.get().getLooper(), null, true);
1655        }
1656
1657        @Override
1658        public void handleMessage(Message msg) {
1659            switch (msg.what) {
1660            case SHOW_ERROR_UI_MSG: {
1661                mAppErrors.handleShowAppErrorUi(msg);
1662                ensureBootCompleted();
1663            } break;
1664            case SHOW_NOT_RESPONDING_UI_MSG: {
1665                mAppErrors.handleShowAnrUi(msg);
1666                ensureBootCompleted();
1667            } break;
1668            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1669                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1670                synchronized (ActivityManagerService.this) {
1671                    ProcessRecord proc = (ProcessRecord) data.get("app");
1672                    if (proc == null) {
1673                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1674                        break;
1675                    }
1676                    if (proc.crashDialog != null) {
1677                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1678                        return;
1679                    }
1680                    AppErrorResult res = (AppErrorResult) data.get("result");
1681                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1682                        Dialog d = new StrictModeViolationDialog(mContext,
1683                                ActivityManagerService.this, res, proc);
1684                        d.show();
1685                        proc.crashDialog = d;
1686                    } else {
1687                        // The device is asleep, so just pretend that the user
1688                        // saw a crash dialog and hit "force quit".
1689                        res.set(0);
1690                    }
1691                }
1692                ensureBootCompleted();
1693            } break;
1694            case SHOW_FACTORY_ERROR_UI_MSG: {
1695                Dialog d = new FactoryErrorDialog(
1696                    mContext, msg.getData().getCharSequence("msg"));
1697                d.show();
1698                ensureBootCompleted();
1699            } break;
1700            case WAIT_FOR_DEBUGGER_UI_MSG: {
1701                synchronized (ActivityManagerService.this) {
1702                    ProcessRecord app = (ProcessRecord)msg.obj;
1703                    if (msg.arg1 != 0) {
1704                        if (!app.waitedForDebugger) {
1705                            Dialog d = new AppWaitingForDebuggerDialog(
1706                                    ActivityManagerService.this,
1707                                    mContext, app);
1708                            app.waitDialog = d;
1709                            app.waitedForDebugger = true;
1710                            d.show();
1711                        }
1712                    } else {
1713                        if (app.waitDialog != null) {
1714                            app.waitDialog.dismiss();
1715                            app.waitDialog = null;
1716                        }
1717                    }
1718                }
1719            } break;
1720            case SHOW_UID_ERROR_UI_MSG: {
1721                if (mShowDialogs) {
1722                    AlertDialog d = new BaseErrorDialog(mContext);
1723                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1724                    d.setCancelable(false);
1725                    d.setTitle(mContext.getText(R.string.android_system_label));
1726                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1727                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1728                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1729                    d.show();
1730                }
1731            } break;
1732            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1733                if (mShowDialogs) {
1734                    AlertDialog d = new BaseErrorDialog(mContext);
1735                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1736                    d.setCancelable(false);
1737                    d.setTitle(mContext.getText(R.string.android_system_label));
1738                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1739                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1740                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1741                    d.show();
1742                }
1743            } break;
1744            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1745                synchronized (ActivityManagerService.this) {
1746                    ActivityRecord ar = (ActivityRecord) msg.obj;
1747                    if (mCompatModeDialog != null) {
1748                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1749                                ar.info.applicationInfo.packageName)) {
1750                            return;
1751                        }
1752                        mCompatModeDialog.dismiss();
1753                        mCompatModeDialog = null;
1754                    }
1755                    if (ar != null && false) {
1756                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1757                                ar.packageName)) {
1758                            int mode = mCompatModePackages.computeCompatModeLocked(
1759                                    ar.info.applicationInfo);
1760                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1761                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1762                                mCompatModeDialog = new CompatModeDialog(
1763                                        ActivityManagerService.this, mContext,
1764                                        ar.info.applicationInfo);
1765                                mCompatModeDialog.show();
1766                            }
1767                        }
1768                    }
1769                }
1770                break;
1771            }
1772            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1773                synchronized (ActivityManagerService.this) {
1774                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1775                    if (mUnsupportedDisplaySizeDialog != null) {
1776                        mUnsupportedDisplaySizeDialog.dismiss();
1777                        mUnsupportedDisplaySizeDialog = null;
1778                    }
1779                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1780                            ar.packageName)) {
1781                        // TODO(multi-display): Show dialog on appropriate display.
1782                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1783                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1784                        mUnsupportedDisplaySizeDialog.show();
1785                    }
1786                }
1787                break;
1788            }
1789            case START_USER_SWITCH_UI_MSG: {
1790                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1791                break;
1792            }
1793            case DISMISS_DIALOG_UI_MSG: {
1794                final Dialog d = (Dialog) msg.obj;
1795                d.dismiss();
1796                break;
1797            }
1798            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1799                dispatchProcessesChanged();
1800                break;
1801            }
1802            case DISPATCH_PROCESS_DIED_UI_MSG: {
1803                final int pid = msg.arg1;
1804                final int uid = msg.arg2;
1805                dispatchProcessDied(pid, uid);
1806                break;
1807            }
1808            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1809                dispatchUidsChanged();
1810            } break;
1811            }
1812        }
1813    }
1814
1815    final class MainHandler extends Handler {
1816        public MainHandler(Looper looper) {
1817            super(looper, null, true);
1818        }
1819
1820        @Override
1821        public void handleMessage(Message msg) {
1822            switch (msg.what) {
1823            case UPDATE_CONFIGURATION_MSG: {
1824                final ContentResolver resolver = mContext.getContentResolver();
1825                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1826                        msg.arg1);
1827            } break;
1828            case GC_BACKGROUND_PROCESSES_MSG: {
1829                synchronized (ActivityManagerService.this) {
1830                    performAppGcsIfAppropriateLocked();
1831                }
1832            } break;
1833            case SERVICE_TIMEOUT_MSG: {
1834                if (mDidDexOpt) {
1835                    mDidDexOpt = false;
1836                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1837                    nmsg.obj = msg.obj;
1838                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1839                    return;
1840                }
1841                mServices.serviceTimeout((ProcessRecord)msg.obj);
1842            } break;
1843            case UPDATE_TIME_ZONE: {
1844                synchronized (ActivityManagerService.this) {
1845                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1846                        ProcessRecord r = mLruProcesses.get(i);
1847                        if (r.thread != null) {
1848                            try {
1849                                r.thread.updateTimeZone();
1850                            } catch (RemoteException ex) {
1851                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1852                            }
1853                        }
1854                    }
1855                }
1856            } break;
1857            case CLEAR_DNS_CACHE_MSG: {
1858                synchronized (ActivityManagerService.this) {
1859                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1860                        ProcessRecord r = mLruProcesses.get(i);
1861                        if (r.thread != null) {
1862                            try {
1863                                r.thread.clearDnsCache();
1864                            } catch (RemoteException ex) {
1865                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1866                            }
1867                        }
1868                    }
1869                }
1870            } break;
1871            case UPDATE_HTTP_PROXY_MSG: {
1872                ProxyInfo proxy = (ProxyInfo)msg.obj;
1873                String host = "";
1874                String port = "";
1875                String exclList = "";
1876                Uri pacFileUrl = Uri.EMPTY;
1877                if (proxy != null) {
1878                    host = proxy.getHost();
1879                    port = Integer.toString(proxy.getPort());
1880                    exclList = proxy.getExclusionListAsString();
1881                    pacFileUrl = proxy.getPacFileUrl();
1882                }
1883                synchronized (ActivityManagerService.this) {
1884                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1885                        ProcessRecord r = mLruProcesses.get(i);
1886                        if (r.thread != null) {
1887                            try {
1888                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1889                            } catch (RemoteException ex) {
1890                                Slog.w(TAG, "Failed to update http proxy for: " +
1891                                        r.info.processName);
1892                            }
1893                        }
1894                    }
1895                }
1896            } break;
1897            case PROC_START_TIMEOUT_MSG: {
1898                if (mDidDexOpt) {
1899                    mDidDexOpt = false;
1900                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1901                    nmsg.obj = msg.obj;
1902                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1903                    return;
1904                }
1905                ProcessRecord app = (ProcessRecord)msg.obj;
1906                synchronized (ActivityManagerService.this) {
1907                    processStartTimedOutLocked(app);
1908                }
1909            } break;
1910            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1911                ProcessRecord app = (ProcessRecord)msg.obj;
1912                synchronized (ActivityManagerService.this) {
1913                    processContentProviderPublishTimedOutLocked(app);
1914                }
1915            } break;
1916            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1917                synchronized (ActivityManagerService.this) {
1918                    mActivityStarter.doPendingActivityLaunchesLocked(true);
1919                }
1920            } break;
1921            case KILL_APPLICATION_MSG: {
1922                synchronized (ActivityManagerService.this) {
1923                    final int appId = msg.arg1;
1924                    final int userId = msg.arg2;
1925                    Bundle bundle = (Bundle)msg.obj;
1926                    String pkg = bundle.getString("pkg");
1927                    String reason = bundle.getString("reason");
1928                    forceStopPackageLocked(pkg, appId, false, false, true, false,
1929                            false, userId, reason);
1930                }
1931            } break;
1932            case FINALIZE_PENDING_INTENT_MSG: {
1933                ((PendingIntentRecord)msg.obj).completeFinalize();
1934            } break;
1935            case POST_HEAVY_NOTIFICATION_MSG: {
1936                INotificationManager inm = NotificationManager.getService();
1937                if (inm == null) {
1938                    return;
1939                }
1940
1941                ActivityRecord root = (ActivityRecord)msg.obj;
1942                ProcessRecord process = root.app;
1943                if (process == null) {
1944                    return;
1945                }
1946
1947                try {
1948                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1949                    String text = mContext.getString(R.string.heavy_weight_notification,
1950                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1951                    Notification notification = new Notification.Builder(context)
1952                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1953                            .setWhen(0)
1954                            .setOngoing(true)
1955                            .setTicker(text)
1956                            .setColor(mContext.getColor(
1957                                    com.android.internal.R.color.system_notification_accent_color))
1958                            .setContentTitle(text)
1959                            .setContentText(
1960                                    mContext.getText(R.string.heavy_weight_notification_detail))
1961                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1962                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1963                                    new UserHandle(root.userId)))
1964                            .build();
1965                    try {
1966                        int[] outId = new int[1];
1967                        inm.enqueueNotificationWithTag("android", "android", null,
1968                                R.string.heavy_weight_notification,
1969                                notification, outId, root.userId);
1970                    } catch (RuntimeException e) {
1971                        Slog.w(ActivityManagerService.TAG,
1972                                "Error showing notification for heavy-weight app", e);
1973                    } catch (RemoteException e) {
1974                    }
1975                } catch (NameNotFoundException e) {
1976                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1977                }
1978            } break;
1979            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1980                INotificationManager inm = NotificationManager.getService();
1981                if (inm == null) {
1982                    return;
1983                }
1984                try {
1985                    inm.cancelNotificationWithTag("android", null,
1986                            R.string.heavy_weight_notification,  msg.arg1);
1987                } catch (RuntimeException e) {
1988                    Slog.w(ActivityManagerService.TAG,
1989                            "Error canceling notification for service", e);
1990                } catch (RemoteException e) {
1991                }
1992            } break;
1993            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1994                synchronized (ActivityManagerService.this) {
1995                    checkExcessivePowerUsageLocked(true);
1996                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1997                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1998                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1999                }
2000            } break;
2001            case REPORT_MEM_USAGE_MSG: {
2002                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2003                Thread thread = new Thread() {
2004                    @Override public void run() {
2005                        reportMemUsage(memInfos);
2006                    }
2007                };
2008                thread.start();
2009                break;
2010            }
2011            case START_USER_SWITCH_FG_MSG: {
2012                mUserController.startUserInForeground(msg.arg1);
2013                break;
2014            }
2015            case REPORT_USER_SWITCH_MSG: {
2016                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2017                break;
2018            }
2019            case CONTINUE_USER_SWITCH_MSG: {
2020                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2021                break;
2022            }
2023            case USER_SWITCH_TIMEOUT_MSG: {
2024                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2025                break;
2026            }
2027            case IMMERSIVE_MODE_LOCK_MSG: {
2028                final boolean nextState = (msg.arg1 != 0);
2029                if (mUpdateLock.isHeld() != nextState) {
2030                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2031                            "Applying new update lock state '" + nextState
2032                            + "' for " + (ActivityRecord)msg.obj);
2033                    if (nextState) {
2034                        mUpdateLock.acquire();
2035                    } else {
2036                        mUpdateLock.release();
2037                    }
2038                }
2039                break;
2040            }
2041            case PERSIST_URI_GRANTS_MSG: {
2042                writeGrantedUriPermissions();
2043                break;
2044            }
2045            case REQUEST_ALL_PSS_MSG: {
2046                synchronized (ActivityManagerService.this) {
2047                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2048                }
2049                break;
2050            }
2051            case START_PROFILES_MSG: {
2052                synchronized (ActivityManagerService.this) {
2053                    mUserController.startProfilesLocked();
2054                }
2055                break;
2056            }
2057            case UPDATE_TIME_PREFERENCE_MSG: {
2058                // The user's time format preference might have changed.
2059                // For convenience we re-use the Intent extra values.
2060                synchronized (ActivityManagerService.this) {
2061                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2062                        ProcessRecord r = mLruProcesses.get(i);
2063                        if (r.thread != null) {
2064                            try {
2065                                r.thread.updateTimePrefs(msg.arg1);
2066                            } catch (RemoteException ex) {
2067                                Slog.w(TAG, "Failed to update preferences for: "
2068                                        + r.info.processName);
2069                            }
2070                        }
2071                    }
2072                }
2073                break;
2074            }
2075            case SYSTEM_USER_START_MSG: {
2076                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2077                        Integer.toString(msg.arg1), msg.arg1);
2078                mSystemServiceManager.startUser(msg.arg1);
2079                break;
2080            }
2081            case SYSTEM_USER_UNLOCK_MSG: {
2082                final int userId = msg.arg1;
2083                mSystemServiceManager.unlockUser(userId);
2084                synchronized (ActivityManagerService.this) {
2085                    mRecentTasks.loadUserRecentsLocked(userId);
2086                }
2087                if (userId == UserHandle.USER_SYSTEM) {
2088                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2089                }
2090                installEncryptionUnawareProviders(userId);
2091                mUserController.finishUserUnlocked((UserState) msg.obj);
2092                break;
2093            }
2094            case SYSTEM_USER_CURRENT_MSG: {
2095                mBatteryStatsService.noteEvent(
2096                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2097                        Integer.toString(msg.arg2), msg.arg2);
2098                mBatteryStatsService.noteEvent(
2099                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2100                        Integer.toString(msg.arg1), msg.arg1);
2101                mSystemServiceManager.switchUser(msg.arg1);
2102                break;
2103            }
2104            case ENTER_ANIMATION_COMPLETE_MSG: {
2105                synchronized (ActivityManagerService.this) {
2106                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2107                    if (r != null && r.app != null && r.app.thread != null) {
2108                        try {
2109                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2110                        } catch (RemoteException e) {
2111                        }
2112                    }
2113                }
2114                break;
2115            }
2116            case FINISH_BOOTING_MSG: {
2117                if (msg.arg1 != 0) {
2118                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2119                    finishBooting();
2120                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2121                }
2122                if (msg.arg2 != 0) {
2123                    enableScreenAfterBoot();
2124                }
2125                break;
2126            }
2127            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2128                try {
2129                    Locale l = (Locale) msg.obj;
2130                    IBinder service = ServiceManager.getService("mount");
2131                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2132                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2133                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2134                } catch (RemoteException e) {
2135                    Log.e(TAG, "Error storing locale for decryption UI", e);
2136                }
2137                break;
2138            }
2139            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2140                final int uid = msg.arg1;
2141                final byte[] firstPacket = (byte[]) msg.obj;
2142
2143                synchronized (mPidsSelfLocked) {
2144                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2145                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2146                        if (p.uid == uid) {
2147                            try {
2148                                p.thread.notifyCleartextNetwork(firstPacket);
2149                            } catch (RemoteException ignored) {
2150                            }
2151                        }
2152                    }
2153                }
2154                break;
2155            }
2156            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2157                final String procName;
2158                final int uid;
2159                final long memLimit;
2160                final String reportPackage;
2161                synchronized (ActivityManagerService.this) {
2162                    procName = mMemWatchDumpProcName;
2163                    uid = mMemWatchDumpUid;
2164                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2165                    if (val == null) {
2166                        val = mMemWatchProcesses.get(procName, 0);
2167                    }
2168                    if (val != null) {
2169                        memLimit = val.first;
2170                        reportPackage = val.second;
2171                    } else {
2172                        memLimit = 0;
2173                        reportPackage = null;
2174                    }
2175                }
2176                if (procName == null) {
2177                    return;
2178                }
2179
2180                if (DEBUG_PSS) Slog.d(TAG_PSS,
2181                        "Showing dump heap notification from " + procName + "/" + uid);
2182
2183                INotificationManager inm = NotificationManager.getService();
2184                if (inm == null) {
2185                    return;
2186                }
2187
2188                String text = mContext.getString(R.string.dump_heap_notification, procName);
2189
2190
2191                Intent deleteIntent = new Intent();
2192                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2193                Intent intent = new Intent();
2194                intent.setClassName("android", DumpHeapActivity.class.getName());
2195                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2196                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2197                if (reportPackage != null) {
2198                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2199                }
2200                int userId = UserHandle.getUserId(uid);
2201                Notification notification = new Notification.Builder(mContext)
2202                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2203                        .setWhen(0)
2204                        .setOngoing(true)
2205                        .setAutoCancel(true)
2206                        .setTicker(text)
2207                        .setColor(mContext.getColor(
2208                                com.android.internal.R.color.system_notification_accent_color))
2209                        .setContentTitle(text)
2210                        .setContentText(
2211                                mContext.getText(R.string.dump_heap_notification_detail))
2212                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2213                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2214                                new UserHandle(userId)))
2215                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2216                                deleteIntent, 0, UserHandle.SYSTEM))
2217                        .build();
2218
2219                try {
2220                    int[] outId = new int[1];
2221                    inm.enqueueNotificationWithTag("android", "android", null,
2222                            R.string.dump_heap_notification,
2223                            notification, outId, userId);
2224                } catch (RuntimeException e) {
2225                    Slog.w(ActivityManagerService.TAG,
2226                            "Error showing notification for dump heap", e);
2227                } catch (RemoteException e) {
2228                }
2229            } break;
2230            case DELETE_DUMPHEAP_MSG: {
2231                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2232                        DumpHeapActivity.JAVA_URI,
2233                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2234                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2235                        UserHandle.myUserId());
2236                synchronized (ActivityManagerService.this) {
2237                    mMemWatchDumpFile = null;
2238                    mMemWatchDumpProcName = null;
2239                    mMemWatchDumpPid = -1;
2240                    mMemWatchDumpUid = -1;
2241                }
2242            } break;
2243            case FOREGROUND_PROFILE_CHANGED_MSG: {
2244                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2245            } break;
2246            case REPORT_TIME_TRACKER_MSG: {
2247                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2248                tracker.deliverResult(mContext);
2249            } break;
2250            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2251                mUserController.dispatchUserSwitchComplete(msg.arg1);
2252            } break;
2253            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2254                mUserController.dispatchLockedBootComplete(msg.arg1);
2255            } break;
2256            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2257                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2258                try {
2259                    connection.shutdown();
2260                } catch (RemoteException e) {
2261                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2262                }
2263                // Only a UiAutomation can set this flag and now that
2264                // it is finished we make sure it is reset to its default.
2265                mUserIsMonkey = false;
2266            } break;
2267            case IDLE_UIDS_MSG: {
2268                idleUids();
2269            } break;
2270            case VR_MODE_CHANGE_MSG: {
2271                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2272                if (vrService == null) {
2273                    break;
2274                }
2275                final ActivityRecord r = (ActivityRecord) msg.obj;
2276                boolean vrMode;
2277                ComponentName requestedPackage;
2278                ComponentName callingPackage;
2279                int userId;
2280                synchronized (ActivityManagerService.this) {
2281                    vrMode = r.requestedVrComponent != null;
2282                    requestedPackage = r.requestedVrComponent;
2283                    userId = r.userId;
2284                    callingPackage = r.info.getComponentName();
2285                    if (mInVrMode != vrMode) {
2286                        mInVrMode = vrMode;
2287                        mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), mInVrMode);
2288                        if (r.app != null) {
2289                            ProcessRecord proc = r.app;
2290                            if (proc.vrThreadTid > 0) {
2291                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2292                                    try {
2293                                        if (mInVrMode == true) {
2294                                            Process.setThreadScheduler(proc.vrThreadTid,
2295                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2296                                        } else {
2297                                            Process.setThreadScheduler(proc.vrThreadTid,
2298                                                Process.SCHED_OTHER, 0);
2299                                        }
2300                                    } catch (IllegalArgumentException e) {
2301                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2302                                                + " not exist:\n" + e);
2303                                    }
2304                                }
2305                            }
2306                        }
2307                    }
2308                }
2309                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2310            } case NOTIFY_VR_SLEEPING_MSG: {
2311                notifyVrManagerOfSleepState(msg.arg1 != 0);
2312            } break;
2313            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2314                synchronized (ActivityManagerService.this) {
2315                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2316                        ProcessRecord r = mLruProcesses.get(i);
2317                        if (r.thread != null) {
2318                            try {
2319                                r.thread.handleTrustStorageUpdate();
2320                            } catch (RemoteException ex) {
2321                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2322                                        r.info.processName);
2323                            }
2324                        }
2325                    }
2326                }
2327            } break;
2328            }
2329        }
2330    };
2331
2332    static final int COLLECT_PSS_BG_MSG = 1;
2333
2334    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2335        @Override
2336        public void handleMessage(Message msg) {
2337            switch (msg.what) {
2338            case COLLECT_PSS_BG_MSG: {
2339                long start = SystemClock.uptimeMillis();
2340                MemInfoReader memInfo = null;
2341                synchronized (ActivityManagerService.this) {
2342                    if (mFullPssPending) {
2343                        mFullPssPending = false;
2344                        memInfo = new MemInfoReader();
2345                    }
2346                }
2347                if (memInfo != null) {
2348                    updateCpuStatsNow();
2349                    long nativeTotalPss = 0;
2350                    final List<ProcessCpuTracker.Stats> stats;
2351                    synchronized (mProcessCpuTracker) {
2352                        stats = mProcessCpuTracker.getStats( (st)-> {
2353                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2354                        });
2355                    }
2356                    final int N = stats.size();
2357                    for (int j = 0; j < N; j++) {
2358                        synchronized (mPidsSelfLocked) {
2359                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2360                                // This is one of our own processes; skip it.
2361                                continue;
2362                            }
2363                        }
2364                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2365                    }
2366                    memInfo.readMemInfo();
2367                    synchronized (ActivityManagerService.this) {
2368                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2369                                + (SystemClock.uptimeMillis()-start) + "ms");
2370                        final long cachedKb = memInfo.getCachedSizeKb();
2371                        final long freeKb = memInfo.getFreeSizeKb();
2372                        final long zramKb = memInfo.getZramTotalSizeKb();
2373                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2374                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2375                                kernelKb*1024, nativeTotalPss*1024);
2376                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2377                                nativeTotalPss);
2378                    }
2379                }
2380
2381                int num = 0;
2382                long[] tmp = new long[2];
2383                do {
2384                    ProcessRecord proc;
2385                    int procState;
2386                    int pid;
2387                    long lastPssTime;
2388                    synchronized (ActivityManagerService.this) {
2389                        if (mPendingPssProcesses.size() <= 0) {
2390                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2391                                    "Collected PSS of " + num + " processes in "
2392                                    + (SystemClock.uptimeMillis() - start) + "ms");
2393                            mPendingPssProcesses.clear();
2394                            return;
2395                        }
2396                        proc = mPendingPssProcesses.remove(0);
2397                        procState = proc.pssProcState;
2398                        lastPssTime = proc.lastPssTime;
2399                        if (proc.thread != null && procState == proc.setProcState
2400                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2401                                        < SystemClock.uptimeMillis()) {
2402                            pid = proc.pid;
2403                        } else {
2404                            proc = null;
2405                            pid = 0;
2406                        }
2407                    }
2408                    if (proc != null) {
2409                        long pss = Debug.getPss(pid, tmp, null);
2410                        synchronized (ActivityManagerService.this) {
2411                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2412                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2413                                num++;
2414                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2415                                        SystemClock.uptimeMillis());
2416                            }
2417                        }
2418                    }
2419                } while (true);
2420            }
2421            }
2422        }
2423    };
2424
2425    public void setSystemProcess() {
2426        try {
2427            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2428            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2429            ServiceManager.addService("meminfo", new MemBinder(this));
2430            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2431            ServiceManager.addService("dbinfo", new DbBinder(this));
2432            if (MONITOR_CPU_USAGE) {
2433                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2434            }
2435            ServiceManager.addService("permission", new PermissionController(this));
2436            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2437
2438            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2439                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2440            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2441
2442            synchronized (this) {
2443                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2444                app.persistent = true;
2445                app.pid = MY_PID;
2446                app.maxAdj = ProcessList.SYSTEM_ADJ;
2447                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2448                synchronized (mPidsSelfLocked) {
2449                    mPidsSelfLocked.put(app.pid, app);
2450                }
2451                updateLruProcessLocked(app, false, null);
2452                updateOomAdjLocked();
2453            }
2454        } catch (PackageManager.NameNotFoundException e) {
2455            throw new RuntimeException(
2456                    "Unable to find android system package", e);
2457        }
2458    }
2459
2460    public void setWindowManager(WindowManagerService wm) {
2461        mWindowManager = wm;
2462        mStackSupervisor.setWindowManager(wm);
2463        mActivityStarter.setWindowManager(wm);
2464    }
2465
2466    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2467        mUsageStatsService = usageStatsManager;
2468    }
2469
2470    public void startObservingNativeCrashes() {
2471        final NativeCrashListener ncl = new NativeCrashListener(this);
2472        ncl.start();
2473    }
2474
2475    public IAppOpsService getAppOpsService() {
2476        return mAppOpsService;
2477    }
2478
2479    static class MemBinder extends Binder {
2480        ActivityManagerService mActivityManagerService;
2481        MemBinder(ActivityManagerService activityManagerService) {
2482            mActivityManagerService = activityManagerService;
2483        }
2484
2485        @Override
2486        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2487            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2488                    != PackageManager.PERMISSION_GRANTED) {
2489                pw.println("Permission Denial: can't dump meminfo from from pid="
2490                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2491                        + " without permission " + android.Manifest.permission.DUMP);
2492                return;
2493            }
2494
2495            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2496        }
2497    }
2498
2499    static class GraphicsBinder extends Binder {
2500        ActivityManagerService mActivityManagerService;
2501        GraphicsBinder(ActivityManagerService activityManagerService) {
2502            mActivityManagerService = activityManagerService;
2503        }
2504
2505        @Override
2506        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2507            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2508                    != PackageManager.PERMISSION_GRANTED) {
2509                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2510                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2511                        + " without permission " + android.Manifest.permission.DUMP);
2512                return;
2513            }
2514
2515            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2516        }
2517    }
2518
2519    static class DbBinder extends Binder {
2520        ActivityManagerService mActivityManagerService;
2521        DbBinder(ActivityManagerService activityManagerService) {
2522            mActivityManagerService = activityManagerService;
2523        }
2524
2525        @Override
2526        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2527            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2528                    != PackageManager.PERMISSION_GRANTED) {
2529                pw.println("Permission Denial: can't dump dbinfo from from pid="
2530                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2531                        + " without permission " + android.Manifest.permission.DUMP);
2532                return;
2533            }
2534
2535            mActivityManagerService.dumpDbInfo(fd, pw, args);
2536        }
2537    }
2538
2539    static class CpuBinder extends Binder {
2540        ActivityManagerService mActivityManagerService;
2541        CpuBinder(ActivityManagerService activityManagerService) {
2542            mActivityManagerService = activityManagerService;
2543        }
2544
2545        @Override
2546        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2547            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2548                    != PackageManager.PERMISSION_GRANTED) {
2549                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2550                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2551                        + " without permission " + android.Manifest.permission.DUMP);
2552                return;
2553            }
2554
2555            synchronized (mActivityManagerService.mProcessCpuTracker) {
2556                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2557                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2558                        SystemClock.uptimeMillis()));
2559            }
2560        }
2561    }
2562
2563    public static final class Lifecycle extends SystemService {
2564        private final ActivityManagerService mService;
2565
2566        public Lifecycle(Context context) {
2567            super(context);
2568            mService = new ActivityManagerService(context);
2569        }
2570
2571        @Override
2572        public void onStart() {
2573            mService.start();
2574        }
2575
2576        public ActivityManagerService getService() {
2577            return mService;
2578        }
2579    }
2580
2581    // Note: This method is invoked on the main thread but may need to attach various
2582    // handlers to other threads.  So take care to be explicit about the looper.
2583    public ActivityManagerService(Context systemContext) {
2584        mContext = systemContext;
2585        mFactoryTest = FactoryTest.getMode();
2586        mSystemThread = ActivityThread.currentActivityThread();
2587
2588        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2589
2590        mPermissionReviewRequired = mContext.getResources().getBoolean(
2591                com.android.internal.R.bool.config_permissionReviewRequired);
2592
2593        mHandlerThread = new ServiceThread(TAG,
2594                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2595        mHandlerThread.start();
2596        mHandler = new MainHandler(mHandlerThread.getLooper());
2597        mUiHandler = new UiHandler();
2598
2599        /* static; one-time init here */
2600        if (sKillHandler == null) {
2601            sKillThread = new ServiceThread(TAG + ":kill",
2602                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2603            sKillThread.start();
2604            sKillHandler = new KillHandler(sKillThread.getLooper());
2605        }
2606
2607        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2608                "foreground", BROADCAST_FG_TIMEOUT, false);
2609        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2610                "background", BROADCAST_BG_TIMEOUT, true);
2611        mBroadcastQueues[0] = mFgBroadcastQueue;
2612        mBroadcastQueues[1] = mBgBroadcastQueue;
2613
2614        mServices = new ActiveServices(this);
2615        mProviderMap = new ProviderMap(this);
2616        mAppErrors = new AppErrors(mContext, this);
2617
2618        // TODO: Move creation of battery stats service outside of activity manager service.
2619        File dataDir = Environment.getDataDirectory();
2620        File systemDir = new File(dataDir, "system");
2621        systemDir.mkdirs();
2622        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2623        mBatteryStatsService.getActiveStatistics().readLocked();
2624        mBatteryStatsService.scheduleWriteToDisk();
2625        mOnBattery = DEBUG_POWER ? true
2626                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2627        mBatteryStatsService.getActiveStatistics().setCallback(this);
2628
2629        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2630
2631        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2632        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2633                new IAppOpsCallback.Stub() {
2634                    @Override public void opChanged(int op, int uid, String packageName) {
2635                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2636                            if (mAppOpsService.checkOperation(op, uid, packageName)
2637                                    != AppOpsManager.MODE_ALLOWED) {
2638                                runInBackgroundDisabled(uid);
2639                            }
2640                        }
2641                    }
2642                });
2643
2644        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2645
2646        mUserController = new UserController(this);
2647
2648        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2649            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2650
2651        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2652            mUseFifoUiScheduling = true;
2653        }
2654
2655        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2656        mTempConfig.setToDefaults();
2657        mTempConfig.setLocales(LocaleList.getDefault());
2658        mConfigurationSeq = mTempConfig.seq = 1;
2659        mStackSupervisor = new ActivityStackSupervisor(this);
2660        mStackSupervisor.onConfigurationChanged(mTempConfig);
2661        mKeyguardController = mStackSupervisor.mKeyguardController;
2662        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2663        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2664        mTaskChangeNotificationController =
2665                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2666        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2667        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2668
2669        mProcessCpuThread = new Thread("CpuTracker") {
2670            @Override
2671            public void run() {
2672                synchronized (mProcessCpuTracker) {
2673                    mProcessCpuInitLatch.countDown();
2674                    mProcessCpuTracker.init();
2675                }
2676                while (true) {
2677                    try {
2678                        try {
2679                            synchronized(this) {
2680                                final long now = SystemClock.uptimeMillis();
2681                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2682                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2683                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2684                                //        + ", write delay=" + nextWriteDelay);
2685                                if (nextWriteDelay < nextCpuDelay) {
2686                                    nextCpuDelay = nextWriteDelay;
2687                                }
2688                                if (nextCpuDelay > 0) {
2689                                    mProcessCpuMutexFree.set(true);
2690                                    this.wait(nextCpuDelay);
2691                                }
2692                            }
2693                        } catch (InterruptedException e) {
2694                        }
2695                        updateCpuStatsNow();
2696                    } catch (Exception e) {
2697                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2698                    }
2699                }
2700            }
2701        };
2702
2703        Watchdog.getInstance().addMonitor(this);
2704        Watchdog.getInstance().addThread(mHandler);
2705    }
2706
2707    public void setSystemServiceManager(SystemServiceManager mgr) {
2708        mSystemServiceManager = mgr;
2709    }
2710
2711    public void setInstaller(Installer installer) {
2712        mInstaller = installer;
2713    }
2714
2715    private void start() {
2716        Process.removeAllProcessGroups();
2717        mProcessCpuThread.start();
2718
2719        mBatteryStatsService.publish(mContext);
2720        mAppOpsService.publish(mContext);
2721        Slog.d("AppOps", "AppOpsService published");
2722        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2723        // Wait for the synchronized block started in mProcessCpuThread,
2724        // so that any other acccess to mProcessCpuTracker from main thread
2725        // will be blocked during mProcessCpuTracker initialization.
2726        try {
2727            mProcessCpuInitLatch.await();
2728        } catch (InterruptedException e) {
2729            Slog.wtf(TAG, "Interrupted wait during start", e);
2730            Thread.currentThread().interrupt();
2731            throw new IllegalStateException("Interrupted wait during start");
2732        }
2733    }
2734
2735    void onUserStoppedLocked(int userId) {
2736        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2737    }
2738
2739    public void initPowerManagement() {
2740        mStackSupervisor.initPowerManagement();
2741        mBatteryStatsService.initPowerManagement();
2742        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2743        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2744        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2745        mVoiceWakeLock.setReferenceCounted(false);
2746    }
2747
2748    @Override
2749    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2750            throws RemoteException {
2751        if (code == SYSPROPS_TRANSACTION) {
2752            // We need to tell all apps about the system property change.
2753            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2754            synchronized(this) {
2755                final int NP = mProcessNames.getMap().size();
2756                for (int ip=0; ip<NP; ip++) {
2757                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2758                    final int NA = apps.size();
2759                    for (int ia=0; ia<NA; ia++) {
2760                        ProcessRecord app = apps.valueAt(ia);
2761                        if (app.thread != null) {
2762                            procs.add(app.thread.asBinder());
2763                        }
2764                    }
2765                }
2766            }
2767
2768            int N = procs.size();
2769            for (int i=0; i<N; i++) {
2770                Parcel data2 = Parcel.obtain();
2771                try {
2772                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2773                            Binder.FLAG_ONEWAY);
2774                } catch (RemoteException e) {
2775                }
2776                data2.recycle();
2777            }
2778        }
2779        try {
2780            return super.onTransact(code, data, reply, flags);
2781        } catch (RuntimeException e) {
2782            // The activity manager only throws security exceptions, so let's
2783            // log all others.
2784            if (!(e instanceof SecurityException)) {
2785                Slog.wtf(TAG, "Activity Manager Crash", e);
2786            }
2787            throw e;
2788        }
2789    }
2790
2791    void updateCpuStats() {
2792        final long now = SystemClock.uptimeMillis();
2793        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2794            return;
2795        }
2796        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2797            synchronized (mProcessCpuThread) {
2798                mProcessCpuThread.notify();
2799            }
2800        }
2801    }
2802
2803    void updateCpuStatsNow() {
2804        synchronized (mProcessCpuTracker) {
2805            mProcessCpuMutexFree.set(false);
2806            final long now = SystemClock.uptimeMillis();
2807            boolean haveNewCpuStats = false;
2808
2809            if (MONITOR_CPU_USAGE &&
2810                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2811                mLastCpuTime.set(now);
2812                mProcessCpuTracker.update();
2813                if (mProcessCpuTracker.hasGoodLastStats()) {
2814                    haveNewCpuStats = true;
2815                    //Slog.i(TAG, mProcessCpu.printCurrentState());
2816                    //Slog.i(TAG, "Total CPU usage: "
2817                    //        + mProcessCpu.getTotalCpuPercent() + "%");
2818
2819                    // Slog the cpu usage if the property is set.
2820                    if ("true".equals(SystemProperties.get("events.cpu"))) {
2821                        int user = mProcessCpuTracker.getLastUserTime();
2822                        int system = mProcessCpuTracker.getLastSystemTime();
2823                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
2824                        int irq = mProcessCpuTracker.getLastIrqTime();
2825                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2826                        int idle = mProcessCpuTracker.getLastIdleTime();
2827
2828                        int total = user + system + iowait + irq + softIrq + idle;
2829                        if (total == 0) total = 1;
2830
2831                        EventLog.writeEvent(EventLogTags.CPU,
2832                                ((user+system+iowait+irq+softIrq) * 100) / total,
2833                                (user * 100) / total,
2834                                (system * 100) / total,
2835                                (iowait * 100) / total,
2836                                (irq * 100) / total,
2837                                (softIrq * 100) / total);
2838                    }
2839                }
2840            }
2841
2842            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2843            synchronized(bstats) {
2844                synchronized(mPidsSelfLocked) {
2845                    if (haveNewCpuStats) {
2846                        if (bstats.startAddingCpuLocked()) {
2847                            int totalUTime = 0;
2848                            int totalSTime = 0;
2849                            final int N = mProcessCpuTracker.countStats();
2850                            for (int i=0; i<N; i++) {
2851                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2852                                if (!st.working) {
2853                                    continue;
2854                                }
2855                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2856                                totalUTime += st.rel_utime;
2857                                totalSTime += st.rel_stime;
2858                                if (pr != null) {
2859                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2860                                    if (ps == null || !ps.isActive()) {
2861                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2862                                                pr.info.uid, pr.processName);
2863                                    }
2864                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2865                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
2866                                } else {
2867                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2868                                    if (ps == null || !ps.isActive()) {
2869                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2870                                                bstats.mapUid(st.uid), st.name);
2871                                    }
2872                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2873                                }
2874                            }
2875                            final int userTime = mProcessCpuTracker.getLastUserTime();
2876                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
2877                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2878                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
2879                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2880                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
2881                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2882                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2883                        }
2884                    }
2885                }
2886
2887                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2888                    mLastWriteTime = now;
2889                    mBatteryStatsService.scheduleWriteToDisk();
2890                }
2891            }
2892        }
2893    }
2894
2895    @Override
2896    public void batteryNeedsCpuUpdate() {
2897        updateCpuStatsNow();
2898    }
2899
2900    @Override
2901    public void batteryPowerChanged(boolean onBattery) {
2902        // When plugging in, update the CPU stats first before changing
2903        // the plug state.
2904        updateCpuStatsNow();
2905        synchronized (this) {
2906            synchronized(mPidsSelfLocked) {
2907                mOnBattery = DEBUG_POWER ? true : onBattery;
2908            }
2909        }
2910    }
2911
2912    @Override
2913    public void batterySendBroadcast(Intent intent) {
2914        synchronized (this) {
2915            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2916                    AppOpsManager.OP_NONE, null, false, false,
2917                    -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2918        }
2919    }
2920
2921    /**
2922     * Initialize the application bind args. These are passed to each
2923     * process when the bindApplication() IPC is sent to the process. They're
2924     * lazily setup to make sure the services are running when they're asked for.
2925     */
2926    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2927        // Isolated processes won't get this optimization, so that we don't
2928        // violate the rules about which services they have access to.
2929        if (isolated) {
2930            if (mIsolatedAppBindArgs == null) {
2931                mIsolatedAppBindArgs = new HashMap<>();
2932                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2933            }
2934            return mIsolatedAppBindArgs;
2935        }
2936
2937        if (mAppBindArgs == null) {
2938            mAppBindArgs = new HashMap<>();
2939
2940            // Setup the application init args
2941            mAppBindArgs.put("package", ServiceManager.getService("package"));
2942            mAppBindArgs.put("window", ServiceManager.getService("window"));
2943            mAppBindArgs.put(Context.ALARM_SERVICE,
2944                    ServiceManager.getService(Context.ALARM_SERVICE));
2945        }
2946        return mAppBindArgs;
2947    }
2948
2949    /**
2950     * Update AMS states when an activity is resumed. This should only be called by
2951     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
2952     */
2953    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
2954        if (r.task.isApplicationTask()) {
2955            if (mCurAppTimeTracker != r.appTimeTracker) {
2956                // We are switching app tracking.  Complete the current one.
2957                if (mCurAppTimeTracker != null) {
2958                    mCurAppTimeTracker.stop();
2959                    mHandler.obtainMessage(
2960                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2961                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2962                    mCurAppTimeTracker = null;
2963                }
2964                if (r.appTimeTracker != null) {
2965                    mCurAppTimeTracker = r.appTimeTracker;
2966                    startTimeTrackingFocusedActivityLocked();
2967                }
2968            } else {
2969                startTimeTrackingFocusedActivityLocked();
2970            }
2971        } else {
2972            r.appTimeTracker = null;
2973        }
2974        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2975        // TODO: Probably not, because we don't want to resume voice on switching
2976        // back to this activity
2977        if (r.task.voiceInteractor != null) {
2978            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2979        } else {
2980            finishRunningVoiceLocked();
2981            IVoiceInteractionSession session;
2982            if (mLastResumedActivity != null
2983                    && ((session = mLastResumedActivity.task.voiceSession) != null
2984                    || (session = mLastResumedActivity.voiceSession) != null)) {
2985                // We had been in a voice interaction session, but now focused has
2986                // move to something different.  Just finish the session, we can't
2987                // return to it and retain the proper state and synchronization with
2988                // the voice interaction service.
2989                finishVoiceTask(session);
2990            }
2991        }
2992
2993        mWindowManager.setFocusedApp(r.appToken, true);
2994
2995        applyUpdateLockStateLocked(r);
2996        applyUpdateVrModeLocked(r);
2997        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
2998            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2999            mHandler.obtainMessage(
3000                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3001        }
3002
3003        mLastResumedActivity = r;
3004
3005        EventLogTags.writeAmSetResumedActivity(
3006                r == null ? -1 : r.userId,
3007                r == null ? "NULL" : r.shortComponentName,
3008                reason);
3009    }
3010
3011    @Override
3012    public void setFocusedStack(int stackId) {
3013        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3014        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3015        final long callingId = Binder.clearCallingIdentity();
3016        try {
3017            synchronized (this) {
3018                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3019                if (stack == null) {
3020                    return;
3021                }
3022                final ActivityRecord r = stack.topRunningActivityLocked();
3023                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3024                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3025                }
3026            }
3027        } finally {
3028            Binder.restoreCallingIdentity(callingId);
3029        }
3030    }
3031
3032    @Override
3033    public void setFocusedTask(int taskId) {
3034        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3035        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3036        final long callingId = Binder.clearCallingIdentity();
3037        try {
3038            synchronized (this) {
3039                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3040                if (task == null) {
3041                    return;
3042                }
3043                final ActivityRecord r = task.topRunningActivityLocked();
3044                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3045                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3046                }
3047            }
3048        } finally {
3049            Binder.restoreCallingIdentity(callingId);
3050        }
3051    }
3052
3053    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3054    @Override
3055    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3056        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3057        mTaskChangeNotificationController.registerTaskStackListener(listener);
3058    }
3059
3060    /**
3061     * Unregister a task stack listener so that it stops receiving callbacks.
3062     */
3063    @Override
3064    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3065         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3066         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3067     }
3068
3069    @Override
3070    public void notifyActivityDrawn(IBinder token) {
3071        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3072        synchronized (this) {
3073            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3074            if (r != null) {
3075                r.getStack().notifyActivityDrawnLocked(r);
3076            }
3077        }
3078    }
3079
3080    final void applyUpdateLockStateLocked(ActivityRecord r) {
3081        // Modifications to the UpdateLock state are done on our handler, outside
3082        // the activity manager's locks.  The new state is determined based on the
3083        // state *now* of the relevant activity record.  The object is passed to
3084        // the handler solely for logging detail, not to be consulted/modified.
3085        final boolean nextState = r != null && r.immersive;
3086        mHandler.sendMessage(
3087                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3088    }
3089
3090    final void applyUpdateVrModeLocked(ActivityRecord r) {
3091        mHandler.sendMessage(
3092                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3093    }
3094
3095    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3096        mHandler.sendMessage(
3097                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3098    }
3099
3100    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3101        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3102        if (vrService == null) {
3103            return;
3104        }
3105        vrService.onSleepStateChanged(isSleeping);
3106    }
3107
3108    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3109        Message msg = Message.obtain();
3110        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3111        msg.obj = r.task.askedCompatMode ? null : r;
3112        mUiHandler.sendMessage(msg);
3113    }
3114
3115    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3116        final Configuration globalConfig = getGlobalConfiguration();
3117        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3118                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3119            final Message msg = Message.obtain();
3120            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3121            msg.obj = r;
3122            mUiHandler.sendMessage(msg);
3123        }
3124    }
3125
3126    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3127            String what, Object obj, ProcessRecord srcApp) {
3128        app.lastActivityTime = now;
3129
3130        if (app.activities.size() > 0) {
3131            // Don't want to touch dependent processes that are hosting activities.
3132            return index;
3133        }
3134
3135        int lrui = mLruProcesses.lastIndexOf(app);
3136        if (lrui < 0) {
3137            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3138                    + what + " " + obj + " from " + srcApp);
3139            return index;
3140        }
3141
3142        if (lrui >= index) {
3143            // Don't want to cause this to move dependent processes *back* in the
3144            // list as if they were less frequently used.
3145            return index;
3146        }
3147
3148        if (lrui >= mLruProcessActivityStart) {
3149            // Don't want to touch dependent processes that are hosting activities.
3150            return index;
3151        }
3152
3153        mLruProcesses.remove(lrui);
3154        if (index > 0) {
3155            index--;
3156        }
3157        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3158                + " in LRU list: " + app);
3159        mLruProcesses.add(index, app);
3160        return index;
3161    }
3162
3163    static void killProcessGroup(int uid, int pid) {
3164        if (sKillHandler != null) {
3165            sKillHandler.sendMessage(
3166                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3167        } else {
3168            Slog.w(TAG, "Asked to kill process group before system bringup!");
3169            Process.killProcessGroup(uid, pid);
3170        }
3171    }
3172
3173    final void removeLruProcessLocked(ProcessRecord app) {
3174        int lrui = mLruProcesses.lastIndexOf(app);
3175        if (lrui >= 0) {
3176            if (!app.killed) {
3177                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3178                Process.killProcessQuiet(app.pid);
3179                killProcessGroup(app.uid, app.pid);
3180            }
3181            if (lrui <= mLruProcessActivityStart) {
3182                mLruProcessActivityStart--;
3183            }
3184            if (lrui <= mLruProcessServiceStart) {
3185                mLruProcessServiceStart--;
3186            }
3187            mLruProcesses.remove(lrui);
3188        }
3189    }
3190
3191    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3192            ProcessRecord client) {
3193        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3194                || app.treatLikeActivity;
3195        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3196        if (!activityChange && hasActivity) {
3197            // The process has activities, so we are only allowing activity-based adjustments
3198            // to move it.  It should be kept in the front of the list with other
3199            // processes that have activities, and we don't want those to change their
3200            // order except due to activity operations.
3201            return;
3202        }
3203
3204        mLruSeq++;
3205        final long now = SystemClock.uptimeMillis();
3206        app.lastActivityTime = now;
3207
3208        // First a quick reject: if the app is already at the position we will
3209        // put it, then there is nothing to do.
3210        if (hasActivity) {
3211            final int N = mLruProcesses.size();
3212            if (N > 0 && mLruProcesses.get(N-1) == app) {
3213                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3214                return;
3215            }
3216        } else {
3217            if (mLruProcessServiceStart > 0
3218                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3219                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3220                return;
3221            }
3222        }
3223
3224        int lrui = mLruProcesses.lastIndexOf(app);
3225
3226        if (app.persistent && lrui >= 0) {
3227            // We don't care about the position of persistent processes, as long as
3228            // they are in the list.
3229            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3230            return;
3231        }
3232
3233        /* In progress: compute new position first, so we can avoid doing work
3234           if the process is not actually going to move.  Not yet working.
3235        int addIndex;
3236        int nextIndex;
3237        boolean inActivity = false, inService = false;
3238        if (hasActivity) {
3239            // Process has activities, put it at the very tipsy-top.
3240            addIndex = mLruProcesses.size();
3241            nextIndex = mLruProcessServiceStart;
3242            inActivity = true;
3243        } else if (hasService) {
3244            // Process has services, put it at the top of the service list.
3245            addIndex = mLruProcessActivityStart;
3246            nextIndex = mLruProcessServiceStart;
3247            inActivity = true;
3248            inService = true;
3249        } else  {
3250            // Process not otherwise of interest, it goes to the top of the non-service area.
3251            addIndex = mLruProcessServiceStart;
3252            if (client != null) {
3253                int clientIndex = mLruProcesses.lastIndexOf(client);
3254                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3255                        + app);
3256                if (clientIndex >= 0 && addIndex > clientIndex) {
3257                    addIndex = clientIndex;
3258                }
3259            }
3260            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3261        }
3262
3263        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3264                + mLruProcessActivityStart + "): " + app);
3265        */
3266
3267        if (lrui >= 0) {
3268            if (lrui < mLruProcessActivityStart) {
3269                mLruProcessActivityStart--;
3270            }
3271            if (lrui < mLruProcessServiceStart) {
3272                mLruProcessServiceStart--;
3273            }
3274            /*
3275            if (addIndex > lrui) {
3276                addIndex--;
3277            }
3278            if (nextIndex > lrui) {
3279                nextIndex--;
3280            }
3281            */
3282            mLruProcesses.remove(lrui);
3283        }
3284
3285        /*
3286        mLruProcesses.add(addIndex, app);
3287        if (inActivity) {
3288            mLruProcessActivityStart++;
3289        }
3290        if (inService) {
3291            mLruProcessActivityStart++;
3292        }
3293        */
3294
3295        int nextIndex;
3296        if (hasActivity) {
3297            final int N = mLruProcesses.size();
3298            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3299                // Process doesn't have activities, but has clients with
3300                // activities...  move it up, but one below the top (the top
3301                // should always have a real activity).
3302                if (DEBUG_LRU) Slog.d(TAG_LRU,
3303                        "Adding to second-top of LRU activity list: " + app);
3304                mLruProcesses.add(N - 1, app);
3305                // To keep it from spamming the LRU list (by making a bunch of clients),
3306                // we will push down any other entries owned by the app.
3307                final int uid = app.info.uid;
3308                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3309                    ProcessRecord subProc = mLruProcesses.get(i);
3310                    if (subProc.info.uid == uid) {
3311                        // We want to push this one down the list.  If the process after
3312                        // it is for the same uid, however, don't do so, because we don't
3313                        // want them internally to be re-ordered.
3314                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3315                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3316                                    "Pushing uid " + uid + " swapping at " + i + ": "
3317                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3318                            ProcessRecord tmp = mLruProcesses.get(i);
3319                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3320                            mLruProcesses.set(i - 1, tmp);
3321                            i--;
3322                        }
3323                    } else {
3324                        // A gap, we can stop here.
3325                        break;
3326                    }
3327                }
3328            } else {
3329                // Process has activities, put it at the very tipsy-top.
3330                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3331                mLruProcesses.add(app);
3332            }
3333            nextIndex = mLruProcessServiceStart;
3334        } else if (hasService) {
3335            // Process has services, put it at the top of the service list.
3336            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3337            mLruProcesses.add(mLruProcessActivityStart, app);
3338            nextIndex = mLruProcessServiceStart;
3339            mLruProcessActivityStart++;
3340        } else  {
3341            // Process not otherwise of interest, it goes to the top of the non-service area.
3342            int index = mLruProcessServiceStart;
3343            if (client != null) {
3344                // If there is a client, don't allow the process to be moved up higher
3345                // in the list than that client.
3346                int clientIndex = mLruProcesses.lastIndexOf(client);
3347                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3348                        + " when updating " + app);
3349                if (clientIndex <= lrui) {
3350                    // Don't allow the client index restriction to push it down farther in the
3351                    // list than it already is.
3352                    clientIndex = lrui;
3353                }
3354                if (clientIndex >= 0 && index > clientIndex) {
3355                    index = clientIndex;
3356                }
3357            }
3358            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3359            mLruProcesses.add(index, app);
3360            nextIndex = index-1;
3361            mLruProcessActivityStart++;
3362            mLruProcessServiceStart++;
3363        }
3364
3365        // If the app is currently using a content provider or service,
3366        // bump those processes as well.
3367        for (int j=app.connections.size()-1; j>=0; j--) {
3368            ConnectionRecord cr = app.connections.valueAt(j);
3369            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3370                    && cr.binding.service.app != null
3371                    && cr.binding.service.app.lruSeq != mLruSeq
3372                    && !cr.binding.service.app.persistent) {
3373                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3374                        "service connection", cr, app);
3375            }
3376        }
3377        for (int j=app.conProviders.size()-1; j>=0; j--) {
3378            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3379            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3380                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3381                        "provider reference", cpr, app);
3382            }
3383        }
3384    }
3385
3386    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3387        if (uid == Process.SYSTEM_UID) {
3388            // The system gets to run in any process.  If there are multiple
3389            // processes with the same uid, just pick the first (this
3390            // should never happen).
3391            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3392            if (procs == null) return null;
3393            final int procCount = procs.size();
3394            for (int i = 0; i < procCount; i++) {
3395                final int procUid = procs.keyAt(i);
3396                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3397                    // Don't use an app process or different user process for system component.
3398                    continue;
3399                }
3400                return procs.valueAt(i);
3401            }
3402        }
3403        ProcessRecord proc = mProcessNames.get(processName, uid);
3404        if (false && proc != null && !keepIfLarge
3405                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3406                && proc.lastCachedPss >= 4000) {
3407            // Turn this condition on to cause killing to happen regularly, for testing.
3408            if (proc.baseProcessTracker != null) {
3409                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3410            }
3411            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3412        } else if (proc != null && !keepIfLarge
3413                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3414                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3415            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3416            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3417                if (proc.baseProcessTracker != null) {
3418                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3419                }
3420                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3421            }
3422        }
3423        return proc;
3424    }
3425
3426    void notifyPackageUse(String packageName, int reason) {
3427        IPackageManager pm = AppGlobals.getPackageManager();
3428        try {
3429            pm.notifyPackageUse(packageName, reason);
3430        } catch (RemoteException e) {
3431        }
3432    }
3433
3434    boolean isNextTransitionForward() {
3435        int transit = mWindowManager.getPendingAppTransition();
3436        return transit == TRANSIT_ACTIVITY_OPEN
3437                || transit == TRANSIT_TASK_OPEN
3438                || transit == TRANSIT_TASK_TO_FRONT;
3439    }
3440
3441    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3442            String processName, String abiOverride, int uid, Runnable crashHandler) {
3443        synchronized(this) {
3444            ApplicationInfo info = new ApplicationInfo();
3445            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3446            // For isolated processes, the former contains the parent's uid and the latter the
3447            // actual uid of the isolated process.
3448            // In the special case introduced by this method (which is, starting an isolated
3449            // process directly from the SystemServer without an actual parent app process) the
3450            // closest thing to a parent's uid is SYSTEM_UID.
3451            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3452            // the |isolated| logic in the ProcessRecord constructor.
3453            info.uid = Process.SYSTEM_UID;
3454            info.processName = processName;
3455            info.className = entryPoint;
3456            info.packageName = "android";
3457            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3458                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3459                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3460                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3461                    crashHandler);
3462            return proc != null ? proc.pid : 0;
3463        }
3464    }
3465
3466    final ProcessRecord startProcessLocked(String processName,
3467            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3468            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3469            boolean isolated, boolean keepIfLarge) {
3470        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3471                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3472                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3473                null /* crashHandler */);
3474    }
3475
3476    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3477            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3478            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3479            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3480        long startTime = SystemClock.elapsedRealtime();
3481        ProcessRecord app;
3482        if (!isolated) {
3483            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3484            checkTime(startTime, "startProcess: after getProcessRecord");
3485
3486            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3487                // If we are in the background, then check to see if this process
3488                // is bad.  If so, we will just silently fail.
3489                if (mAppErrors.isBadProcessLocked(info)) {
3490                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3491                            + "/" + info.processName);
3492                    return null;
3493                }
3494            } else {
3495                // When the user is explicitly starting a process, then clear its
3496                // crash count so that we won't make it bad until they see at
3497                // least one crash dialog again, and make the process good again
3498                // if it had been bad.
3499                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3500                        + "/" + info.processName);
3501                mAppErrors.resetProcessCrashTimeLocked(info);
3502                if (mAppErrors.isBadProcessLocked(info)) {
3503                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3504                            UserHandle.getUserId(info.uid), info.uid,
3505                            info.processName);
3506                    mAppErrors.clearBadProcessLocked(info);
3507                    if (app != null) {
3508                        app.bad = false;
3509                    }
3510                }
3511            }
3512        } else {
3513            // If this is an isolated process, it can't re-use an existing process.
3514            app = null;
3515        }
3516
3517        // We don't have to do anything more if:
3518        // (1) There is an existing application record; and
3519        // (2) The caller doesn't think it is dead, OR there is no thread
3520        //     object attached to it so we know it couldn't have crashed; and
3521        // (3) There is a pid assigned to it, so it is either starting or
3522        //     already running.
3523        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3524                + " app=" + app + " knownToBeDead=" + knownToBeDead
3525                + " thread=" + (app != null ? app.thread : null)
3526                + " pid=" + (app != null ? app.pid : -1));
3527        if (app != null && app.pid > 0) {
3528            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3529                // We already have the app running, or are waiting for it to
3530                // come up (we have a pid but not yet its thread), so keep it.
3531                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3532                // If this is a new package in the process, add the package to the list
3533                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3534                checkTime(startTime, "startProcess: done, added package to proc");
3535                return app;
3536            }
3537
3538            // An application record is attached to a previous process,
3539            // clean it up now.
3540            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3541            checkTime(startTime, "startProcess: bad proc running, killing");
3542            killProcessGroup(app.uid, app.pid);
3543            handleAppDiedLocked(app, true, true);
3544            checkTime(startTime, "startProcess: done killing old proc");
3545        }
3546
3547        String hostingNameStr = hostingName != null
3548                ? hostingName.flattenToShortString() : null;
3549
3550        if (app == null) {
3551            checkTime(startTime, "startProcess: creating new process record");
3552            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3553            if (app == null) {
3554                Slog.w(TAG, "Failed making new process record for "
3555                        + processName + "/" + info.uid + " isolated=" + isolated);
3556                return null;
3557            }
3558            app.crashHandler = crashHandler;
3559            checkTime(startTime, "startProcess: done creating new process record");
3560        } else {
3561            // If this is a new package in the process, add the package to the list
3562            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3563            checkTime(startTime, "startProcess: added package to existing proc");
3564        }
3565
3566        // If the system is not ready yet, then hold off on starting this
3567        // process until it is.
3568        if (!mProcessesReady
3569                && !isAllowedWhileBooting(info)
3570                && !allowWhileBooting) {
3571            if (!mProcessesOnHold.contains(app)) {
3572                mProcessesOnHold.add(app);
3573            }
3574            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3575                    "System not ready, putting on hold: " + app);
3576            checkTime(startTime, "startProcess: returning with proc on hold");
3577            return app;
3578        }
3579
3580        checkTime(startTime, "startProcess: stepping in to startProcess");
3581        startProcessLocked(
3582                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3583        checkTime(startTime, "startProcess: done starting proc!");
3584        return (app.pid != 0) ? app : null;
3585    }
3586
3587    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3588        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3589    }
3590
3591    private final void startProcessLocked(ProcessRecord app,
3592            String hostingType, String hostingNameStr) {
3593        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3594                null /* entryPoint */, null /* entryPointArgs */);
3595    }
3596
3597    private final void startProcessLocked(ProcessRecord app, String hostingType,
3598            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3599        long startTime = SystemClock.elapsedRealtime();
3600        if (app.pid > 0 && app.pid != MY_PID) {
3601            checkTime(startTime, "startProcess: removing from pids map");
3602            synchronized (mPidsSelfLocked) {
3603                mPidsSelfLocked.remove(app.pid);
3604                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3605            }
3606            checkTime(startTime, "startProcess: done removing from pids map");
3607            app.setPid(0);
3608        }
3609
3610        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3611                "startProcessLocked removing on hold: " + app);
3612        mProcessesOnHold.remove(app);
3613
3614        checkTime(startTime, "startProcess: starting to update cpu stats");
3615        updateCpuStats();
3616        checkTime(startTime, "startProcess: done updating cpu stats");
3617
3618        try {
3619            try {
3620                final int userId = UserHandle.getUserId(app.uid);
3621                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3622            } catch (RemoteException e) {
3623                throw e.rethrowAsRuntimeException();
3624            }
3625
3626            int uid = app.uid;
3627            int[] gids = null;
3628            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3629            if (!app.isolated) {
3630                int[] permGids = null;
3631                try {
3632                    checkTime(startTime, "startProcess: getting gids from package manager");
3633                    final IPackageManager pm = AppGlobals.getPackageManager();
3634                    permGids = pm.getPackageGids(app.info.packageName,
3635                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3636                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3637                            StorageManagerInternal.class);
3638                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3639                            app.info.packageName);
3640                } catch (RemoteException e) {
3641                    throw e.rethrowAsRuntimeException();
3642                }
3643
3644                /*
3645                 * Add shared application and profile GIDs so applications can share some
3646                 * resources like shared libraries and access user-wide resources
3647                 */
3648                if (ArrayUtils.isEmpty(permGids)) {
3649                    gids = new int[3];
3650                } else {
3651                    gids = new int[permGids.length + 3];
3652                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3653                }
3654                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3655                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3656                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3657            }
3658            checkTime(startTime, "startProcess: building args");
3659            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3660                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3661                        && mTopComponent != null
3662                        && app.processName.equals(mTopComponent.getPackageName())) {
3663                    uid = 0;
3664                }
3665                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3666                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3667                    uid = 0;
3668                }
3669            }
3670            int debugFlags = 0;
3671            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3672                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3673                // Also turn on CheckJNI for debuggable apps. It's quite
3674                // awkward to turn on otherwise.
3675                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3676            }
3677            // Run the app in safe mode if its manifest requests so or the
3678            // system is booted in safe mode.
3679            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3680                mSafeMode == true) {
3681                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3682            }
3683            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3684                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3685            }
3686            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3687            if ("true".equals(genDebugInfoProperty)) {
3688                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3689            }
3690            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3691                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3692            }
3693            if ("1".equals(SystemProperties.get("debug.assert"))) {
3694                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3695            }
3696            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3697                // Enable all debug flags required by the native debugger.
3698                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3699                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3700                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3701                mNativeDebuggingApp = null;
3702            }
3703
3704            String invokeWith = null;
3705            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3706                // Debuggable apps may include a wrapper script with their library directory.
3707                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3708                if (new File(wrapperFileName).exists()) {
3709                    invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3710                }
3711            }
3712
3713            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3714            if (requiredAbi == null) {
3715                requiredAbi = Build.SUPPORTED_ABIS[0];
3716            }
3717
3718            String instructionSet = null;
3719            if (app.info.primaryCpuAbi != null) {
3720                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3721            }
3722
3723            app.gids = gids;
3724            app.requiredAbi = requiredAbi;
3725            app.instructionSet = instructionSet;
3726
3727            // Start the process.  It will either succeed and return a result containing
3728            // the PID of the new process, or else throw a RuntimeException.
3729            boolean isActivityProcess = (entryPoint == null);
3730            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3731            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3732                    app.processName);
3733            checkTime(startTime, "startProcess: asking zygote to start proc");
3734            Process.ProcessStartResult startResult;
3735            if (hostingType.equals("webview_service")) {
3736                startResult = Process.startWebView(entryPoint,
3737                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3738                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3739                        app.info.dataDir, null, entryPointArgs);
3740            } else {
3741                startResult = Process.start(entryPoint,
3742                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3743                        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3744                        app.info.dataDir, invokeWith, entryPointArgs);
3745            }
3746            checkTime(startTime, "startProcess: returned from zygote!");
3747            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3748
3749            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3750            checkTime(startTime, "startProcess: done updating battery stats");
3751
3752            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3753                    UserHandle.getUserId(uid), startResult.pid, uid,
3754                    app.processName, hostingType,
3755                    hostingNameStr != null ? hostingNameStr : "");
3756
3757            try {
3758                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3759                        app.info.seinfo, app.info.sourceDir, startResult.pid);
3760            } catch (RemoteException ex) {
3761                // Ignore
3762            }
3763
3764            if (app.persistent) {
3765                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3766            }
3767
3768            checkTime(startTime, "startProcess: building log message");
3769            StringBuilder buf = mStringBuilder;
3770            buf.setLength(0);
3771            buf.append("Start proc ");
3772            buf.append(startResult.pid);
3773            buf.append(':');
3774            buf.append(app.processName);
3775            buf.append('/');
3776            UserHandle.formatUid(buf, uid);
3777            if (!isActivityProcess) {
3778                buf.append(" [");
3779                buf.append(entryPoint);
3780                buf.append("]");
3781            }
3782            buf.append(" for ");
3783            buf.append(hostingType);
3784            if (hostingNameStr != null) {
3785                buf.append(" ");
3786                buf.append(hostingNameStr);
3787            }
3788            Slog.i(TAG, buf.toString());
3789            app.setPid(startResult.pid);
3790            app.usingWrapper = startResult.usingWrapper;
3791            app.removed = false;
3792            app.killed = false;
3793            app.killedByAm = false;
3794            checkTime(startTime, "startProcess: starting to update pids map");
3795            ProcessRecord oldApp;
3796            synchronized (mPidsSelfLocked) {
3797                oldApp = mPidsSelfLocked.get(startResult.pid);
3798            }
3799            // If there is already an app occupying that pid that hasn't been cleaned up
3800            if (oldApp != null && !app.isolated) {
3801                // Clean up anything relating to this pid first
3802                Slog.w(TAG, "Reusing pid " + startResult.pid
3803                        + " while app is still mapped to it");
3804                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3805                        true /*replacingPid*/);
3806            }
3807            synchronized (mPidsSelfLocked) {
3808                this.mPidsSelfLocked.put(startResult.pid, app);
3809                if (isActivityProcess) {
3810                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3811                    msg.obj = app;
3812                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3813                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3814                }
3815            }
3816            checkTime(startTime, "startProcess: done updating pids map");
3817        } catch (RuntimeException e) {
3818            Slog.e(TAG, "Failure starting process " + app.processName, e);
3819
3820            // Something went very wrong while trying to start this process; one
3821            // common case is when the package is frozen due to an active
3822            // upgrade. To recover, clean up any active bookkeeping related to
3823            // starting this process. (We already invoked this method once when
3824            // the package was initially frozen through KILL_APPLICATION_MSG, so
3825            // it doesn't hurt to use it again.)
3826            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3827                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3828        }
3829    }
3830
3831    void updateUsageStats(ActivityRecord component, boolean resumed) {
3832        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3833                "updateUsageStats: comp=" + component + "res=" + resumed);
3834        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3835        if (resumed) {
3836            if (mUsageStatsService != null) {
3837                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3838                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3839            }
3840            synchronized (stats) {
3841                stats.noteActivityResumedLocked(component.app.uid);
3842            }
3843        } else {
3844            if (mUsageStatsService != null) {
3845                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3846                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3847            }
3848            synchronized (stats) {
3849                stats.noteActivityPausedLocked(component.app.uid);
3850            }
3851        }
3852    }
3853
3854    Intent getHomeIntent() {
3855        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3856        intent.setComponent(mTopComponent);
3857        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3858        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3859            intent.addCategory(Intent.CATEGORY_HOME);
3860        }
3861        return intent;
3862    }
3863
3864    boolean startHomeActivityLocked(int userId, String reason) {
3865        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3866                && mTopAction == null) {
3867            // We are running in factory test mode, but unable to find
3868            // the factory test app, so just sit around displaying the
3869            // error message and don't try to start anything.
3870            return false;
3871        }
3872        Intent intent = getHomeIntent();
3873        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3874        if (aInfo != null) {
3875            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3876            // Don't do this if the home app is currently being
3877            // instrumented.
3878            aInfo = new ActivityInfo(aInfo);
3879            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3880            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3881                    aInfo.applicationInfo.uid, true);
3882            if (app == null || app.instrumentationClass == null) {
3883                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3884                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3885            }
3886        } else {
3887            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3888        }
3889
3890        return true;
3891    }
3892
3893    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3894        ActivityInfo ai = null;
3895        ComponentName comp = intent.getComponent();
3896        try {
3897            if (comp != null) {
3898                // Factory test.
3899                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3900            } else {
3901                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3902                        intent,
3903                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3904                        flags, userId);
3905
3906                if (info != null) {
3907                    ai = info.activityInfo;
3908                }
3909            }
3910        } catch (RemoteException e) {
3911            // ignore
3912        }
3913
3914        return ai;
3915    }
3916
3917    /**
3918     * Starts the "new version setup screen" if appropriate.
3919     */
3920    void startSetupActivityLocked() {
3921        // Only do this once per boot.
3922        if (mCheckedForSetup) {
3923            return;
3924        }
3925
3926        // We will show this screen if the current one is a different
3927        // version than the last one shown, and we are not running in
3928        // low-level factory test mode.
3929        final ContentResolver resolver = mContext.getContentResolver();
3930        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3931                Settings.Global.getInt(resolver,
3932                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3933            mCheckedForSetup = true;
3934
3935            // See if we should be showing the platform update setup UI.
3936            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3937            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3938                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3939            if (!ris.isEmpty()) {
3940                final ResolveInfo ri = ris.get(0);
3941                String vers = ri.activityInfo.metaData != null
3942                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3943                        : null;
3944                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3945                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3946                            Intent.METADATA_SETUP_VERSION);
3947                }
3948                String lastVers = Settings.Secure.getString(
3949                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3950                if (vers != null && !vers.equals(lastVers)) {
3951                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3952                    intent.setComponent(new ComponentName(
3953                            ri.activityInfo.packageName, ri.activityInfo.name));
3954                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3955                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3956                            null, 0, 0, 0, null, false, false, null, null, null);
3957                }
3958            }
3959        }
3960    }
3961
3962    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3963        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3964    }
3965
3966    void enforceNotIsolatedCaller(String caller) {
3967        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3968            throw new SecurityException("Isolated process not allowed to call " + caller);
3969        }
3970    }
3971
3972    void enforceShellRestriction(String restriction, int userHandle) {
3973        if (Binder.getCallingUid() == Process.SHELL_UID) {
3974            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3975                throw new SecurityException("Shell does not have permission to access user "
3976                        + userHandle);
3977            }
3978        }
3979    }
3980
3981    @Override
3982    public int getFrontActivityScreenCompatMode() {
3983        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3984        synchronized (this) {
3985            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3986        }
3987    }
3988
3989    @Override
3990    public void setFrontActivityScreenCompatMode(int mode) {
3991        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3992                "setFrontActivityScreenCompatMode");
3993        synchronized (this) {
3994            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3995        }
3996    }
3997
3998    @Override
3999    public int getPackageScreenCompatMode(String packageName) {
4000        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4001        synchronized (this) {
4002            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4003        }
4004    }
4005
4006    @Override
4007    public void setPackageScreenCompatMode(String packageName, int mode) {
4008        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4009                "setPackageScreenCompatMode");
4010        synchronized (this) {
4011            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4012        }
4013    }
4014
4015    @Override
4016    public boolean getPackageAskScreenCompat(String packageName) {
4017        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4018        synchronized (this) {
4019            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4020        }
4021    }
4022
4023    @Override
4024    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4025        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4026                "setPackageAskScreenCompat");
4027        synchronized (this) {
4028            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4029        }
4030    }
4031
4032    private boolean hasUsageStatsPermission(String callingPackage) {
4033        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4034                Binder.getCallingUid(), callingPackage);
4035        if (mode == AppOpsManager.MODE_DEFAULT) {
4036            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4037                    == PackageManager.PERMISSION_GRANTED;
4038        }
4039        return mode == AppOpsManager.MODE_ALLOWED;
4040    }
4041
4042    @Override
4043    public int getPackageProcessState(String packageName, String callingPackage) {
4044        if (!hasUsageStatsPermission(callingPackage)) {
4045            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4046                    "getPackageProcessState");
4047        }
4048
4049        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4050        synchronized (this) {
4051            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4052                final ProcessRecord proc = mLruProcesses.get(i);
4053                if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4054                        || procState > proc.setProcState) {
4055                    if (proc.pkgList.containsKey(packageName)) {
4056                        procState = proc.setProcState;
4057                        break;
4058                    }
4059                    if (proc.pkgDeps != null && proc.pkgDeps.contains(packageName)) {
4060                        procState = proc.setProcState;
4061                    }
4062                }
4063            }
4064        }
4065        return procState;
4066    }
4067
4068    @Override
4069    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4070            throws RemoteException {
4071        synchronized (this) {
4072            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4073            if (app == null) {
4074                throw new IllegalArgumentException("Unknown process: " + process);
4075            }
4076            if (app.thread == null) {
4077                throw new IllegalArgumentException("Process has no app thread");
4078            }
4079            if (app.trimMemoryLevel >= level) {
4080                throw new IllegalArgumentException(
4081                        "Unable to set a higher trim level than current level");
4082            }
4083            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4084                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4085                throw new IllegalArgumentException("Unable to set a background trim level "
4086                    + "on a foreground process");
4087            }
4088            app.thread.scheduleTrimMemory(level);
4089            app.trimMemoryLevel = level;
4090            return true;
4091        }
4092    }
4093
4094    private void dispatchProcessesChanged() {
4095        int N;
4096        synchronized (this) {
4097            N = mPendingProcessChanges.size();
4098            if (mActiveProcessChanges.length < N) {
4099                mActiveProcessChanges = new ProcessChangeItem[N];
4100            }
4101            mPendingProcessChanges.toArray(mActiveProcessChanges);
4102            mPendingProcessChanges.clear();
4103            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4104                    "*** Delivering " + N + " process changes");
4105        }
4106
4107        int i = mProcessObservers.beginBroadcast();
4108        while (i > 0) {
4109            i--;
4110            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4111            if (observer != null) {
4112                try {
4113                    for (int j=0; j<N; j++) {
4114                        ProcessChangeItem item = mActiveProcessChanges[j];
4115                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4116                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4117                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4118                                    + item.uid + ": " + item.foregroundActivities);
4119                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4120                                    item.foregroundActivities);
4121                        }
4122                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4123                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4124                                    "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4125                                    + ": " + item.processState);
4126                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4127                        }
4128                    }
4129                } catch (RemoteException e) {
4130                }
4131            }
4132        }
4133        mProcessObservers.finishBroadcast();
4134
4135        synchronized (this) {
4136            for (int j=0; j<N; j++) {
4137                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4138            }
4139        }
4140    }
4141
4142    private void dispatchProcessDied(int pid, int uid) {
4143        int i = mProcessObservers.beginBroadcast();
4144        while (i > 0) {
4145            i--;
4146            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4147            if (observer != null) {
4148                try {
4149                    observer.onProcessDied(pid, uid);
4150                } catch (RemoteException e) {
4151                }
4152            }
4153        }
4154        mProcessObservers.finishBroadcast();
4155    }
4156
4157    private void dispatchUidsChanged() {
4158        int N;
4159        synchronized (this) {
4160            N = mPendingUidChanges.size();
4161            if (mActiveUidChanges.length < N) {
4162                mActiveUidChanges = new UidRecord.ChangeItem[N];
4163            }
4164            for (int i=0; i<N; i++) {
4165                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4166                mActiveUidChanges[i] = change;
4167                if (change.uidRecord != null) {
4168                    change.uidRecord.pendingChange = null;
4169                    change.uidRecord = null;
4170                }
4171            }
4172            mPendingUidChanges.clear();
4173            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4174                    "*** Delivering " + N + " uid changes");
4175        }
4176
4177        int i = mUidObservers.beginBroadcast();
4178        while (i > 0) {
4179            i--;
4180            final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4181            final UidObserverRegistration reg = (UidObserverRegistration)
4182                    mUidObservers.getBroadcastCookie(i);
4183            if (observer != null) {
4184                try {
4185                    for (int j=0; j<N; j++) {
4186                        UidRecord.ChangeItem item = mActiveUidChanges[j];
4187                        final int change = item.change;
4188                        UidRecord validateUid = null;
4189                        if (VALIDATE_UID_STATES && i == 0) {
4190                            validateUid = mValidateUids.get(item.uid);
4191                            if (validateUid == null && change != UidRecord.CHANGE_GONE
4192                                    && change != UidRecord.CHANGE_GONE_IDLE) {
4193                                validateUid = new UidRecord(item.uid);
4194                                mValidateUids.put(item.uid, validateUid);
4195                            }
4196                        }
4197                        if (change == UidRecord.CHANGE_IDLE
4198                                || change == UidRecord.CHANGE_GONE_IDLE) {
4199                            if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4200                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4201                                        "UID idle uid=" + item.uid);
4202                                observer.onUidIdle(item.uid, item.ephemeral);
4203                            }
4204                            if (VALIDATE_UID_STATES && i == 0) {
4205                                if (validateUid != null) {
4206                                    validateUid.idle = true;
4207                                }
4208                            }
4209                        } else if (change == UidRecord.CHANGE_ACTIVE) {
4210                            if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4211                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4212                                        "UID active uid=" + item.uid);
4213                                observer.onUidActive(item.uid);
4214                            }
4215                            if (VALIDATE_UID_STATES && i == 0) {
4216                                validateUid.idle = false;
4217                            }
4218                        }
4219                        if (change == UidRecord.CHANGE_GONE
4220                                || change == UidRecord.CHANGE_GONE_IDLE) {
4221                            if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4222                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4223                                        "UID gone uid=" + item.uid);
4224                                observer.onUidGone(item.uid, item.ephemeral);
4225                            }
4226                            if (reg.lastProcStates != null) {
4227                                reg.lastProcStates.delete(item.uid);
4228                            }
4229                            if (VALIDATE_UID_STATES && i == 0) {
4230                                if (validateUid != null) {
4231                                    mValidateUids.remove(item.uid);
4232                                }
4233                            }
4234                        } else {
4235                            if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4236                                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4237                                        "UID CHANGED uid=" + item.uid
4238                                                + ": " + item.processState);
4239                                boolean doReport = true;
4240                                if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4241                                    final int lastState = reg.lastProcStates.get(item.uid,
4242                                            ActivityManager.PROCESS_STATE_UNKNOWN);
4243                                    if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4244                                        final boolean lastAboveCut = lastState <= reg.cutpoint;
4245                                        final boolean newAboveCut = item.processState <= reg.cutpoint;
4246                                        doReport = lastAboveCut != newAboveCut;
4247                                    } else {
4248                                        doReport = item.processState
4249                                                != ActivityManager.PROCESS_STATE_NONEXISTENT;
4250                                    }
4251                                }
4252                                if (doReport) {
4253                                    if (reg.lastProcStates != null) {
4254                                        reg.lastProcStates.put(item.uid, item.processState);
4255                                    }
4256                                    observer.onUidStateChanged(item.uid, item.processState);
4257                                }
4258                            }
4259                            if (VALIDATE_UID_STATES && i == 0) {
4260                                validateUid.curProcState = validateUid.setProcState
4261                                        = item.processState;
4262                            }
4263                        }
4264                    }
4265                } catch (RemoteException e) {
4266                }
4267            }
4268        }
4269        mUidObservers.finishBroadcast();
4270
4271        synchronized (this) {
4272            for (int j=0; j<N; j++) {
4273                mAvailUidChanges.add(mActiveUidChanges[j]);
4274            }
4275        }
4276    }
4277
4278    @Override
4279    public final int startActivity(IApplicationThread caller, String callingPackage,
4280            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4281            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4282        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4283                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4284                UserHandle.getCallingUserId());
4285    }
4286
4287    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4288        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4289        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4290                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4291                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4292
4293        // TODO: Switch to user app stacks here.
4294        String mimeType = intent.getType();
4295        final Uri data = intent.getData();
4296        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4297            mimeType = getProviderMimeType(data, userId);
4298        }
4299        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4300
4301        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4302        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4303                null, 0, 0, null, null, null, null, false, userId, container, null);
4304    }
4305
4306    @Override
4307    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4308            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4309            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4310        enforceNotIsolatedCaller("startActivity");
4311        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4312                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4313        // TODO: Switch to user app stacks here.
4314        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4315                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4316                profilerInfo, null, null, bOptions, false, userId, null, null);
4317    }
4318
4319    @Override
4320    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4321            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4322            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4323            int userId) {
4324
4325        // This is very dangerous -- it allows you to perform a start activity (including
4326        // permission grants) as any app that may launch one of your own activities.  So
4327        // we will only allow this to be done from activities that are part of the core framework,
4328        // and then only when they are running as the system.
4329        final ActivityRecord sourceRecord;
4330        final int targetUid;
4331        final String targetPackage;
4332        synchronized (this) {
4333            if (resultTo == null) {
4334                throw new SecurityException("Must be called from an activity");
4335            }
4336            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4337            if (sourceRecord == null) {
4338                throw new SecurityException("Called with bad activity token: " + resultTo);
4339            }
4340            if (!sourceRecord.info.packageName.equals("android")) {
4341                throw new SecurityException(
4342                        "Must be called from an activity that is declared in the android package");
4343            }
4344            if (sourceRecord.app == null) {
4345                throw new SecurityException("Called without a process attached to activity");
4346            }
4347            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4348                // This is still okay, as long as this activity is running under the
4349                // uid of the original calling activity.
4350                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4351                    throw new SecurityException(
4352                            "Calling activity in uid " + sourceRecord.app.uid
4353                                    + " must be system uid or original calling uid "
4354                                    + sourceRecord.launchedFromUid);
4355                }
4356            }
4357            if (ignoreTargetSecurity) {
4358                if (intent.getComponent() == null) {
4359                    throw new SecurityException(
4360                            "Component must be specified with ignoreTargetSecurity");
4361                }
4362                if (intent.getSelector() != null) {
4363                    throw new SecurityException(
4364                            "Selector not allowed with ignoreTargetSecurity");
4365                }
4366            }
4367            targetUid = sourceRecord.launchedFromUid;
4368            targetPackage = sourceRecord.launchedFromPackage;
4369        }
4370
4371        if (userId == UserHandle.USER_NULL) {
4372            userId = UserHandle.getUserId(sourceRecord.app.uid);
4373        }
4374
4375        // TODO: Switch to user app stacks here.
4376        try {
4377            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4378                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4379                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4380            return ret;
4381        } catch (SecurityException e) {
4382            // XXX need to figure out how to propagate to original app.
4383            // A SecurityException here is generally actually a fault of the original
4384            // calling activity (such as a fairly granting permissions), so propagate it
4385            // back to them.
4386            /*
4387            StringBuilder msg = new StringBuilder();
4388            msg.append("While launching");
4389            msg.append(intent.toString());
4390            msg.append(": ");
4391            msg.append(e.getMessage());
4392            */
4393            throw e;
4394        }
4395    }
4396
4397    @Override
4398    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4399            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4400            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4401        enforceNotIsolatedCaller("startActivityAndWait");
4402        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4403                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4404        WaitResult res = new WaitResult();
4405        // TODO: Switch to user app stacks here.
4406        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4407                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4408                bOptions, false, userId, null, null);
4409        return res;
4410    }
4411
4412    @Override
4413    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4414            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4415            int startFlags, Configuration config, Bundle bOptions, int userId) {
4416        enforceNotIsolatedCaller("startActivityWithConfig");
4417        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4418                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4419        // TODO: Switch to user app stacks here.
4420        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4421                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4422                null, null, config, bOptions, false, userId, null, null);
4423        return ret;
4424    }
4425
4426    @Override
4427    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4428            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4429            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4430            throws TransactionTooLargeException {
4431        enforceNotIsolatedCaller("startActivityIntentSender");
4432        // Refuse possible leaked file descriptors
4433        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4434            throw new IllegalArgumentException("File descriptors passed in Intent");
4435        }
4436
4437        IIntentSender sender = intent.getTarget();
4438        if (!(sender instanceof PendingIntentRecord)) {
4439            throw new IllegalArgumentException("Bad PendingIntent object");
4440        }
4441
4442        PendingIntentRecord pir = (PendingIntentRecord)sender;
4443
4444        synchronized (this) {
4445            // If this is coming from the currently resumed activity, it is
4446            // effectively saying that app switches are allowed at this point.
4447            final ActivityStack stack = getFocusedStack();
4448            if (stack.mResumedActivity != null &&
4449                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4450                mAppSwitchesAllowedTime = 0;
4451            }
4452        }
4453        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4454                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4455        return ret;
4456    }
4457
4458    @Override
4459    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4460            Intent intent, String resolvedType, IVoiceInteractionSession session,
4461            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4462            Bundle bOptions, int userId) {
4463        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4464                != PackageManager.PERMISSION_GRANTED) {
4465            String msg = "Permission Denial: startVoiceActivity() from pid="
4466                    + Binder.getCallingPid()
4467                    + ", uid=" + Binder.getCallingUid()
4468                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4469            Slog.w(TAG, msg);
4470            throw new SecurityException(msg);
4471        }
4472        if (session == null || interactor == null) {
4473            throw new NullPointerException("null session or interactor");
4474        }
4475        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4476                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4477        // TODO: Switch to user app stacks here.
4478        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4479                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4480                null, bOptions, false, userId, null, null);
4481    }
4482
4483    @Override
4484    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4485            throws RemoteException {
4486        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4487        synchronized (this) {
4488            ActivityRecord activity = getFocusedStack().topActivity();
4489            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4490                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4491            }
4492            if (mRunningVoice != null || activity.task.voiceSession != null
4493                    || activity.voiceSession != null) {
4494                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4495                return;
4496            }
4497            if (activity.pendingVoiceInteractionStart) {
4498                Slog.w(TAG, "Pending start of voice interaction already.");
4499                return;
4500            }
4501            activity.pendingVoiceInteractionStart = true;
4502        }
4503        LocalServices.getService(VoiceInteractionManagerInternal.class)
4504                .startLocalVoiceInteraction(callingActivity, options);
4505    }
4506
4507    @Override
4508    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4509        LocalServices.getService(VoiceInteractionManagerInternal.class)
4510                .stopLocalVoiceInteraction(callingActivity);
4511    }
4512
4513    @Override
4514    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4515        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4516                .supportsLocalVoiceInteraction();
4517    }
4518
4519    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4520            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4521        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4522        if (activityToCallback == null) return;
4523        activityToCallback.setVoiceSessionLocked(voiceSession);
4524
4525        // Inform the activity
4526        try {
4527            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4528                    voiceInteractor);
4529            long token = Binder.clearCallingIdentity();
4530            try {
4531                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4532            } finally {
4533                Binder.restoreCallingIdentity(token);
4534            }
4535            // TODO: VI Should we cache the activity so that it's easier to find later
4536            // rather than scan through all the stacks and activities?
4537        } catch (RemoteException re) {
4538            activityToCallback.clearVoiceSessionLocked();
4539            // TODO: VI Should this terminate the voice session?
4540        }
4541    }
4542
4543    @Override
4544    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4545        synchronized (this) {
4546            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4547                if (keepAwake) {
4548                    mVoiceWakeLock.acquire();
4549                } else {
4550                    mVoiceWakeLock.release();
4551                }
4552            }
4553        }
4554    }
4555
4556    @Override
4557    public boolean startNextMatchingActivity(IBinder callingActivity,
4558            Intent intent, Bundle bOptions) {
4559        // Refuse possible leaked file descriptors
4560        if (intent != null && intent.hasFileDescriptors() == true) {
4561            throw new IllegalArgumentException("File descriptors passed in Intent");
4562        }
4563        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4564
4565        synchronized (this) {
4566            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4567            if (r == null) {
4568                ActivityOptions.abort(options);
4569                return false;
4570            }
4571            if (r.app == null || r.app.thread == null) {
4572                // The caller is not running...  d'oh!
4573                ActivityOptions.abort(options);
4574                return false;
4575            }
4576            intent = new Intent(intent);
4577            // The caller is not allowed to change the data.
4578            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4579            // And we are resetting to find the next component...
4580            intent.setComponent(null);
4581
4582            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4583
4584            ActivityInfo aInfo = null;
4585            try {
4586                List<ResolveInfo> resolves =
4587                    AppGlobals.getPackageManager().queryIntentActivities(
4588                            intent, r.resolvedType,
4589                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4590                            UserHandle.getCallingUserId()).getList();
4591
4592                // Look for the original activity in the list...
4593                final int N = resolves != null ? resolves.size() : 0;
4594                for (int i=0; i<N; i++) {
4595                    ResolveInfo rInfo = resolves.get(i);
4596                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4597                            && rInfo.activityInfo.name.equals(r.info.name)) {
4598                        // We found the current one...  the next matching is
4599                        // after it.
4600                        i++;
4601                        if (i<N) {
4602                            aInfo = resolves.get(i).activityInfo;
4603                        }
4604                        if (debug) {
4605                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4606                                    + "/" + r.info.name);
4607                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4608                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4609                        }
4610                        break;
4611                    }
4612                }
4613            } catch (RemoteException e) {
4614            }
4615
4616            if (aInfo == null) {
4617                // Nobody who is next!
4618                ActivityOptions.abort(options);
4619                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4620                return false;
4621            }
4622
4623            intent.setComponent(new ComponentName(
4624                    aInfo.applicationInfo.packageName, aInfo.name));
4625            intent.setFlags(intent.getFlags()&~(
4626                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4627                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4628                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4629                    Intent.FLAG_ACTIVITY_NEW_TASK));
4630
4631            // Okay now we need to start the new activity, replacing the
4632            // currently running activity.  This is a little tricky because
4633            // we want to start the new one as if the current one is finished,
4634            // but not finish the current one first so that there is no flicker.
4635            // And thus...
4636            final boolean wasFinishing = r.finishing;
4637            r.finishing = true;
4638
4639            // Propagate reply information over to the new activity.
4640            final ActivityRecord resultTo = r.resultTo;
4641            final String resultWho = r.resultWho;
4642            final int requestCode = r.requestCode;
4643            r.resultTo = null;
4644            if (resultTo != null) {
4645                resultTo.removeResultsLocked(r, resultWho, requestCode);
4646            }
4647
4648            final long origId = Binder.clearCallingIdentity();
4649            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4650                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4651                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4652                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4653                    false, false, null, null, null);
4654            Binder.restoreCallingIdentity(origId);
4655
4656            r.finishing = wasFinishing;
4657            if (res != ActivityManager.START_SUCCESS) {
4658                return false;
4659            }
4660            return true;
4661        }
4662    }
4663
4664    @Override
4665    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4666        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4667            String msg = "Permission Denial: startActivityFromRecents called without " +
4668                    START_TASKS_FROM_RECENTS;
4669            Slog.w(TAG, msg);
4670            throw new SecurityException(msg);
4671        }
4672        final long origId = Binder.clearCallingIdentity();
4673        try {
4674            synchronized (this) {
4675                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4676            }
4677        } finally {
4678            Binder.restoreCallingIdentity(origId);
4679        }
4680    }
4681
4682    final int startActivityInPackage(int uid, String callingPackage,
4683            Intent intent, String resolvedType, IBinder resultTo,
4684            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4685            IActivityContainer container, TaskRecord inTask) {
4686
4687        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4688                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4689
4690        // TODO: Switch to user app stacks here.
4691        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4692                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4693                null, null, null, bOptions, false, userId, container, inTask);
4694        return ret;
4695    }
4696
4697    @Override
4698    public final int startActivities(IApplicationThread caller, String callingPackage,
4699            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4700            int userId) {
4701        enforceNotIsolatedCaller("startActivities");
4702        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4703                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4704        // TODO: Switch to user app stacks here.
4705        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4706                resolvedTypes, resultTo, bOptions, userId);
4707        return ret;
4708    }
4709
4710    final int startActivitiesInPackage(int uid, String callingPackage,
4711            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4712            Bundle bOptions, int userId) {
4713
4714        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4715                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4716        // TODO: Switch to user app stacks here.
4717        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4718                resultTo, bOptions, userId);
4719        return ret;
4720    }
4721
4722    @Override
4723    public void reportActivityFullyDrawn(IBinder token) {
4724        synchronized (this) {
4725            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4726            if (r == null) {
4727                return;
4728            }
4729            r.reportFullyDrawnLocked();
4730        }
4731    }
4732
4733    @Override
4734    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4735        synchronized (this) {
4736            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4737            if (r == null) {
4738                return;
4739            }
4740            final long origId = Binder.clearCallingIdentity();
4741            try {
4742                r.setRequestedOrientation(requestedOrientation);
4743            } finally {
4744                Binder.restoreCallingIdentity(origId);
4745            }
4746        }
4747    }
4748
4749    @Override
4750    public int getRequestedOrientation(IBinder token) {
4751        synchronized (this) {
4752            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4753            if (r == null) {
4754                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4755            }
4756            return r.getRequestedOrientation();
4757        }
4758    }
4759
4760    @Override
4761    public final void requestActivityRelaunch(IBinder token) {
4762        synchronized(this) {
4763            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4764            if (r == null) {
4765                return;
4766            }
4767            final long origId = Binder.clearCallingIdentity();
4768            try {
4769                r.forceNewConfig = true;
4770                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
4771                        false /* preserveWindow */);
4772            } finally {
4773                Binder.restoreCallingIdentity(origId);
4774            }
4775        }
4776    }
4777
4778    /**
4779     * This is the internal entry point for handling Activity.finish().
4780     *
4781     * @param token The Binder token referencing the Activity we want to finish.
4782     * @param resultCode Result code, if any, from this Activity.
4783     * @param resultData Result data (Intent), if any, from this Activity.
4784     * @param finishTask Whether to finish the task associated with this Activity.
4785     *
4786     * @return Returns true if the activity successfully finished, or false if it is still running.
4787     */
4788    @Override
4789    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4790            int finishTask) {
4791        // Refuse possible leaked file descriptors
4792        if (resultData != null && resultData.hasFileDescriptors() == true) {
4793            throw new IllegalArgumentException("File descriptors passed in Intent");
4794        }
4795
4796        synchronized(this) {
4797            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4798            if (r == null) {
4799                return true;
4800            }
4801            // Keep track of the root activity of the task before we finish it
4802            TaskRecord tr = r.task;
4803            ActivityRecord rootR = tr.getRootActivity();
4804            if (rootR == null) {
4805                Slog.w(TAG, "Finishing task with all activities already finished");
4806            }
4807            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4808            // finish.
4809            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4810                    mStackSupervisor.isLastLockedTask(tr)) {
4811                Slog.i(TAG, "Not finishing task in lock task mode");
4812                mStackSupervisor.showLockTaskToast();
4813                return false;
4814            }
4815            if (mController != null) {
4816                // Find the first activity that is not finishing.
4817                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
4818                if (next != null) {
4819                    // ask watcher if this is allowed
4820                    boolean resumeOK = true;
4821                    try {
4822                        resumeOK = mController.activityResuming(next.packageName);
4823                    } catch (RemoteException e) {
4824                        mController = null;
4825                        Watchdog.getInstance().setActivityController(null);
4826                    }
4827
4828                    if (!resumeOK) {
4829                        Slog.i(TAG, "Not finishing activity because controller resumed");
4830                        return false;
4831                    }
4832                }
4833            }
4834            final long origId = Binder.clearCallingIdentity();
4835            try {
4836                boolean res;
4837                final boolean finishWithRootActivity =
4838                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4839                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4840                        || (finishWithRootActivity && r == rootR)) {
4841                    // If requested, remove the task that is associated to this activity only if it
4842                    // was the root activity in the task. The result code and data is ignored
4843                    // because we don't support returning them across task boundaries. Also, to
4844                    // keep backwards compatibility we remove the task from recents when finishing
4845                    // task with root activity.
4846                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4847                    if (!res) {
4848                        Slog.i(TAG, "Removing task failed to finish activity");
4849                    }
4850                } else {
4851                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
4852                            resultData, "app-request", true);
4853                    if (!res) {
4854                        Slog.i(TAG, "Failed to finish by app-request");
4855                    }
4856                }
4857                return res;
4858            } finally {
4859                Binder.restoreCallingIdentity(origId);
4860            }
4861        }
4862    }
4863
4864    @Override
4865    public final void finishHeavyWeightApp() {
4866        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4867                != PackageManager.PERMISSION_GRANTED) {
4868            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4869                    + Binder.getCallingPid()
4870                    + ", uid=" + Binder.getCallingUid()
4871                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4872            Slog.w(TAG, msg);
4873            throw new SecurityException(msg);
4874        }
4875
4876        synchronized(this) {
4877            if (mHeavyWeightProcess == null) {
4878                return;
4879            }
4880
4881            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4882            for (int i = 0; i < activities.size(); i++) {
4883                ActivityRecord r = activities.get(i);
4884                if (!r.finishing && r.isInStackLocked()) {
4885                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
4886                            null, "finish-heavy", true);
4887                }
4888            }
4889
4890            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4891                    mHeavyWeightProcess.userId, 0));
4892            mHeavyWeightProcess = null;
4893        }
4894    }
4895
4896    @Override
4897    public void crashApplication(int uid, int initialPid, String packageName,
4898            String message) {
4899        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4900                != PackageManager.PERMISSION_GRANTED) {
4901            String msg = "Permission Denial: crashApplication() from pid="
4902                    + Binder.getCallingPid()
4903                    + ", uid=" + Binder.getCallingUid()
4904                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4905            Slog.w(TAG, msg);
4906            throw new SecurityException(msg);
4907        }
4908
4909        synchronized(this) {
4910            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4911        }
4912    }
4913
4914    @Override
4915    public final void finishSubActivity(IBinder token, String resultWho,
4916            int requestCode) {
4917        synchronized(this) {
4918            final long origId = Binder.clearCallingIdentity();
4919            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4920            if (r != null) {
4921                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
4922            }
4923            Binder.restoreCallingIdentity(origId);
4924        }
4925    }
4926
4927    @Override
4928    public boolean finishActivityAffinity(IBinder token) {
4929        synchronized(this) {
4930            final long origId = Binder.clearCallingIdentity();
4931            try {
4932                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4933                if (r == null) {
4934                    return false;
4935                }
4936
4937                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4938                // can finish.
4939                final TaskRecord task = r.task;
4940                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4941                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4942                    mStackSupervisor.showLockTaskToast();
4943                    return false;
4944                }
4945                return task.getStack().finishActivityAffinityLocked(r);
4946            } finally {
4947                Binder.restoreCallingIdentity(origId);
4948            }
4949        }
4950    }
4951
4952    @Override
4953    public void finishVoiceTask(IVoiceInteractionSession session) {
4954        synchronized (this) {
4955            final long origId = Binder.clearCallingIdentity();
4956            try {
4957                // TODO: VI Consider treating local voice interactions and voice tasks
4958                // differently here
4959                mStackSupervisor.finishVoiceTask(session);
4960            } finally {
4961                Binder.restoreCallingIdentity(origId);
4962            }
4963        }
4964
4965    }
4966
4967    @Override
4968    public boolean releaseActivityInstance(IBinder token) {
4969        synchronized(this) {
4970            final long origId = Binder.clearCallingIdentity();
4971            try {
4972                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4973                if (r == null) {
4974                    return false;
4975                }
4976                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
4977            } finally {
4978                Binder.restoreCallingIdentity(origId);
4979            }
4980        }
4981    }
4982
4983    @Override
4984    public void releaseSomeActivities(IApplicationThread appInt) {
4985        synchronized(this) {
4986            final long origId = Binder.clearCallingIdentity();
4987            try {
4988                ProcessRecord app = getRecordForAppLocked(appInt);
4989                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4990            } finally {
4991                Binder.restoreCallingIdentity(origId);
4992            }
4993        }
4994    }
4995
4996    @Override
4997    public boolean willActivityBeVisible(IBinder token) {
4998        synchronized(this) {
4999            ActivityStack stack = ActivityRecord.getStackLocked(token);
5000            if (stack != null) {
5001                return stack.willActivityBeVisibleLocked(token);
5002            }
5003            return false;
5004        }
5005    }
5006
5007    @Override
5008    public void overridePendingTransition(IBinder token, String packageName,
5009            int enterAnim, int exitAnim) {
5010        synchronized(this) {
5011            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5012            if (self == null) {
5013                return;
5014            }
5015
5016            final long origId = Binder.clearCallingIdentity();
5017
5018            if (self.state == ActivityState.RESUMED
5019                    || self.state == ActivityState.PAUSING) {
5020                mWindowManager.overridePendingAppTransition(packageName,
5021                        enterAnim, exitAnim, null);
5022            }
5023
5024            Binder.restoreCallingIdentity(origId);
5025        }
5026    }
5027
5028    /**
5029     * Main function for removing an existing process from the activity manager
5030     * as a result of that process going away.  Clears out all connections
5031     * to the process.
5032     */
5033    private final void handleAppDiedLocked(ProcessRecord app,
5034            boolean restarting, boolean allowRestart) {
5035        int pid = app.pid;
5036        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5037                false /*replacingPid*/);
5038        if (!kept && !restarting) {
5039            removeLruProcessLocked(app);
5040            if (pid > 0) {
5041                ProcessList.remove(pid);
5042            }
5043        }
5044
5045        if (mProfileProc == app) {
5046            clearProfilerLocked();
5047        }
5048
5049        // Remove this application's activities from active lists.
5050        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5051
5052        app.activities.clear();
5053
5054        if (app.instrumentationClass != null) {
5055            Slog.w(TAG, "Crash of app " + app.processName
5056                  + " running instrumentation " + app.instrumentationClass);
5057            Bundle info = new Bundle();
5058            info.putString("shortMsg", "Process crashed.");
5059            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5060        }
5061
5062        mWindowManager.deferSurfaceLayout();
5063        try {
5064            if (!restarting && hasVisibleActivities
5065                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5066                // If there was nothing to resume, and we are not already restarting this process, but
5067                // there is a visible activity that is hosted by the process...  then make sure all
5068                // visible activities are running, taking care of restarting this process.
5069                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5070            }
5071        } finally {
5072            mWindowManager.continueSurfaceLayout();
5073        }
5074    }
5075
5076    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5077        IBinder threadBinder = thread.asBinder();
5078        // Find the application record.
5079        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5080            ProcessRecord rec = mLruProcesses.get(i);
5081            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5082                return i;
5083            }
5084        }
5085        return -1;
5086    }
5087
5088    final ProcessRecord getRecordForAppLocked(
5089            IApplicationThread thread) {
5090        if (thread == null) {
5091            return null;
5092        }
5093
5094        int appIndex = getLRURecordIndexForAppLocked(thread);
5095        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5096    }
5097
5098    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5099        // If there are no longer any background processes running,
5100        // and the app that died was not running instrumentation,
5101        // then tell everyone we are now low on memory.
5102        boolean haveBg = false;
5103        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5104            ProcessRecord rec = mLruProcesses.get(i);
5105            if (rec.thread != null
5106                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5107                haveBg = true;
5108                break;
5109            }
5110        }
5111
5112        if (!haveBg) {
5113            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5114            if (doReport) {
5115                long now = SystemClock.uptimeMillis();
5116                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5117                    doReport = false;
5118                } else {
5119                    mLastMemUsageReportTime = now;
5120                }
5121            }
5122            final ArrayList<ProcessMemInfo> memInfos
5123                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5124            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5125            long now = SystemClock.uptimeMillis();
5126            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5127                ProcessRecord rec = mLruProcesses.get(i);
5128                if (rec == dyingProc || rec.thread == null) {
5129                    continue;
5130                }
5131                if (doReport) {
5132                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5133                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5134                }
5135                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5136                    // The low memory report is overriding any current
5137                    // state for a GC request.  Make sure to do
5138                    // heavy/important/visible/foreground processes first.
5139                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5140                        rec.lastRequestedGc = 0;
5141                    } else {
5142                        rec.lastRequestedGc = rec.lastLowMemory;
5143                    }
5144                    rec.reportLowMemory = true;
5145                    rec.lastLowMemory = now;
5146                    mProcessesToGc.remove(rec);
5147                    addProcessToGcListLocked(rec);
5148                }
5149            }
5150            if (doReport) {
5151                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5152                mHandler.sendMessage(msg);
5153            }
5154            scheduleAppGcsLocked();
5155        }
5156    }
5157
5158    final void appDiedLocked(ProcessRecord app) {
5159       appDiedLocked(app, app.pid, app.thread, false);
5160    }
5161
5162    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5163            boolean fromBinderDied) {
5164        // First check if this ProcessRecord is actually active for the pid.
5165        synchronized (mPidsSelfLocked) {
5166            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5167            if (curProc != app) {
5168                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5169                return;
5170            }
5171        }
5172
5173        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5174        synchronized (stats) {
5175            stats.noteProcessDiedLocked(app.info.uid, pid);
5176        }
5177
5178        if (!app.killed) {
5179            if (!fromBinderDied) {
5180                Process.killProcessQuiet(pid);
5181            }
5182            killProcessGroup(app.uid, pid);
5183            app.killed = true;
5184        }
5185
5186        // Clean up already done if the process has been re-started.
5187        if (app.pid == pid && app.thread != null &&
5188                app.thread.asBinder() == thread.asBinder()) {
5189            boolean doLowMem = app.instrumentationClass == null;
5190            boolean doOomAdj = doLowMem;
5191            if (!app.killedByAm) {
5192                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5193                        + ") has died");
5194                mAllowLowerMemLevel = true;
5195            } else {
5196                // Note that we always want to do oom adj to update our state with the
5197                // new number of procs.
5198                mAllowLowerMemLevel = false;
5199                doLowMem = false;
5200            }
5201            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5202            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5203                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5204            handleAppDiedLocked(app, false, true);
5205
5206            if (doOomAdj) {
5207                updateOomAdjLocked();
5208            }
5209            if (doLowMem) {
5210                doLowMemReportIfNeededLocked(app);
5211            }
5212        } else if (app.pid != pid) {
5213            // A new process has already been started.
5214            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5215                    + ") has died and restarted (pid " + app.pid + ").");
5216            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5217        } else if (DEBUG_PROCESSES) {
5218            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5219                    + thread.asBinder());
5220        }
5221    }
5222
5223    /**
5224     * If a stack trace dump file is configured, dump process stack traces.
5225     * @param clearTraces causes the dump file to be erased prior to the new
5226     *    traces being written, if true; when false, the new traces will be
5227     *    appended to any existing file content.
5228     * @param firstPids of dalvik VM processes to dump stack traces for first
5229     * @param lastPids of dalvik VM processes to dump stack traces for last
5230     * @param nativeProcs optional list of native process names to dump stack crawls
5231     * @return file containing stack traces, or null if no dump file is configured
5232     */
5233    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5234            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5235        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5236        if (tracesPath == null || tracesPath.length() == 0) {
5237            return null;
5238        }
5239
5240        File tracesFile = new File(tracesPath);
5241        try {
5242            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5243            tracesFile.createNewFile();
5244            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5245        } catch (IOException e) {
5246            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5247            return null;
5248        }
5249
5250        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5251        return tracesFile;
5252    }
5253
5254    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5255            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5256        // Use a FileObserver to detect when traces finish writing.
5257        // The order of traces is considered important to maintain for legibility.
5258        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5259            @Override
5260            public synchronized void onEvent(int event, String path) { notify(); }
5261        };
5262
5263        try {
5264            observer.startWatching();
5265
5266            // First collect all of the stacks of the most important pids.
5267            if (firstPids != null) {
5268                try {
5269                    int num = firstPids.size();
5270                    for (int i = 0; i < num; i++) {
5271                        synchronized (observer) {
5272                            if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5273                                    + firstPids.get(i));
5274                            final long sime = SystemClock.elapsedRealtime();
5275                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5276                            observer.wait(1000);  // Wait for write-close, give up after 1 sec
5277                            if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5278                                    + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5279                        }
5280                    }
5281                } catch (InterruptedException e) {
5282                    Slog.wtf(TAG, e);
5283                }
5284            }
5285
5286            // Next collect the stacks of the native pids
5287            if (nativeProcs != null) {
5288                int[] pids = Process.getPidsForCommands(nativeProcs);
5289                if (pids != null) {
5290                    for (int pid : pids) {
5291                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5292                        final long sime = SystemClock.elapsedRealtime();
5293                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5294                        if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5295                                + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5296                    }
5297                }
5298            }
5299
5300            // Lastly, measure CPU usage.
5301            if (processCpuTracker != null) {
5302                processCpuTracker.init();
5303                System.gc();
5304                processCpuTracker.update();
5305                try {
5306                    synchronized (processCpuTracker) {
5307                        processCpuTracker.wait(500); // measure over 1/2 second.
5308                    }
5309                } catch (InterruptedException e) {
5310                }
5311                processCpuTracker.update();
5312
5313                // We'll take the stack crawls of just the top apps using CPU.
5314                final int N = processCpuTracker.countWorkingStats();
5315                int numProcs = 0;
5316                for (int i=0; i<N && numProcs<5; i++) {
5317                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5318                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5319                        numProcs++;
5320                        try {
5321                            synchronized (observer) {
5322                                if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5323                                        + stats.pid);
5324                                final long stime = SystemClock.elapsedRealtime();
5325                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5326                                observer.wait(1000);  // Wait for write-close, give up after 1 sec
5327                                if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5328                                        + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5329                            }
5330                        } catch (InterruptedException e) {
5331                            Slog.wtf(TAG, e);
5332                        }
5333                    } else if (DEBUG_ANR) {
5334                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5335                                + stats.pid);
5336                    }
5337                }
5338            }
5339        } finally {
5340            observer.stopWatching();
5341        }
5342    }
5343
5344    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5345        if (true || IS_USER_BUILD) {
5346            return;
5347        }
5348        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5349        if (tracesPath == null || tracesPath.length() == 0) {
5350            return;
5351        }
5352
5353        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5354        StrictMode.allowThreadDiskWrites();
5355        try {
5356            final File tracesFile = new File(tracesPath);
5357            final File tracesDir = tracesFile.getParentFile();
5358            final File tracesTmp = new File(tracesDir, "__tmp__");
5359            try {
5360                if (tracesFile.exists()) {
5361                    tracesTmp.delete();
5362                    tracesFile.renameTo(tracesTmp);
5363                }
5364                StringBuilder sb = new StringBuilder();
5365                Time tobj = new Time();
5366                tobj.set(System.currentTimeMillis());
5367                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5368                sb.append(": ");
5369                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5370                sb.append(" since ");
5371                sb.append(msg);
5372                FileOutputStream fos = new FileOutputStream(tracesFile);
5373                fos.write(sb.toString().getBytes());
5374                if (app == null) {
5375                    fos.write("\n*** No application process!".getBytes());
5376                }
5377                fos.close();
5378                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5379            } catch (IOException e) {
5380                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5381                return;
5382            }
5383
5384            if (app != null) {
5385                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5386                firstPids.add(app.pid);
5387                dumpStackTraces(tracesPath, firstPids, null, null, null);
5388            }
5389
5390            File lastTracesFile = null;
5391            File curTracesFile = null;
5392            for (int i=9; i>=0; i--) {
5393                String name = String.format(Locale.US, "slow%02d.txt", i);
5394                curTracesFile = new File(tracesDir, name);
5395                if (curTracesFile.exists()) {
5396                    if (lastTracesFile != null) {
5397                        curTracesFile.renameTo(lastTracesFile);
5398                    } else {
5399                        curTracesFile.delete();
5400                    }
5401                }
5402                lastTracesFile = curTracesFile;
5403            }
5404            tracesFile.renameTo(curTracesFile);
5405            if (tracesTmp.exists()) {
5406                tracesTmp.renameTo(tracesFile);
5407            }
5408        } finally {
5409            StrictMode.setThreadPolicy(oldPolicy);
5410        }
5411    }
5412
5413    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5414        if (!mLaunchWarningShown) {
5415            mLaunchWarningShown = true;
5416            mUiHandler.post(new Runnable() {
5417                @Override
5418                public void run() {
5419                    synchronized (ActivityManagerService.this) {
5420                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5421                        d.show();
5422                        mUiHandler.postDelayed(new Runnable() {
5423                            @Override
5424                            public void run() {
5425                                synchronized (ActivityManagerService.this) {
5426                                    d.dismiss();
5427                                    mLaunchWarningShown = false;
5428                                }
5429                            }
5430                        }, 4000);
5431                    }
5432                }
5433            });
5434        }
5435    }
5436
5437    @Override
5438    public boolean clearApplicationUserData(final String packageName,
5439            final IPackageDataObserver observer, int userId) {
5440        enforceNotIsolatedCaller("clearApplicationUserData");
5441        int uid = Binder.getCallingUid();
5442        int pid = Binder.getCallingPid();
5443        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5444                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5445
5446
5447        long callingId = Binder.clearCallingIdentity();
5448        try {
5449            IPackageManager pm = AppGlobals.getPackageManager();
5450            int pkgUid = -1;
5451            synchronized(this) {
5452                if (getPackageManagerInternalLocked().isPackageDataProtected(
5453                        userId, packageName)) {
5454                    throw new SecurityException(
5455                            "Cannot clear data for a protected package: " + packageName);
5456                }
5457
5458                try {
5459                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5460                } catch (RemoteException e) {
5461                }
5462                if (pkgUid == -1) {
5463                    Slog.w(TAG, "Invalid packageName: " + packageName);
5464                    if (observer != null) {
5465                        try {
5466                            observer.onRemoveCompleted(packageName, false);
5467                        } catch (RemoteException e) {
5468                            Slog.i(TAG, "Observer no longer exists.");
5469                        }
5470                    }
5471                    return false;
5472                }
5473                if (uid == pkgUid || checkComponentPermission(
5474                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5475                        pid, uid, -1, true)
5476                        == PackageManager.PERMISSION_GRANTED) {
5477                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5478                } else {
5479                    throw new SecurityException("PID " + pid + " does not have permission "
5480                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5481                                    + " of package " + packageName);
5482                }
5483
5484                // Remove all tasks match the cleared application package and user
5485                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5486                    final TaskRecord tr = mRecentTasks.get(i);
5487                    final String taskPackageName =
5488                            tr.getBaseIntent().getComponent().getPackageName();
5489                    if (tr.userId != userId) continue;
5490                    if (!taskPackageName.equals(packageName)) continue;
5491                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5492                }
5493            }
5494
5495            final int pkgUidF = pkgUid;
5496            final int userIdF = userId;
5497            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5498                @Override
5499                public void onRemoveCompleted(String packageName, boolean succeeded)
5500                        throws RemoteException {
5501                    synchronized (ActivityManagerService.this) {
5502                        finishForceStopPackageLocked(packageName, pkgUidF);
5503                    }
5504
5505                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5506                            Uri.fromParts("package", packageName, null));
5507                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5508                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5509                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5510                            null, null, 0, null, null, null, null, false, false, userIdF);
5511
5512                    if (observer != null) {
5513                        observer.onRemoveCompleted(packageName, succeeded);
5514                    }
5515                }
5516            };
5517
5518            try {
5519                // Clear application user data
5520                pm.clearApplicationUserData(packageName, localObserver, userId);
5521
5522                synchronized(this) {
5523                    // Remove all permissions granted from/to this package
5524                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5525                }
5526
5527                // Remove all zen rules created by this package; revoke it's zen access.
5528                INotificationManager inm = NotificationManager.getService();
5529                inm.removeAutomaticZenRules(packageName);
5530                inm.setNotificationPolicyAccessGranted(packageName, false);
5531
5532            } catch (RemoteException e) {
5533            }
5534        } finally {
5535            Binder.restoreCallingIdentity(callingId);
5536        }
5537        return true;
5538    }
5539
5540    @Override
5541    public void killBackgroundProcesses(final String packageName, int userId) {
5542        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5543                != PackageManager.PERMISSION_GRANTED &&
5544                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5545                        != PackageManager.PERMISSION_GRANTED) {
5546            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5547                    + Binder.getCallingPid()
5548                    + ", uid=" + Binder.getCallingUid()
5549                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5550            Slog.w(TAG, msg);
5551            throw new SecurityException(msg);
5552        }
5553
5554        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5555                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5556        long callingId = Binder.clearCallingIdentity();
5557        try {
5558            IPackageManager pm = AppGlobals.getPackageManager();
5559            synchronized(this) {
5560                int appId = -1;
5561                try {
5562                    appId = UserHandle.getAppId(
5563                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5564                } catch (RemoteException e) {
5565                }
5566                if (appId == -1) {
5567                    Slog.w(TAG, "Invalid packageName: " + packageName);
5568                    return;
5569                }
5570                killPackageProcessesLocked(packageName, appId, userId,
5571                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5572            }
5573        } finally {
5574            Binder.restoreCallingIdentity(callingId);
5575        }
5576    }
5577
5578    @Override
5579    public void killAllBackgroundProcesses() {
5580        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5581                != PackageManager.PERMISSION_GRANTED) {
5582            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5583                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5584                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5585            Slog.w(TAG, msg);
5586            throw new SecurityException(msg);
5587        }
5588
5589        final long callingId = Binder.clearCallingIdentity();
5590        try {
5591            synchronized (this) {
5592                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5593                final int NP = mProcessNames.getMap().size();
5594                for (int ip = 0; ip < NP; ip++) {
5595                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5596                    final int NA = apps.size();
5597                    for (int ia = 0; ia < NA; ia++) {
5598                        final ProcessRecord app = apps.valueAt(ia);
5599                        if (app.persistent) {
5600                            // We don't kill persistent processes.
5601                            continue;
5602                        }
5603                        if (app.removed) {
5604                            procs.add(app);
5605                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5606                            app.removed = true;
5607                            procs.add(app);
5608                        }
5609                    }
5610                }
5611
5612                final int N = procs.size();
5613                for (int i = 0; i < N; i++) {
5614                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5615                }
5616
5617                mAllowLowerMemLevel = true;
5618
5619                updateOomAdjLocked();
5620                doLowMemReportIfNeededLocked(null);
5621            }
5622        } finally {
5623            Binder.restoreCallingIdentity(callingId);
5624        }
5625    }
5626
5627    /**
5628     * Kills all background processes, except those matching any of the
5629     * specified properties.
5630     *
5631     * @param minTargetSdk the target SDK version at or above which to preserve
5632     *                     processes, or {@code -1} to ignore the target SDK
5633     * @param maxProcState the process state at or below which to preserve
5634     *                     processes, or {@code -1} to ignore the process state
5635     */
5636    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5637        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5638                != PackageManager.PERMISSION_GRANTED) {
5639            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5640                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5641                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5642            Slog.w(TAG, msg);
5643            throw new SecurityException(msg);
5644        }
5645
5646        final long callingId = Binder.clearCallingIdentity();
5647        try {
5648            synchronized (this) {
5649                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5650                final int NP = mProcessNames.getMap().size();
5651                for (int ip = 0; ip < NP; ip++) {
5652                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5653                    final int NA = apps.size();
5654                    for (int ia = 0; ia < NA; ia++) {
5655                        final ProcessRecord app = apps.valueAt(ia);
5656                        if (app.removed) {
5657                            procs.add(app);
5658                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5659                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5660                            app.removed = true;
5661                            procs.add(app);
5662                        }
5663                    }
5664                }
5665
5666                final int N = procs.size();
5667                for (int i = 0; i < N; i++) {
5668                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5669                }
5670            }
5671        } finally {
5672            Binder.restoreCallingIdentity(callingId);
5673        }
5674    }
5675
5676    @Override
5677    public void forceStopPackage(final String packageName, int userId) {
5678        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5679                != PackageManager.PERMISSION_GRANTED) {
5680            String msg = "Permission Denial: forceStopPackage() from pid="
5681                    + Binder.getCallingPid()
5682                    + ", uid=" + Binder.getCallingUid()
5683                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5684            Slog.w(TAG, msg);
5685            throw new SecurityException(msg);
5686        }
5687        final int callingPid = Binder.getCallingPid();
5688        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5689                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5690        long callingId = Binder.clearCallingIdentity();
5691        try {
5692            IPackageManager pm = AppGlobals.getPackageManager();
5693            synchronized(this) {
5694                int[] users = userId == UserHandle.USER_ALL
5695                        ? mUserController.getUsers() : new int[] { userId };
5696                for (int user : users) {
5697                    int pkgUid = -1;
5698                    try {
5699                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5700                                user);
5701                    } catch (RemoteException e) {
5702                    }
5703                    if (pkgUid == -1) {
5704                        Slog.w(TAG, "Invalid packageName: " + packageName);
5705                        continue;
5706                    }
5707                    try {
5708                        pm.setPackageStoppedState(packageName, true, user);
5709                    } catch (RemoteException e) {
5710                    } catch (IllegalArgumentException e) {
5711                        Slog.w(TAG, "Failed trying to unstop package "
5712                                + packageName + ": " + e);
5713                    }
5714                    if (mUserController.isUserRunningLocked(user, 0)) {
5715                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5716                        finishForceStopPackageLocked(packageName, pkgUid);
5717                    }
5718                }
5719            }
5720        } finally {
5721            Binder.restoreCallingIdentity(callingId);
5722        }
5723    }
5724
5725    @Override
5726    public void addPackageDependency(String packageName) {
5727        synchronized (this) {
5728            int callingPid = Binder.getCallingPid();
5729            if (callingPid == Process.myPid()) {
5730                //  Yeah, um, no.
5731                return;
5732            }
5733            ProcessRecord proc;
5734            synchronized (mPidsSelfLocked) {
5735                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5736            }
5737            if (proc != null) {
5738                if (proc.pkgDeps == null) {
5739                    proc.pkgDeps = new ArraySet<String>(1);
5740                }
5741                proc.pkgDeps.add(packageName);
5742            }
5743        }
5744    }
5745
5746    /*
5747     * The pkg name and app id have to be specified.
5748     */
5749    @Override
5750    public void killApplication(String pkg, int appId, int userId, String reason) {
5751        if (pkg == null) {
5752            return;
5753        }
5754        // Make sure the uid is valid.
5755        if (appId < 0) {
5756            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5757            return;
5758        }
5759        int callerUid = Binder.getCallingUid();
5760        // Only the system server can kill an application
5761        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5762            // Post an aysnc message to kill the application
5763            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5764            msg.arg1 = appId;
5765            msg.arg2 = userId;
5766            Bundle bundle = new Bundle();
5767            bundle.putString("pkg", pkg);
5768            bundle.putString("reason", reason);
5769            msg.obj = bundle;
5770            mHandler.sendMessage(msg);
5771        } else {
5772            throw new SecurityException(callerUid + " cannot kill pkg: " +
5773                    pkg);
5774        }
5775    }
5776
5777    @Override
5778    public void closeSystemDialogs(String reason) {
5779        enforceNotIsolatedCaller("closeSystemDialogs");
5780
5781        final int pid = Binder.getCallingPid();
5782        final int uid = Binder.getCallingUid();
5783        final long origId = Binder.clearCallingIdentity();
5784        try {
5785            synchronized (this) {
5786                // Only allow this from foreground processes, so that background
5787                // applications can't abuse it to prevent system UI from being shown.
5788                if (uid >= Process.FIRST_APPLICATION_UID) {
5789                    ProcessRecord proc;
5790                    synchronized (mPidsSelfLocked) {
5791                        proc = mPidsSelfLocked.get(pid);
5792                    }
5793                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5794                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5795                                + " from background process " + proc);
5796                        return;
5797                    }
5798                }
5799                closeSystemDialogsLocked(reason);
5800            }
5801        } finally {
5802            Binder.restoreCallingIdentity(origId);
5803        }
5804    }
5805
5806    void closeSystemDialogsLocked(String reason) {
5807        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5808        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5809                | Intent.FLAG_RECEIVER_FOREGROUND);
5810        if (reason != null) {
5811            intent.putExtra("reason", reason);
5812        }
5813        mWindowManager.closeSystemDialogs(reason);
5814
5815        mStackSupervisor.closeSystemDialogsLocked();
5816
5817        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5818                AppOpsManager.OP_NONE, null, false, false,
5819                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5820    }
5821
5822    @Override
5823    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5824        enforceNotIsolatedCaller("getProcessMemoryInfo");
5825        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5826        for (int i=pids.length-1; i>=0; i--) {
5827            ProcessRecord proc;
5828            int oomAdj;
5829            synchronized (this) {
5830                synchronized (mPidsSelfLocked) {
5831                    proc = mPidsSelfLocked.get(pids[i]);
5832                    oomAdj = proc != null ? proc.setAdj : 0;
5833                }
5834            }
5835            infos[i] = new Debug.MemoryInfo();
5836            Debug.getMemoryInfo(pids[i], infos[i]);
5837            if (proc != null) {
5838                synchronized (this) {
5839                    if (proc.thread != null && proc.setAdj == oomAdj) {
5840                        // Record this for posterity if the process has been stable.
5841                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5842                                infos[i].getTotalUss(), false, proc.pkgList);
5843                    }
5844                }
5845            }
5846        }
5847        return infos;
5848    }
5849
5850    @Override
5851    public long[] getProcessPss(int[] pids) {
5852        enforceNotIsolatedCaller("getProcessPss");
5853        long[] pss = new long[pids.length];
5854        for (int i=pids.length-1; i>=0; i--) {
5855            ProcessRecord proc;
5856            int oomAdj;
5857            synchronized (this) {
5858                synchronized (mPidsSelfLocked) {
5859                    proc = mPidsSelfLocked.get(pids[i]);
5860                    oomAdj = proc != null ? proc.setAdj : 0;
5861                }
5862            }
5863            long[] tmpUss = new long[1];
5864            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5865            if (proc != null) {
5866                synchronized (this) {
5867                    if (proc.thread != null && proc.setAdj == oomAdj) {
5868                        // Record this for posterity if the process has been stable.
5869                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5870                    }
5871                }
5872            }
5873        }
5874        return pss;
5875    }
5876
5877    @Override
5878    public void killApplicationProcess(String processName, int uid) {
5879        if (processName == null) {
5880            return;
5881        }
5882
5883        int callerUid = Binder.getCallingUid();
5884        // Only the system server can kill an application
5885        if (callerUid == Process.SYSTEM_UID) {
5886            synchronized (this) {
5887                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5888                if (app != null && app.thread != null) {
5889                    try {
5890                        app.thread.scheduleSuicide();
5891                    } catch (RemoteException e) {
5892                        // If the other end already died, then our work here is done.
5893                    }
5894                } else {
5895                    Slog.w(TAG, "Process/uid not found attempting kill of "
5896                            + processName + " / " + uid);
5897                }
5898            }
5899        } else {
5900            throw new SecurityException(callerUid + " cannot kill app process: " +
5901                    processName);
5902        }
5903    }
5904
5905    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5906        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5907                false, true, false, false, UserHandle.getUserId(uid), reason);
5908    }
5909
5910    private void finishForceStopPackageLocked(final String packageName, int uid) {
5911        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5912                Uri.fromParts("package", packageName, null));
5913        if (!mProcessesReady) {
5914            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5915                    | Intent.FLAG_RECEIVER_FOREGROUND);
5916        }
5917        intent.putExtra(Intent.EXTRA_UID, uid);
5918        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5919        broadcastIntentLocked(null, null, intent,
5920                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5921                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5922    }
5923
5924
5925    private final boolean killPackageProcessesLocked(String packageName, int appId,
5926            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5927            boolean doit, boolean evenPersistent, String reason) {
5928        ArrayList<ProcessRecord> procs = new ArrayList<>();
5929
5930        // Remove all processes this package may have touched: all with the
5931        // same UID (except for the system or root user), and all whose name
5932        // matches the package name.
5933        final int NP = mProcessNames.getMap().size();
5934        for (int ip=0; ip<NP; ip++) {
5935            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5936            final int NA = apps.size();
5937            for (int ia=0; ia<NA; ia++) {
5938                ProcessRecord app = apps.valueAt(ia);
5939                if (app.persistent && !evenPersistent) {
5940                    // we don't kill persistent processes
5941                    continue;
5942                }
5943                if (app.removed) {
5944                    if (doit) {
5945                        procs.add(app);
5946                    }
5947                    continue;
5948                }
5949
5950                // Skip process if it doesn't meet our oom adj requirement.
5951                if (app.setAdj < minOomAdj) {
5952                    continue;
5953                }
5954
5955                // If no package is specified, we call all processes under the
5956                // give user id.
5957                if (packageName == null) {
5958                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5959                        continue;
5960                    }
5961                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5962                        continue;
5963                    }
5964                // Package has been specified, we want to hit all processes
5965                // that match it.  We need to qualify this by the processes
5966                // that are running under the specified app and user ID.
5967                } else {
5968                    final boolean isDep = app.pkgDeps != null
5969                            && app.pkgDeps.contains(packageName);
5970                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5971                        continue;
5972                    }
5973                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5974                        continue;
5975                    }
5976                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5977                        continue;
5978                    }
5979                }
5980
5981                // Process has passed all conditions, kill it!
5982                if (!doit) {
5983                    return true;
5984                }
5985                app.removed = true;
5986                procs.add(app);
5987            }
5988        }
5989
5990        int N = procs.size();
5991        for (int i=0; i<N; i++) {
5992            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5993        }
5994        updateOomAdjLocked();
5995        return N > 0;
5996    }
5997
5998    private void cleanupDisabledPackageComponentsLocked(
5999            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6000
6001        Set<String> disabledClasses = null;
6002        boolean packageDisabled = false;
6003        IPackageManager pm = AppGlobals.getPackageManager();
6004
6005        if (changedClasses == null) {
6006            // Nothing changed...
6007            return;
6008        }
6009
6010        // Determine enable/disable state of the package and its components.
6011        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6012        for (int i = changedClasses.length - 1; i >= 0; i--) {
6013            final String changedClass = changedClasses[i];
6014
6015            if (changedClass.equals(packageName)) {
6016                try {
6017                    // Entire package setting changed
6018                    enabled = pm.getApplicationEnabledSetting(packageName,
6019                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6020                } catch (Exception e) {
6021                    // No such package/component; probably racing with uninstall.  In any
6022                    // event it means we have nothing further to do here.
6023                    return;
6024                }
6025                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6026                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6027                if (packageDisabled) {
6028                    // Entire package is disabled.
6029                    // No need to continue to check component states.
6030                    disabledClasses = null;
6031                    break;
6032                }
6033            } else {
6034                try {
6035                    enabled = pm.getComponentEnabledSetting(
6036                            new ComponentName(packageName, changedClass),
6037                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6038                } catch (Exception e) {
6039                    // As above, probably racing with uninstall.
6040                    return;
6041                }
6042                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6043                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6044                    if (disabledClasses == null) {
6045                        disabledClasses = new ArraySet<>(changedClasses.length);
6046                    }
6047                    disabledClasses.add(changedClass);
6048                }
6049            }
6050        }
6051
6052        if (!packageDisabled && disabledClasses == null) {
6053            // Nothing to do here...
6054            return;
6055        }
6056
6057        // Clean-up disabled activities.
6058        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6059                packageName, disabledClasses, true, false, userId) && mBooted) {
6060            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6061            mStackSupervisor.scheduleIdleLocked();
6062        }
6063
6064        // Clean-up disabled tasks
6065        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6066
6067        // Clean-up disabled services.
6068        mServices.bringDownDisabledPackageServicesLocked(
6069                packageName, disabledClasses, userId, false, killProcess, true);
6070
6071        // Clean-up disabled providers.
6072        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6073        mProviderMap.collectPackageProvidersLocked(
6074                packageName, disabledClasses, true, false, userId, providers);
6075        for (int i = providers.size() - 1; i >= 0; i--) {
6076            removeDyingProviderLocked(null, providers.get(i), true);
6077        }
6078
6079        // Clean-up disabled broadcast receivers.
6080        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6081            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6082                    packageName, disabledClasses, userId, true);
6083        }
6084
6085    }
6086
6087    final boolean clearBroadcastQueueForUserLocked(int userId) {
6088        boolean didSomething = false;
6089        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6090            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6091                    null, null, userId, true);
6092        }
6093        return didSomething;
6094    }
6095
6096    final boolean forceStopPackageLocked(String packageName, int appId,
6097            boolean callerWillRestart, boolean purgeCache, boolean doit,
6098            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6099        int i;
6100
6101        if (userId == UserHandle.USER_ALL && packageName == null) {
6102            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6103        }
6104
6105        if (appId < 0 && packageName != null) {
6106            try {
6107                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6108                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6109            } catch (RemoteException e) {
6110            }
6111        }
6112
6113        if (doit) {
6114            if (packageName != null) {
6115                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6116                        + " user=" + userId + ": " + reason);
6117            } else {
6118                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6119            }
6120
6121            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6122        }
6123
6124        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6125                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6126                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6127
6128        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6129
6130        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6131                packageName, null, doit, evenPersistent, userId)) {
6132            if (!doit) {
6133                return true;
6134            }
6135            didSomething = true;
6136        }
6137
6138        if (mServices.bringDownDisabledPackageServicesLocked(
6139                packageName, null, userId, evenPersistent, true, doit)) {
6140            if (!doit) {
6141                return true;
6142            }
6143            didSomething = true;
6144        }
6145
6146        if (packageName == null) {
6147            // Remove all sticky broadcasts from this user.
6148            mStickyBroadcasts.remove(userId);
6149        }
6150
6151        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6152        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6153                userId, providers)) {
6154            if (!doit) {
6155                return true;
6156            }
6157            didSomething = true;
6158        }
6159        for (i = providers.size() - 1; i >= 0; i--) {
6160            removeDyingProviderLocked(null, providers.get(i), true);
6161        }
6162
6163        // Remove transient permissions granted from/to this package/user
6164        removeUriPermissionsForPackageLocked(packageName, userId, false);
6165
6166        if (doit) {
6167            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6168                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6169                        packageName, null, userId, doit);
6170            }
6171        }
6172
6173        if (packageName == null || uninstalling) {
6174            // Remove pending intents.  For now we only do this when force
6175            // stopping users, because we have some problems when doing this
6176            // for packages -- app widgets are not currently cleaned up for
6177            // such packages, so they can be left with bad pending intents.
6178            if (mIntentSenderRecords.size() > 0) {
6179                Iterator<WeakReference<PendingIntentRecord>> it
6180                        = mIntentSenderRecords.values().iterator();
6181                while (it.hasNext()) {
6182                    WeakReference<PendingIntentRecord> wpir = it.next();
6183                    if (wpir == null) {
6184                        it.remove();
6185                        continue;
6186                    }
6187                    PendingIntentRecord pir = wpir.get();
6188                    if (pir == null) {
6189                        it.remove();
6190                        continue;
6191                    }
6192                    if (packageName == null) {
6193                        // Stopping user, remove all objects for the user.
6194                        if (pir.key.userId != userId) {
6195                            // Not the same user, skip it.
6196                            continue;
6197                        }
6198                    } else {
6199                        if (UserHandle.getAppId(pir.uid) != appId) {
6200                            // Different app id, skip it.
6201                            continue;
6202                        }
6203                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6204                            // Different user, skip it.
6205                            continue;
6206                        }
6207                        if (!pir.key.packageName.equals(packageName)) {
6208                            // Different package, skip it.
6209                            continue;
6210                        }
6211                    }
6212                    if (!doit) {
6213                        return true;
6214                    }
6215                    didSomething = true;
6216                    it.remove();
6217                    pir.canceled = true;
6218                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6219                        pir.key.activity.pendingResults.remove(pir.ref);
6220                    }
6221                }
6222            }
6223        }
6224
6225        if (doit) {
6226            if (purgeCache && packageName != null) {
6227                AttributeCache ac = AttributeCache.instance();
6228                if (ac != null) {
6229                    ac.removePackage(packageName);
6230                }
6231            }
6232            if (mBooted) {
6233                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6234                mStackSupervisor.scheduleIdleLocked();
6235            }
6236        }
6237
6238        return didSomething;
6239    }
6240
6241    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6242        return removeProcessNameLocked(name, uid, null);
6243    }
6244
6245    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6246            final ProcessRecord expecting) {
6247        ProcessRecord old = mProcessNames.get(name, uid);
6248        // Only actually remove when the currently recorded value matches the
6249        // record that we expected; if it doesn't match then we raced with a
6250        // newly created process and we don't want to destroy the new one.
6251        if ((expecting == null) || (old == expecting)) {
6252            mProcessNames.remove(name, uid);
6253        }
6254        if (old != null && old.uidRecord != null) {
6255            old.uidRecord.numProcs--;
6256            if (old.uidRecord.numProcs == 0) {
6257                // No more processes using this uid, tell clients it is gone.
6258                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6259                        "No more processes in " + old.uidRecord);
6260                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6261                mActiveUids.remove(uid);
6262                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6263            }
6264            old.uidRecord = null;
6265        }
6266        mIsolatedProcesses.remove(uid);
6267        return old;
6268    }
6269
6270    private final void addProcessNameLocked(ProcessRecord proc) {
6271        // We shouldn't already have a process under this name, but just in case we
6272        // need to clean up whatever may be there now.
6273        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6274        if (old == proc && proc.persistent) {
6275            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6276            Slog.w(TAG, "Re-adding persistent process " + proc);
6277        } else if (old != null) {
6278            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6279        }
6280        UidRecord uidRec = mActiveUids.get(proc.uid);
6281        if (uidRec == null) {
6282            uidRec = new UidRecord(proc.uid);
6283            // This is the first appearance of the uid, report it now!
6284            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6285                    "Creating new process uid: " + uidRec);
6286            mActiveUids.put(proc.uid, uidRec);
6287            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6288            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6289        }
6290        proc.uidRecord = uidRec;
6291
6292        // Reset render thread tid if it was already set, so new process can set it again.
6293        proc.renderThreadTid = 0;
6294        uidRec.numProcs++;
6295        mProcessNames.put(proc.processName, proc.uid, proc);
6296        if (proc.isolated) {
6297            mIsolatedProcesses.put(proc.uid, proc);
6298        }
6299    }
6300
6301    boolean removeProcessLocked(ProcessRecord app,
6302            boolean callerWillRestart, boolean allowRestart, String reason) {
6303        final String name = app.processName;
6304        final int uid = app.uid;
6305        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6306            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6307
6308        ProcessRecord old = mProcessNames.get(name, uid);
6309        if (old != app) {
6310            // This process is no longer active, so nothing to do.
6311            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6312            return false;
6313        }
6314        removeProcessNameLocked(name, uid);
6315        if (mHeavyWeightProcess == app) {
6316            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6317                    mHeavyWeightProcess.userId, 0));
6318            mHeavyWeightProcess = null;
6319        }
6320        boolean needRestart = false;
6321        if (app.pid > 0 && app.pid != MY_PID) {
6322            int pid = app.pid;
6323            synchronized (mPidsSelfLocked) {
6324                mPidsSelfLocked.remove(pid);
6325                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6326            }
6327            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6328            if (app.isolated) {
6329                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6330            }
6331            boolean willRestart = false;
6332            if (app.persistent && !app.isolated) {
6333                if (!callerWillRestart) {
6334                    willRestart = true;
6335                } else {
6336                    needRestart = true;
6337                }
6338            }
6339            app.kill(reason, true);
6340            handleAppDiedLocked(app, willRestart, allowRestart);
6341            if (willRestart) {
6342                removeLruProcessLocked(app);
6343                addAppLocked(app.info, false, null /* ABI override */);
6344            }
6345        } else {
6346            mRemovedProcesses.add(app);
6347        }
6348
6349        return needRestart;
6350    }
6351
6352    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6353        cleanupAppInLaunchingProvidersLocked(app, true);
6354        removeProcessLocked(app, false, true, "timeout publishing content providers");
6355    }
6356
6357    private final void processStartTimedOutLocked(ProcessRecord app) {
6358        final int pid = app.pid;
6359        boolean gone = false;
6360        synchronized (mPidsSelfLocked) {
6361            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6362            if (knownApp != null && knownApp.thread == null) {
6363                mPidsSelfLocked.remove(pid);
6364                gone = true;
6365            }
6366        }
6367
6368        if (gone) {
6369            Slog.w(TAG, "Process " + app + " failed to attach");
6370            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6371                    pid, app.uid, app.processName);
6372            removeProcessNameLocked(app.processName, app.uid);
6373            if (mHeavyWeightProcess == app) {
6374                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6375                        mHeavyWeightProcess.userId, 0));
6376                mHeavyWeightProcess = null;
6377            }
6378            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6379            if (app.isolated) {
6380                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6381            }
6382            // Take care of any launching providers waiting for this process.
6383            cleanupAppInLaunchingProvidersLocked(app, true);
6384            // Take care of any services that are waiting for the process.
6385            mServices.processStartTimedOutLocked(app);
6386            app.kill("start timeout", true);
6387            removeLruProcessLocked(app);
6388            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6389                Slog.w(TAG, "Unattached app died before backup, skipping");
6390                mHandler.post(new Runnable() {
6391                @Override
6392                    public void run(){
6393                        try {
6394                            IBackupManager bm = IBackupManager.Stub.asInterface(
6395                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6396                            bm.agentDisconnected(app.info.packageName);
6397                        } catch (RemoteException e) {
6398                            // Can't happen; the backup manager is local
6399                        }
6400                    }
6401                });
6402            }
6403            if (isPendingBroadcastProcessLocked(pid)) {
6404                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6405                skipPendingBroadcastLocked(pid);
6406            }
6407        } else {
6408            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6409        }
6410    }
6411
6412    private final boolean attachApplicationLocked(IApplicationThread thread,
6413            int pid) {
6414
6415        // Find the application record that is being attached...  either via
6416        // the pid if we are running in multiple processes, or just pull the
6417        // next app record if we are emulating process with anonymous threads.
6418        ProcessRecord app;
6419        long startTime = SystemClock.uptimeMillis();
6420        if (pid != MY_PID && pid >= 0) {
6421            synchronized (mPidsSelfLocked) {
6422                app = mPidsSelfLocked.get(pid);
6423            }
6424        } else {
6425            app = null;
6426        }
6427
6428        if (app == null) {
6429            Slog.w(TAG, "No pending application record for pid " + pid
6430                    + " (IApplicationThread " + thread + "); dropping process");
6431            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6432            if (pid > 0 && pid != MY_PID) {
6433                Process.killProcessQuiet(pid);
6434                //TODO: killProcessGroup(app.info.uid, pid);
6435            } else {
6436                try {
6437                    thread.scheduleExit();
6438                } catch (Exception e) {
6439                    // Ignore exceptions.
6440                }
6441            }
6442            return false;
6443        }
6444
6445        // If this application record is still attached to a previous
6446        // process, clean it up now.
6447        if (app.thread != null) {
6448            handleAppDiedLocked(app, true, true);
6449        }
6450
6451        // Tell the process all about itself.
6452
6453        if (DEBUG_ALL) Slog.v(
6454                TAG, "Binding process pid " + pid + " to record " + app);
6455
6456        final String processName = app.processName;
6457        try {
6458            AppDeathRecipient adr = new AppDeathRecipient(
6459                    app, pid, thread);
6460            thread.asBinder().linkToDeath(adr, 0);
6461            app.deathRecipient = adr;
6462        } catch (RemoteException e) {
6463            app.resetPackageList(mProcessStats);
6464            startProcessLocked(app, "link fail", processName);
6465            return false;
6466        }
6467
6468        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6469
6470        app.makeActive(thread, mProcessStats);
6471        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6472        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6473        app.forcingToForeground = null;
6474        updateProcessForegroundLocked(app, false, false);
6475        app.hasShownUi = false;
6476        app.debugging = false;
6477        app.cached = false;
6478        app.killedByAm = false;
6479        app.killed = false;
6480
6481
6482        // We carefully use the same state that PackageManager uses for
6483        // filtering, since we use this flag to decide if we need to install
6484        // providers when user is unlocked later
6485        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6486
6487        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6488
6489        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6490        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6491
6492        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6493            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6494            msg.obj = app;
6495            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6496        }
6497
6498        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6499
6500        if (!normalMode) {
6501            Slog.i(TAG, "Launching preboot mode app: " + app);
6502        }
6503
6504        if (DEBUG_ALL) Slog.v(
6505            TAG, "New app record " + app
6506            + " thread=" + thread.asBinder() + " pid=" + pid);
6507        try {
6508            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6509            if (mDebugApp != null && mDebugApp.equals(processName)) {
6510                testMode = mWaitForDebugger
6511                    ? ApplicationThreadConstants.DEBUG_WAIT
6512                    : ApplicationThreadConstants.DEBUG_ON;
6513                app.debugging = true;
6514                if (mDebugTransient) {
6515                    mDebugApp = mOrigDebugApp;
6516                    mWaitForDebugger = mOrigWaitForDebugger;
6517                }
6518            }
6519            String profileFile = app.instrumentationProfileFile;
6520            ParcelFileDescriptor profileFd = null;
6521            int samplingInterval = 0;
6522            boolean profileAutoStop = false;
6523            if (mProfileApp != null && mProfileApp.equals(processName)) {
6524                mProfileProc = app;
6525                profileFile = mProfileFile;
6526                profileFd = mProfileFd;
6527                samplingInterval = mSamplingInterval;
6528                profileAutoStop = mAutoStopProfiler;
6529            }
6530            boolean enableTrackAllocation = false;
6531            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6532                enableTrackAllocation = true;
6533                mTrackAllocationApp = null;
6534            }
6535
6536            // If the app is being launched for restore or full backup, set it up specially
6537            boolean isRestrictedBackupMode = false;
6538            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6539                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6540                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6541                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6542                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6543            }
6544
6545            if (app.instrumentationClass != null) {
6546                notifyPackageUse(app.instrumentationClass.getPackageName(),
6547                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6548            }
6549            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6550                    + processName + " with config " + getGlobalConfiguration());
6551            ApplicationInfo appInfo = app.instrumentationInfo != null
6552                    ? app.instrumentationInfo : app.info;
6553            app.compat = compatibilityInfoForPackageLocked(appInfo);
6554            if (profileFd != null) {
6555                profileFd = profileFd.dup();
6556            }
6557            ProfilerInfo profilerInfo = profileFile == null ? null
6558                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6559
6560            // We deprecated Build.SERIAL and only apps that target pre NMR1
6561            // SDK can see it. Since access to the serial is now behind a
6562            // permission we push down the value.
6563            String buildSerial = Build.UNKNOWN;
6564            // TODO: SHTOPSHIP Uncomment the check when clients migrate
6565//            if (appInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
6566                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6567                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6568                        .getSerial();
6569//            }
6570
6571            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6572            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6573                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6574                    app.instrumentationUiAutomationConnection, testMode,
6575                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
6576                    isRestrictedBackupMode || !normalMode, app.persistent,
6577                    new Configuration(getGlobalConfiguration()), app.compat,
6578                    getCommonServicesLocked(app.isolated),
6579                    mCoreSettingsObserver.getCoreSettingsLocked(),
6580                    buildSerial);
6581
6582            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6583            updateLruProcessLocked(app, false, null);
6584            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6585            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6586        } catch (Exception e) {
6587            // todo: Yikes!  What should we do?  For now we will try to
6588            // start another process, but that could easily get us in
6589            // an infinite loop of restarting processes...
6590            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6591
6592            app.resetPackageList(mProcessStats);
6593            app.unlinkDeathRecipient();
6594            startProcessLocked(app, "bind fail", processName);
6595            return false;
6596        }
6597
6598        // Remove this record from the list of starting applications.
6599        mPersistentStartingProcesses.remove(app);
6600        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6601                "Attach application locked removing on hold: " + app);
6602        mProcessesOnHold.remove(app);
6603
6604        boolean badApp = false;
6605        boolean didSomething = false;
6606
6607        // See if the top visible activity is waiting to run in this process...
6608        if (normalMode) {
6609            try {
6610                if (mStackSupervisor.attachApplicationLocked(app)) {
6611                    didSomething = true;
6612                }
6613            } catch (Exception e) {
6614                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6615                badApp = true;
6616            }
6617        }
6618
6619        // Find any services that should be running in this process...
6620        if (!badApp) {
6621            try {
6622                didSomething |= mServices.attachApplicationLocked(app, processName);
6623                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6624            } catch (Exception e) {
6625                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6626                badApp = true;
6627            }
6628        }
6629
6630        // Check if a next-broadcast receiver is in this process...
6631        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6632            try {
6633                didSomething |= sendPendingBroadcastsLocked(app);
6634                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6635            } catch (Exception e) {
6636                // If the app died trying to launch the receiver we declare it 'bad'
6637                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6638                badApp = true;
6639            }
6640        }
6641
6642        // Check whether the next backup agent is in this process...
6643        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6644            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6645                    "New app is backup target, launching agent for " + app);
6646            notifyPackageUse(mBackupTarget.appInfo.packageName,
6647                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6648            try {
6649                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6650                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6651                        mBackupTarget.backupMode);
6652            } catch (Exception e) {
6653                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6654                badApp = true;
6655            }
6656        }
6657
6658        if (badApp) {
6659            app.kill("error during init", true);
6660            handleAppDiedLocked(app, false, true);
6661            return false;
6662        }
6663
6664        if (!didSomething) {
6665            updateOomAdjLocked();
6666            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6667        }
6668
6669        return true;
6670    }
6671
6672    @Override
6673    public final void attachApplication(IApplicationThread thread) {
6674        synchronized (this) {
6675            int callingPid = Binder.getCallingPid();
6676            final long origId = Binder.clearCallingIdentity();
6677            attachApplicationLocked(thread, callingPid);
6678            Binder.restoreCallingIdentity(origId);
6679        }
6680    }
6681
6682    @Override
6683    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6684        final long origId = Binder.clearCallingIdentity();
6685        synchronized (this) {
6686            ActivityStack stack = ActivityRecord.getStackLocked(token);
6687            if (stack != null) {
6688                ActivityRecord r =
6689                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6690                if (stopProfiling) {
6691                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6692                        try {
6693                            mProfileFd.close();
6694                        } catch (IOException e) {
6695                        }
6696                        clearProfilerLocked();
6697                    }
6698                }
6699            }
6700        }
6701        Binder.restoreCallingIdentity(origId);
6702    }
6703
6704    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6705        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6706                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6707    }
6708
6709    void enableScreenAfterBoot() {
6710        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6711                SystemClock.uptimeMillis());
6712        mWindowManager.enableScreenAfterBoot();
6713
6714        synchronized (this) {
6715            updateEventDispatchingLocked();
6716        }
6717    }
6718
6719    @Override
6720    public void showBootMessage(final CharSequence msg, final boolean always) {
6721        if (Binder.getCallingUid() != Process.myUid()) {
6722            throw new SecurityException();
6723        }
6724        mWindowManager.showBootMessage(msg, always);
6725    }
6726
6727    @Override
6728    public void keyguardGoingAway(int flags) {
6729        enforceNotIsolatedCaller("keyguardGoingAway");
6730        final long token = Binder.clearCallingIdentity();
6731        try {
6732            synchronized (this) {
6733                mKeyguardController.keyguardGoingAway(flags);
6734            }
6735        } finally {
6736            Binder.restoreCallingIdentity(token);
6737        }
6738    }
6739
6740    /**
6741     * @return whther the keyguard is currently locked.
6742     */
6743    boolean isKeyguardLocked() {
6744        return mKeyguardController.isKeyguardLocked();
6745    }
6746
6747    final void finishBooting() {
6748        synchronized (this) {
6749            if (!mBootAnimationComplete) {
6750                mCallFinishBooting = true;
6751                return;
6752            }
6753            mCallFinishBooting = false;
6754        }
6755
6756        ArraySet<String> completedIsas = new ArraySet<String>();
6757        for (String abi : Build.SUPPORTED_ABIS) {
6758            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
6759            final String instructionSet = VMRuntime.getInstructionSet(abi);
6760            if (!completedIsas.contains(instructionSet)) {
6761                try {
6762                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6763                } catch (InstallerException e) {
6764                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6765                            e.getMessage() +")");
6766                }
6767                completedIsas.add(instructionSet);
6768            }
6769        }
6770
6771        IntentFilter pkgFilter = new IntentFilter();
6772        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6773        pkgFilter.addDataScheme("package");
6774        mContext.registerReceiver(new BroadcastReceiver() {
6775            @Override
6776            public void onReceive(Context context, Intent intent) {
6777                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6778                if (pkgs != null) {
6779                    for (String pkg : pkgs) {
6780                        synchronized (ActivityManagerService.this) {
6781                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6782                                    0, "query restart")) {
6783                                setResultCode(Activity.RESULT_OK);
6784                                return;
6785                            }
6786                        }
6787                    }
6788                }
6789            }
6790        }, pkgFilter);
6791
6792        IntentFilter dumpheapFilter = new IntentFilter();
6793        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6794        mContext.registerReceiver(new BroadcastReceiver() {
6795            @Override
6796            public void onReceive(Context context, Intent intent) {
6797                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6798                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6799                } else {
6800                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6801                }
6802            }
6803        }, dumpheapFilter);
6804
6805        // Let system services know.
6806        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6807
6808        synchronized (this) {
6809            // Ensure that any processes we had put on hold are now started
6810            // up.
6811            final int NP = mProcessesOnHold.size();
6812            if (NP > 0) {
6813                ArrayList<ProcessRecord> procs =
6814                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6815                for (int ip=0; ip<NP; ip++) {
6816                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6817                            + procs.get(ip));
6818                    startProcessLocked(procs.get(ip), "on-hold", null);
6819                }
6820            }
6821
6822            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6823                // Start looking for apps that are abusing wake locks.
6824                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6825                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6826                // Tell anyone interested that we are done booting!
6827                SystemProperties.set("sys.boot_completed", "1");
6828
6829                // And trigger dev.bootcomplete if we are not showing encryption progress
6830                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6831                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6832                    SystemProperties.set("dev.bootcomplete", "1");
6833                }
6834                mUserController.sendBootCompletedLocked(
6835                        new IIntentReceiver.Stub() {
6836                            @Override
6837                            public void performReceive(Intent intent, int resultCode,
6838                                    String data, Bundle extras, boolean ordered,
6839                                    boolean sticky, int sendingUser) {
6840                                synchronized (ActivityManagerService.this) {
6841                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6842                                            true, false);
6843                                }
6844                            }
6845                        });
6846                scheduleStartProfilesLocked();
6847            }
6848        }
6849    }
6850
6851    @Override
6852    public void bootAnimationComplete() {
6853        final boolean callFinishBooting;
6854        synchronized (this) {
6855            callFinishBooting = mCallFinishBooting;
6856            mBootAnimationComplete = true;
6857        }
6858        if (callFinishBooting) {
6859            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6860            finishBooting();
6861            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6862        }
6863    }
6864
6865    final void ensureBootCompleted() {
6866        boolean booting;
6867        boolean enableScreen;
6868        synchronized (this) {
6869            booting = mBooting;
6870            mBooting = false;
6871            enableScreen = !mBooted;
6872            mBooted = true;
6873        }
6874
6875        if (booting) {
6876            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6877            finishBooting();
6878            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6879        }
6880
6881        if (enableScreen) {
6882            enableScreenAfterBoot();
6883        }
6884    }
6885
6886    @Override
6887    public final void activityResumed(IBinder token) {
6888        final long origId = Binder.clearCallingIdentity();
6889        synchronized(this) {
6890            ActivityRecord.activityResumedLocked(token);
6891            mWindowManager.notifyAppResumedFinished(token);
6892        }
6893        Binder.restoreCallingIdentity(origId);
6894    }
6895
6896    @Override
6897    public final void activityPaused(IBinder token) {
6898        final long origId = Binder.clearCallingIdentity();
6899        synchronized(this) {
6900            ActivityStack stack = ActivityRecord.getStackLocked(token);
6901            if (stack != null) {
6902                stack.activityPausedLocked(token, false);
6903            }
6904        }
6905        Binder.restoreCallingIdentity(origId);
6906    }
6907
6908    @Override
6909    public final void activityStopped(IBinder token, Bundle icicle,
6910            PersistableBundle persistentState, CharSequence description) {
6911        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6912
6913        // Refuse possible leaked file descriptors
6914        if (icicle != null && icicle.hasFileDescriptors()) {
6915            throw new IllegalArgumentException("File descriptors passed in Bundle");
6916        }
6917
6918        final long origId = Binder.clearCallingIdentity();
6919
6920        synchronized (this) {
6921            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
6922            if (r != null) {
6923                r.activityStoppedLocked(icicle, persistentState, description);
6924            }
6925        }
6926
6927        trimApplications();
6928
6929        Binder.restoreCallingIdentity(origId);
6930    }
6931
6932    @Override
6933    public final void activityDestroyed(IBinder token) {
6934        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6935        synchronized (this) {
6936            ActivityStack stack = ActivityRecord.getStackLocked(token);
6937            if (stack != null) {
6938                stack.activityDestroyedLocked(token, "activityDestroyed");
6939            }
6940        }
6941    }
6942
6943    @Override
6944    public final void activityRelaunched(IBinder token) {
6945        final long origId = Binder.clearCallingIdentity();
6946        synchronized (this) {
6947            mStackSupervisor.activityRelaunchedLocked(token);
6948        }
6949        Binder.restoreCallingIdentity(origId);
6950    }
6951
6952    @Override
6953    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6954            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6955        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6956                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6957        synchronized (this) {
6958            ActivityRecord record = ActivityRecord.isInStackLocked(token);
6959            if (record == null) {
6960                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6961                        + "found for: " + token);
6962            }
6963            record.setSizeConfigurations(horizontalSizeConfiguration,
6964                    verticalSizeConfigurations, smallestSizeConfigurations);
6965        }
6966    }
6967
6968    @Override
6969    public final void backgroundResourcesReleased(IBinder token) {
6970        final long origId = Binder.clearCallingIdentity();
6971        try {
6972            synchronized (this) {
6973                ActivityStack stack = ActivityRecord.getStackLocked(token);
6974                if (stack != null) {
6975                    stack.backgroundResourcesReleased();
6976                }
6977            }
6978        } finally {
6979            Binder.restoreCallingIdentity(origId);
6980        }
6981    }
6982
6983    @Override
6984    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6985        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6986    }
6987
6988    @Override
6989    public final void notifyEnterAnimationComplete(IBinder token) {
6990        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6991    }
6992
6993    @Override
6994    public String getCallingPackage(IBinder token) {
6995        synchronized (this) {
6996            ActivityRecord r = getCallingRecordLocked(token);
6997            return r != null ? r.info.packageName : null;
6998        }
6999    }
7000
7001    @Override
7002    public ComponentName getCallingActivity(IBinder token) {
7003        synchronized (this) {
7004            ActivityRecord r = getCallingRecordLocked(token);
7005            return r != null ? r.intent.getComponent() : null;
7006        }
7007    }
7008
7009    private ActivityRecord getCallingRecordLocked(IBinder token) {
7010        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7011        if (r == null) {
7012            return null;
7013        }
7014        return r.resultTo;
7015    }
7016
7017    @Override
7018    public ComponentName getActivityClassForToken(IBinder token) {
7019        synchronized(this) {
7020            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7021            if (r == null) {
7022                return null;
7023            }
7024            return r.intent.getComponent();
7025        }
7026    }
7027
7028    @Override
7029    public String getPackageForToken(IBinder token) {
7030        synchronized(this) {
7031            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7032            if (r == null) {
7033                return null;
7034            }
7035            return r.packageName;
7036        }
7037    }
7038
7039    @Override
7040    public boolean isRootVoiceInteraction(IBinder token) {
7041        synchronized(this) {
7042            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7043            if (r == null) {
7044                return false;
7045            }
7046            return r.rootVoiceInteraction;
7047        }
7048    }
7049
7050    @Override
7051    public IIntentSender getIntentSender(int type,
7052            String packageName, IBinder token, String resultWho,
7053            int requestCode, Intent[] intents, String[] resolvedTypes,
7054            int flags, Bundle bOptions, int userId) {
7055        enforceNotIsolatedCaller("getIntentSender");
7056        // Refuse possible leaked file descriptors
7057        if (intents != null) {
7058            if (intents.length < 1) {
7059                throw new IllegalArgumentException("Intents array length must be >= 1");
7060            }
7061            for (int i=0; i<intents.length; i++) {
7062                Intent intent = intents[i];
7063                if (intent != null) {
7064                    if (intent.hasFileDescriptors()) {
7065                        throw new IllegalArgumentException("File descriptors passed in Intent");
7066                    }
7067                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7068                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7069                        throw new IllegalArgumentException(
7070                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7071                    }
7072                    intents[i] = new Intent(intent);
7073                }
7074            }
7075            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7076                throw new IllegalArgumentException(
7077                        "Intent array length does not match resolvedTypes length");
7078            }
7079        }
7080        if (bOptions != null) {
7081            if (bOptions.hasFileDescriptors()) {
7082                throw new IllegalArgumentException("File descriptors passed in options");
7083            }
7084        }
7085
7086        synchronized(this) {
7087            int callingUid = Binder.getCallingUid();
7088            int origUserId = userId;
7089            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7090                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7091                    ALLOW_NON_FULL, "getIntentSender", null);
7092            if (origUserId == UserHandle.USER_CURRENT) {
7093                // We don't want to evaluate this until the pending intent is
7094                // actually executed.  However, we do want to always do the
7095                // security checking for it above.
7096                userId = UserHandle.USER_CURRENT;
7097            }
7098            try {
7099                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7100                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7101                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7102                    if (!UserHandle.isSameApp(callingUid, uid)) {
7103                        String msg = "Permission Denial: getIntentSender() from pid="
7104                            + Binder.getCallingPid()
7105                            + ", uid=" + Binder.getCallingUid()
7106                            + ", (need uid=" + uid + ")"
7107                            + " is not allowed to send as package " + packageName;
7108                        Slog.w(TAG, msg);
7109                        throw new SecurityException(msg);
7110                    }
7111                }
7112
7113                return getIntentSenderLocked(type, packageName, callingUid, userId,
7114                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7115
7116            } catch (RemoteException e) {
7117                throw new SecurityException(e);
7118            }
7119        }
7120    }
7121
7122    IIntentSender getIntentSenderLocked(int type, String packageName,
7123            int callingUid, int userId, IBinder token, String resultWho,
7124            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7125            Bundle bOptions) {
7126        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7127        ActivityRecord activity = null;
7128        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7129            activity = ActivityRecord.isInStackLocked(token);
7130            if (activity == null) {
7131                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7132                return null;
7133            }
7134            if (activity.finishing) {
7135                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7136                return null;
7137            }
7138        }
7139
7140        // We're going to be splicing together extras before sending, so we're
7141        // okay poking into any contained extras.
7142        if (intents != null) {
7143            for (int i = 0; i < intents.length; i++) {
7144                intents[i].setDefusable(true);
7145            }
7146        }
7147        Bundle.setDefusable(bOptions, true);
7148
7149        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7150        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7151        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7152        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7153                |PendingIntent.FLAG_UPDATE_CURRENT);
7154
7155        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7156                type, packageName, activity, resultWho,
7157                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7158        WeakReference<PendingIntentRecord> ref;
7159        ref = mIntentSenderRecords.get(key);
7160        PendingIntentRecord rec = ref != null ? ref.get() : null;
7161        if (rec != null) {
7162            if (!cancelCurrent) {
7163                if (updateCurrent) {
7164                    if (rec.key.requestIntent != null) {
7165                        rec.key.requestIntent.replaceExtras(intents != null ?
7166                                intents[intents.length - 1] : null);
7167                    }
7168                    if (intents != null) {
7169                        intents[intents.length-1] = rec.key.requestIntent;
7170                        rec.key.allIntents = intents;
7171                        rec.key.allResolvedTypes = resolvedTypes;
7172                    } else {
7173                        rec.key.allIntents = null;
7174                        rec.key.allResolvedTypes = null;
7175                    }
7176                }
7177                return rec;
7178            }
7179            rec.canceled = true;
7180            mIntentSenderRecords.remove(key);
7181        }
7182        if (noCreate) {
7183            return rec;
7184        }
7185        rec = new PendingIntentRecord(this, key, callingUid);
7186        mIntentSenderRecords.put(key, rec.ref);
7187        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7188            if (activity.pendingResults == null) {
7189                activity.pendingResults
7190                        = new HashSet<WeakReference<PendingIntentRecord>>();
7191            }
7192            activity.pendingResults.add(rec.ref);
7193        }
7194        return rec;
7195    }
7196
7197    @Override
7198    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7199            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7200        if (target instanceof PendingIntentRecord) {
7201            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7202                    finishedReceiver, requiredPermission, options);
7203        } else {
7204            if (intent == null) {
7205                // Weird case: someone has given us their own custom IIntentSender, and now
7206                // they have someone else trying to send to it but of course this isn't
7207                // really a PendingIntent, so there is no base Intent, and the caller isn't
7208                // supplying an Intent... but we never want to dispatch a null Intent to
7209                // a receiver, so um...  let's make something up.
7210                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7211                intent = new Intent(Intent.ACTION_MAIN);
7212            }
7213            try {
7214                target.send(code, intent, resolvedType, null, requiredPermission, options);
7215            } catch (RemoteException e) {
7216            }
7217            // Platform code can rely on getting a result back when the send is done, but if
7218            // this intent sender is from outside of the system we can't rely on it doing that.
7219            // So instead we don't give it the result receiver, and instead just directly
7220            // report the finish immediately.
7221            if (finishedReceiver != null) {
7222                try {
7223                    finishedReceiver.performReceive(intent, 0,
7224                            null, null, false, false, UserHandle.getCallingUserId());
7225                } catch (RemoteException e) {
7226                }
7227            }
7228            return 0;
7229        }
7230    }
7231
7232    /**
7233     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7234     *
7235     * <p>{@code callerUid} must be allowed to request such whitelist by calling
7236     * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7237     */
7238    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7239        if (DEBUG_WHITELISTS) {
7240            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7241                    + targetUid + ", " + duration + ")");
7242        }
7243        synchronized (mPidsSelfLocked) {
7244            final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7245            if (pr == null) {
7246                Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7247                return;
7248            }
7249            if (!pr.whitelistManager) {
7250                if (DEBUG_WHITELISTS) {
7251                    Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7252                            + callerPid + " is not allowed");
7253                }
7254                return;
7255            }
7256        }
7257
7258        final long token = Binder.clearCallingIdentity();
7259        try {
7260            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7261                    true, "pe from uid:" + callerUid);
7262        } finally {
7263            Binder.restoreCallingIdentity(token);
7264        }
7265    }
7266
7267    @Override
7268    public void cancelIntentSender(IIntentSender sender) {
7269        if (!(sender instanceof PendingIntentRecord)) {
7270            return;
7271        }
7272        synchronized(this) {
7273            PendingIntentRecord rec = (PendingIntentRecord)sender;
7274            try {
7275                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7276                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7277                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7278                    String msg = "Permission Denial: cancelIntentSender() from pid="
7279                        + Binder.getCallingPid()
7280                        + ", uid=" + Binder.getCallingUid()
7281                        + " is not allowed to cancel packges "
7282                        + rec.key.packageName;
7283                    Slog.w(TAG, msg);
7284                    throw new SecurityException(msg);
7285                }
7286            } catch (RemoteException e) {
7287                throw new SecurityException(e);
7288            }
7289            cancelIntentSenderLocked(rec, true);
7290        }
7291    }
7292
7293    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7294        rec.canceled = true;
7295        mIntentSenderRecords.remove(rec.key);
7296        if (cleanActivity && rec.key.activity != null) {
7297            rec.key.activity.pendingResults.remove(rec.ref);
7298        }
7299    }
7300
7301    @Override
7302    public String getPackageForIntentSender(IIntentSender pendingResult) {
7303        if (!(pendingResult instanceof PendingIntentRecord)) {
7304            return null;
7305        }
7306        try {
7307            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7308            return res.key.packageName;
7309        } catch (ClassCastException e) {
7310        }
7311        return null;
7312    }
7313
7314    @Override
7315    public int getUidForIntentSender(IIntentSender sender) {
7316        if (sender instanceof PendingIntentRecord) {
7317            try {
7318                PendingIntentRecord res = (PendingIntentRecord)sender;
7319                return res.uid;
7320            } catch (ClassCastException e) {
7321            }
7322        }
7323        return -1;
7324    }
7325
7326    @Override
7327    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7328        if (!(pendingResult instanceof PendingIntentRecord)) {
7329            return false;
7330        }
7331        try {
7332            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7333            if (res.key.allIntents == null) {
7334                return false;
7335            }
7336            for (int i=0; i<res.key.allIntents.length; i++) {
7337                Intent intent = res.key.allIntents[i];
7338                if (intent.getPackage() != null && intent.getComponent() != null) {
7339                    return false;
7340                }
7341            }
7342            return true;
7343        } catch (ClassCastException e) {
7344        }
7345        return false;
7346    }
7347
7348    @Override
7349    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7350        if (!(pendingResult instanceof PendingIntentRecord)) {
7351            return false;
7352        }
7353        try {
7354            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7355            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7356                return true;
7357            }
7358            return false;
7359        } catch (ClassCastException e) {
7360        }
7361        return false;
7362    }
7363
7364    @Override
7365    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7366        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7367                "getIntentForIntentSender()");
7368        if (!(pendingResult instanceof PendingIntentRecord)) {
7369            return null;
7370        }
7371        try {
7372            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7373            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7374        } catch (ClassCastException e) {
7375        }
7376        return null;
7377    }
7378
7379    @Override
7380    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7381        if (!(pendingResult instanceof PendingIntentRecord)) {
7382            return null;
7383        }
7384        try {
7385            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7386            synchronized (this) {
7387                return getTagForIntentSenderLocked(res, prefix);
7388            }
7389        } catch (ClassCastException e) {
7390        }
7391        return null;
7392    }
7393
7394    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7395        final Intent intent = res.key.requestIntent;
7396        if (intent != null) {
7397            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7398                    || res.lastTagPrefix.equals(prefix))) {
7399                return res.lastTag;
7400            }
7401            res.lastTagPrefix = prefix;
7402            final StringBuilder sb = new StringBuilder(128);
7403            if (prefix != null) {
7404                sb.append(prefix);
7405            }
7406            if (intent.getAction() != null) {
7407                sb.append(intent.getAction());
7408            } else if (intent.getComponent() != null) {
7409                intent.getComponent().appendShortString(sb);
7410            } else {
7411                sb.append("?");
7412            }
7413            return res.lastTag = sb.toString();
7414        }
7415        return null;
7416    }
7417
7418    @Override
7419    public void setProcessLimit(int max) {
7420        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7421                "setProcessLimit()");
7422        synchronized (this) {
7423            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7424            mProcessLimitOverride = max;
7425        }
7426        trimApplications();
7427    }
7428
7429    @Override
7430    public int getProcessLimit() {
7431        synchronized (this) {
7432            return mProcessLimitOverride;
7433        }
7434    }
7435
7436    void foregroundTokenDied(ForegroundToken token) {
7437        synchronized (ActivityManagerService.this) {
7438            synchronized (mPidsSelfLocked) {
7439                ForegroundToken cur
7440                    = mForegroundProcesses.get(token.pid);
7441                if (cur != token) {
7442                    return;
7443                }
7444                mForegroundProcesses.remove(token.pid);
7445                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7446                if (pr == null) {
7447                    return;
7448                }
7449                pr.forcingToForeground = null;
7450                updateProcessForegroundLocked(pr, false, false);
7451            }
7452            updateOomAdjLocked();
7453        }
7454    }
7455
7456    @Override
7457    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7458        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7459                "setProcessForeground()");
7460        synchronized(this) {
7461            boolean changed = false;
7462
7463            synchronized (mPidsSelfLocked) {
7464                ProcessRecord pr = mPidsSelfLocked.get(pid);
7465                if (pr == null && isForeground) {
7466                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7467                    return;
7468                }
7469                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7470                if (oldToken != null) {
7471                    oldToken.token.unlinkToDeath(oldToken, 0);
7472                    mForegroundProcesses.remove(pid);
7473                    if (pr != null) {
7474                        pr.forcingToForeground = null;
7475                    }
7476                    changed = true;
7477                }
7478                if (isForeground && token != null) {
7479                    ForegroundToken newToken = new ForegroundToken() {
7480                        @Override
7481                        public void binderDied() {
7482                            foregroundTokenDied(this);
7483                        }
7484                    };
7485                    newToken.pid = pid;
7486                    newToken.token = token;
7487                    try {
7488                        token.linkToDeath(newToken, 0);
7489                        mForegroundProcesses.put(pid, newToken);
7490                        pr.forcingToForeground = token;
7491                        changed = true;
7492                    } catch (RemoteException e) {
7493                        // If the process died while doing this, we will later
7494                        // do the cleanup with the process death link.
7495                    }
7496                }
7497            }
7498
7499            if (changed) {
7500                updateOomAdjLocked();
7501            }
7502        }
7503    }
7504
7505    @Override
7506    public boolean isAppForeground(int uid) throws RemoteException {
7507        synchronized (this) {
7508            UidRecord uidRec = mActiveUids.get(uid);
7509            if (uidRec == null || uidRec.idle) {
7510                return false;
7511            }
7512            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7513        }
7514    }
7515
7516    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7517    // be guarded by permission checking.
7518    int getUidState(int uid) {
7519        synchronized (this) {
7520            UidRecord uidRec = mActiveUids.get(uid);
7521            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7522        }
7523    }
7524
7525    @Override
7526    public boolean isInMultiWindowMode(IBinder token) {
7527        final long origId = Binder.clearCallingIdentity();
7528        try {
7529            synchronized(this) {
7530                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7531                if (r == null) {
7532                    return false;
7533                }
7534                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7535                return !r.task.mFullscreen;
7536            }
7537        } finally {
7538            Binder.restoreCallingIdentity(origId);
7539        }
7540    }
7541
7542    @Override
7543    public boolean isInPictureInPictureMode(IBinder token) {
7544        final long origId = Binder.clearCallingIdentity();
7545        try {
7546            synchronized(this) {
7547                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7548                if (stack == null) {
7549                    return false;
7550                }
7551                return stack.mStackId == PINNED_STACK_ID;
7552            }
7553        } finally {
7554            Binder.restoreCallingIdentity(origId);
7555        }
7556    }
7557
7558    @Override
7559    public void enterPictureInPictureMode(IBinder token) {
7560        enterPictureInPictureMode(token, DEFAULT_DISPLAY, -1f /* aspectRatio */,
7561                false /* checkAspectRatio */);
7562    }
7563
7564    @Override
7565    public void enterPictureInPictureModeWithAspectRatio(IBinder token, float aspectRatio) {
7566        enterPictureInPictureMode(token, DEFAULT_DISPLAY, aspectRatio, true /* checkAspectRatio */);
7567    }
7568
7569    @Override
7570    public void enterPictureInPictureModeOnMoveToBackground(IBinder token,
7571            boolean enterPictureInPictureOnMoveToBg) {
7572        final long origId = Binder.clearCallingIdentity();
7573        try {
7574            synchronized(this) {
7575                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7576                        "enterPictureInPictureModeOnMoveToBackground", token, -1f /* aspectRatio */,
7577                        false /* checkAspectRatio */, false /* checkActivityVisibility */);
7578
7579                r.supportsPipOnMoveToBackground = enterPictureInPictureOnMoveToBg;
7580            }
7581        } finally {
7582            Binder.restoreCallingIdentity(origId);
7583        }
7584    }
7585
7586    private void enterPictureInPictureMode(IBinder token, int displayId, float aspectRatio,
7587            boolean checkAspectRatio) {
7588        final long origId = Binder.clearCallingIdentity();
7589        try {
7590            synchronized(this) {
7591                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7592                        "enterPictureInPictureMode", token, aspectRatio, checkAspectRatio,
7593                        true /* checkActivityVisibility */);
7594                final Runnable enterPipRunnable = () -> {
7595                    r.pictureInPictureArgs.aspectRatio = aspectRatio;
7596                    enterPictureInPictureModeLocked(r, displayId, r.pictureInPictureArgs,
7597                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
7598                };
7599
7600                if (isKeyguardLocked()) {
7601                    // If the keyguard is showing or occluded, then try and dismiss it before
7602                    // entering picture-in-picture (this will prompt the user to authenticate if the
7603                    // device is currently locked).
7604                    try {
7605                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7606                            @Override
7607                            public void onDismissError() throws RemoteException {
7608                                // Do nothing
7609                            }
7610
7611                            @Override
7612                            public void onDismissSucceeded() throws RemoteException {
7613                                mHandler.post(enterPipRunnable);
7614                            }
7615
7616                            @Override
7617                            public void onDismissCancelled() throws RemoteException {
7618                                // Do nothing
7619                            }
7620                        });
7621                    } catch (RemoteException e) {
7622                        // Local call
7623                    }
7624                } else {
7625                    // Enter picture in picture immediately otherwise
7626                    enterPipRunnable.run();
7627                }
7628            }
7629        } finally {
7630            Binder.restoreCallingIdentity(origId);
7631        }
7632    }
7633
7634    void enterPictureInPictureModeLocked(ActivityRecord r, int displayId,
7635            PictureInPictureArguments pipArgs, boolean moveHomeStackToFront, String reason) {
7636        final Rect bounds = isValidPictureInPictureAspectRatio(pipArgs.aspectRatio)
7637                ? mWindowManager.getPictureInPictureBounds(displayId, pipArgs.aspectRatio)
7638                : mWindowManager.getPictureInPictureDefaultBounds(displayId);
7639        mStackSupervisor.moveActivityToPinnedStackLocked(r, reason, bounds, moveHomeStackToFront);
7640        mWindowManager.setPictureInPictureActions(pipArgs.userActions);
7641    }
7642
7643    @Override
7644    public void setPictureInPictureAspectRatio(IBinder token, float aspectRatio) {
7645        final long origId = Binder.clearCallingIdentity();
7646        try {
7647            synchronized(this) {
7648                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7649                        "setPictureInPictureAspectRatio", token, aspectRatio,
7650                        true /* checkAspectRatio */, false /* checkActivityVisibility */);
7651
7652                r.pictureInPictureArgs.aspectRatio = aspectRatio;
7653                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7654                    // If the activity is already in picture-in-picture, update the pinned stack now
7655                    mWindowManager.setPictureInPictureAspectRatio(aspectRatio);
7656                }
7657            }
7658        } finally {
7659            Binder.restoreCallingIdentity(origId);
7660        }
7661    }
7662
7663    @Override
7664    public void setPictureInPictureActions(IBinder token, ParceledListSlice actionsList) {
7665        final long origId = Binder.clearCallingIdentity();
7666        try {
7667            synchronized(this) {
7668                final ActivityRecord r = ensureValidPictureInPictureActivityLocked(
7669                        "setPictureInPictureActions", token, -1 /* aspectRatio */,
7670                        false /* checkAspectRatio */, false /* checkActivityVisibility */);
7671
7672                final List<RemoteAction> actions = actionsList.getList();
7673                if (actions.size() > ActivityManager.getMaxNumPictureInPictureActions()) {
7674                    throw new IllegalArgumentException("setPictureInPictureActions: Invalid number"
7675                            + " of picture-in-picture actions.  Only a maximum of "
7676                            + ActivityManager.getMaxNumPictureInPictureActions()
7677                            + " actions allowed");
7678                }
7679
7680                r.pictureInPictureArgs.userActions = actions;
7681                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7682                    // If the activity is already in picture-in-picture, update the pinned stack now
7683                    mWindowManager.setPictureInPictureActions(actions);
7684                }
7685            }
7686        } finally {
7687            Binder.restoreCallingIdentity(origId);
7688        }
7689    }
7690
7691    private boolean isValidPictureInPictureAspectRatio(float aspectRatio) {
7692        return mMinPipAspectRatio <= aspectRatio && aspectRatio <= mMaxPipAspectRatio;
7693    }
7694
7695    /**
7696     * Checks the state of the system and the activity associated with the given {@param token} to
7697     * verify that picture-in-picture is supported for that activity.
7698     *
7699     * @param checkAspectRatio whether or not to check {@param aspectRatio} is within a valid range
7700     * @param checkActivityVisibility whether or not to enforce that the activity is currently
7701     *                                visible
7702     *
7703     * @return the activity record for the given {@param token} if all the checks pass.
7704     */
7705    private ActivityRecord ensureValidPictureInPictureActivityLocked(String caller, IBinder token,
7706            float aspectRatio, boolean checkAspectRatio, boolean checkActivityVisibility) {
7707        if (!mSupportsPictureInPicture) {
7708            throw new IllegalStateException(caller
7709                    + ": Device doesn't support picture-in-picture mode.");
7710        }
7711
7712        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7713        if (r == null) {
7714            throw new IllegalStateException(caller
7715                    + ": Can't find activity for token=" + token);
7716        }
7717
7718        if (!r.canEnterPictureInPicture(checkActivityVisibility)) {
7719            throw new IllegalArgumentException(caller
7720                    + ": Current activity does not support picture-in-picture or is not "
7721                    + "visible r=" + r);
7722        }
7723
7724        if (r.getStack().isHomeStack()) {
7725            throw new IllegalStateException(caller
7726                    + ": Activities on the home stack not supported");
7727        }
7728
7729        if (checkAspectRatio && !isValidPictureInPictureAspectRatio(aspectRatio)) {
7730            throw new IllegalArgumentException(String.format(caller
7731                    + ": Aspect ratio is too extreme (must be between %f and %f).",
7732                            mMinPipAspectRatio, mMaxPipAspectRatio));
7733        }
7734
7735        return r;
7736    }
7737
7738    // =========================================================
7739    // PROCESS INFO
7740    // =========================================================
7741
7742    static class ProcessInfoService extends IProcessInfoService.Stub {
7743        final ActivityManagerService mActivityManagerService;
7744        ProcessInfoService(ActivityManagerService activityManagerService) {
7745            mActivityManagerService = activityManagerService;
7746        }
7747
7748        @Override
7749        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7750            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7751                    /*in*/ pids, /*out*/ states, null);
7752        }
7753
7754        @Override
7755        public void getProcessStatesAndOomScoresFromPids(
7756                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7757            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7758                    /*in*/ pids, /*out*/ states, /*out*/ scores);
7759        }
7760    }
7761
7762    /**
7763     * For each PID in the given input array, write the current process state
7764     * for that process into the states array, or -1 to indicate that no
7765     * process with the given PID exists. If scores array is provided, write
7766     * the oom score for the process into the scores array, with INVALID_ADJ
7767     * indicating the PID doesn't exist.
7768     */
7769    public void getProcessStatesAndOomScoresForPIDs(
7770            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7771        if (scores != null) {
7772            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7773                    "getProcessStatesAndOomScoresForPIDs()");
7774        }
7775
7776        if (pids == null) {
7777            throw new NullPointerException("pids");
7778        } else if (states == null) {
7779            throw new NullPointerException("states");
7780        } else if (pids.length != states.length) {
7781            throw new IllegalArgumentException("pids and states arrays have different lengths!");
7782        } else if (scores != null && pids.length != scores.length) {
7783            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7784        }
7785
7786        synchronized (mPidsSelfLocked) {
7787            for (int i = 0; i < pids.length; i++) {
7788                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7789                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7790                        pr.curProcState;
7791                if (scores != null) {
7792                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7793                }
7794            }
7795        }
7796    }
7797
7798    // =========================================================
7799    // PERMISSIONS
7800    // =========================================================
7801
7802    static class PermissionController extends IPermissionController.Stub {
7803        ActivityManagerService mActivityManagerService;
7804        PermissionController(ActivityManagerService activityManagerService) {
7805            mActivityManagerService = activityManagerService;
7806        }
7807
7808        @Override
7809        public boolean checkPermission(String permission, int pid, int uid) {
7810            return mActivityManagerService.checkPermission(permission, pid,
7811                    uid) == PackageManager.PERMISSION_GRANTED;
7812        }
7813
7814        @Override
7815        public String[] getPackagesForUid(int uid) {
7816            return mActivityManagerService.mContext.getPackageManager()
7817                    .getPackagesForUid(uid);
7818        }
7819
7820        @Override
7821        public boolean isRuntimePermission(String permission) {
7822            try {
7823                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7824                        .getPermissionInfo(permission, 0);
7825                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
7826                        == PermissionInfo.PROTECTION_DANGEROUS;
7827            } catch (NameNotFoundException nnfe) {
7828                Slog.e(TAG, "No such permission: "+ permission, nnfe);
7829            }
7830            return false;
7831        }
7832    }
7833
7834    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7835        @Override
7836        public int checkComponentPermission(String permission, int pid, int uid,
7837                int owningUid, boolean exported) {
7838            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7839                    owningUid, exported);
7840        }
7841
7842        @Override
7843        public Object getAMSLock() {
7844            return ActivityManagerService.this;
7845        }
7846    }
7847
7848    /**
7849     * This can be called with or without the global lock held.
7850     */
7851    int checkComponentPermission(String permission, int pid, int uid,
7852            int owningUid, boolean exported) {
7853        if (pid == MY_PID) {
7854            return PackageManager.PERMISSION_GRANTED;
7855        }
7856        return ActivityManager.checkComponentPermission(permission, uid,
7857                owningUid, exported);
7858    }
7859
7860    /**
7861     * As the only public entry point for permissions checking, this method
7862     * can enforce the semantic that requesting a check on a null global
7863     * permission is automatically denied.  (Internally a null permission
7864     * string is used when calling {@link #checkComponentPermission} in cases
7865     * when only uid-based security is needed.)
7866     *
7867     * This can be called with or without the global lock held.
7868     */
7869    @Override
7870    public int checkPermission(String permission, int pid, int uid) {
7871        if (permission == null) {
7872            return PackageManager.PERMISSION_DENIED;
7873        }
7874        return checkComponentPermission(permission, pid, uid, -1, true);
7875    }
7876
7877    @Override
7878    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7879        if (permission == null) {
7880            return PackageManager.PERMISSION_DENIED;
7881        }
7882
7883        // We might be performing an operation on behalf of an indirect binder
7884        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7885        // client identity accordingly before proceeding.
7886        Identity tlsIdentity = sCallerIdentity.get();
7887        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7888            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7889                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7890            uid = tlsIdentity.uid;
7891            pid = tlsIdentity.pid;
7892        }
7893
7894        return checkComponentPermission(permission, pid, uid, -1, true);
7895    }
7896
7897    /**
7898     * Binder IPC calls go through the public entry point.
7899     * This can be called with or without the global lock held.
7900     */
7901    int checkCallingPermission(String permission) {
7902        return checkPermission(permission,
7903                Binder.getCallingPid(),
7904                UserHandle.getAppId(Binder.getCallingUid()));
7905    }
7906
7907    /**
7908     * This can be called with or without the global lock held.
7909     */
7910    void enforceCallingPermission(String permission, String func) {
7911        if (checkCallingPermission(permission)
7912                == PackageManager.PERMISSION_GRANTED) {
7913            return;
7914        }
7915
7916        String msg = "Permission Denial: " + func + " from pid="
7917                + Binder.getCallingPid()
7918                + ", uid=" + Binder.getCallingUid()
7919                + " requires " + permission;
7920        Slog.w(TAG, msg);
7921        throw new SecurityException(msg);
7922    }
7923
7924    /**
7925     * Determine if UID is holding permissions required to access {@link Uri} in
7926     * the given {@link ProviderInfo}. Final permission checking is always done
7927     * in {@link ContentProvider}.
7928     */
7929    private final boolean checkHoldingPermissionsLocked(
7930            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7931        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7932                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7933        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7934            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7935                    != PERMISSION_GRANTED) {
7936                return false;
7937            }
7938        }
7939        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7940    }
7941
7942    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7943            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7944        if (pi.applicationInfo.uid == uid) {
7945            return true;
7946        } else if (!pi.exported) {
7947            return false;
7948        }
7949
7950        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7951        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7952        try {
7953            // check if target holds top-level <provider> permissions
7954            if (!readMet && pi.readPermission != null && considerUidPermissions
7955                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7956                readMet = true;
7957            }
7958            if (!writeMet && pi.writePermission != null && considerUidPermissions
7959                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7960                writeMet = true;
7961            }
7962
7963            // track if unprotected read/write is allowed; any denied
7964            // <path-permission> below removes this ability
7965            boolean allowDefaultRead = pi.readPermission == null;
7966            boolean allowDefaultWrite = pi.writePermission == null;
7967
7968            // check if target holds any <path-permission> that match uri
7969            final PathPermission[] pps = pi.pathPermissions;
7970            if (pps != null) {
7971                final String path = grantUri.uri.getPath();
7972                int i = pps.length;
7973                while (i > 0 && (!readMet || !writeMet)) {
7974                    i--;
7975                    PathPermission pp = pps[i];
7976                    if (pp.match(path)) {
7977                        if (!readMet) {
7978                            final String pprperm = pp.getReadPermission();
7979                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7980                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
7981                                    + ": match=" + pp.match(path)
7982                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7983                            if (pprperm != null) {
7984                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7985                                        == PERMISSION_GRANTED) {
7986                                    readMet = true;
7987                                } else {
7988                                    allowDefaultRead = false;
7989                                }
7990                            }
7991                        }
7992                        if (!writeMet) {
7993                            final String ppwperm = pp.getWritePermission();
7994                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7995                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
7996                                    + ": match=" + pp.match(path)
7997                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7998                            if (ppwperm != null) {
7999                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8000                                        == PERMISSION_GRANTED) {
8001                                    writeMet = true;
8002                                } else {
8003                                    allowDefaultWrite = false;
8004                                }
8005                            }
8006                        }
8007                    }
8008                }
8009            }
8010
8011            // grant unprotected <provider> read/write, if not blocked by
8012            // <path-permission> above
8013            if (allowDefaultRead) readMet = true;
8014            if (allowDefaultWrite) writeMet = true;
8015
8016        } catch (RemoteException e) {
8017            return false;
8018        }
8019
8020        return readMet && writeMet;
8021    }
8022
8023    public int getAppStartMode(int uid, String packageName) {
8024        synchronized (this) {
8025            return checkAllowBackgroundLocked(uid, packageName, -1, false);
8026        }
8027    }
8028
8029    int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
8030            boolean alwaysRestrict) {
8031        UidRecord uidRec = mActiveUids.get(uid);
8032        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8033            boolean ephemeral;
8034            if (uidRec == null) {
8035                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8036                        UserHandle.getUserId(uid), packageName);
8037            } else {
8038                ephemeral = uidRec.ephemeral;
8039            }
8040
8041            if (ephemeral) {
8042                // We are hard-core about ephemeral apps not running in the background.
8043                return ActivityManager.APP_START_MODE_DISABLED;
8044            } else {
8045                if (callingPid >= 0) {
8046                    ProcessRecord proc;
8047                    synchronized (mPidsSelfLocked) {
8048                        proc = mPidsSelfLocked.get(callingPid);
8049                    }
8050                    if (proc != null && proc.curProcState
8051                            < ActivityManager.PROCESS_STATE_RECEIVER) {
8052                        // Whoever is instigating this is in the foreground, so we will allow it
8053                        // to go through.
8054                        return ActivityManager.APP_START_MODE_NORMAL;
8055                    }
8056                }
8057                if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
8058                        packageName) != AppOpsManager.MODE_ALLOWED) {
8059                    return ActivityManager.APP_START_MODE_DELAYED;
8060                }
8061            }
8062        }
8063        return ActivityManager.APP_START_MODE_NORMAL;
8064    }
8065
8066    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8067        ProviderInfo pi = null;
8068        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8069        if (cpr != null) {
8070            pi = cpr.info;
8071        } else {
8072            try {
8073                pi = AppGlobals.getPackageManager().resolveContentProvider(
8074                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8075                        userHandle);
8076            } catch (RemoteException ex) {
8077            }
8078        }
8079        return pi;
8080    }
8081
8082    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8083        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8084        if (targetUris != null) {
8085            return targetUris.get(grantUri);
8086        }
8087        return null;
8088    }
8089
8090    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8091            String targetPkg, int targetUid, GrantUri grantUri) {
8092        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8093        if (targetUris == null) {
8094            targetUris = Maps.newArrayMap();
8095            mGrantedUriPermissions.put(targetUid, targetUris);
8096        }
8097
8098        UriPermission perm = targetUris.get(grantUri);
8099        if (perm == null) {
8100            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8101            targetUris.put(grantUri, perm);
8102        }
8103
8104        return perm;
8105    }
8106
8107    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8108            final int modeFlags) {
8109        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8110        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8111                : UriPermission.STRENGTH_OWNED;
8112
8113        // Root gets to do everything.
8114        if (uid == 0) {
8115            return true;
8116        }
8117
8118        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8119        if (perms == null) return false;
8120
8121        // First look for exact match
8122        final UriPermission exactPerm = perms.get(grantUri);
8123        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8124            return true;
8125        }
8126
8127        // No exact match, look for prefixes
8128        final int N = perms.size();
8129        for (int i = 0; i < N; i++) {
8130            final UriPermission perm = perms.valueAt(i);
8131            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8132                    && perm.getStrength(modeFlags) >= minStrength) {
8133                return true;
8134            }
8135        }
8136
8137        return false;
8138    }
8139
8140    /**
8141     * @param uri This uri must NOT contain an embedded userId.
8142     * @param userId The userId in which the uri is to be resolved.
8143     */
8144    @Override
8145    public int checkUriPermission(Uri uri, int pid, int uid,
8146            final int modeFlags, int userId, IBinder callerToken) {
8147        enforceNotIsolatedCaller("checkUriPermission");
8148
8149        // Another redirected-binder-call permissions check as in
8150        // {@link checkPermissionWithToken}.
8151        Identity tlsIdentity = sCallerIdentity.get();
8152        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8153            uid = tlsIdentity.uid;
8154            pid = tlsIdentity.pid;
8155        }
8156
8157        // Our own process gets to do everything.
8158        if (pid == MY_PID) {
8159            return PackageManager.PERMISSION_GRANTED;
8160        }
8161        synchronized (this) {
8162            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8163                    ? PackageManager.PERMISSION_GRANTED
8164                    : PackageManager.PERMISSION_DENIED;
8165        }
8166    }
8167
8168    /**
8169     * Check if the targetPkg can be granted permission to access uri by
8170     * the callingUid using the given modeFlags.  Throws a security exception
8171     * if callingUid is not allowed to do this.  Returns the uid of the target
8172     * if the URI permission grant should be performed; returns -1 if it is not
8173     * needed (for example targetPkg already has permission to access the URI).
8174     * If you already know the uid of the target, you can supply it in
8175     * lastTargetUid else set that to -1.
8176     */
8177    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8178            final int modeFlags, int lastTargetUid) {
8179        if (!Intent.isAccessUriMode(modeFlags)) {
8180            return -1;
8181        }
8182
8183        if (targetPkg != null) {
8184            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8185                    "Checking grant " + targetPkg + " permission to " + grantUri);
8186        }
8187
8188        final IPackageManager pm = AppGlobals.getPackageManager();
8189
8190        // If this is not a content: uri, we can't do anything with it.
8191        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8192            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8193                    "Can't grant URI permission for non-content URI: " + grantUri);
8194            return -1;
8195        }
8196
8197        final String authority = grantUri.uri.getAuthority();
8198        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8199                MATCH_DEBUG_TRIAGED_MISSING);
8200        if (pi == null) {
8201            Slog.w(TAG, "No content provider found for permission check: " +
8202                    grantUri.uri.toSafeString());
8203            return -1;
8204        }
8205
8206        int targetUid = lastTargetUid;
8207        if (targetUid < 0 && targetPkg != null) {
8208            try {
8209                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8210                        UserHandle.getUserId(callingUid));
8211                if (targetUid < 0) {
8212                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8213                            "Can't grant URI permission no uid for: " + targetPkg);
8214                    return -1;
8215                }
8216            } catch (RemoteException ex) {
8217                return -1;
8218            }
8219        }
8220
8221        // If we're extending a persistable grant, then we always need to create
8222        // the grant data structure so that take/release APIs work
8223        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8224            return targetUid;
8225        }
8226
8227        if (targetUid >= 0) {
8228            // First...  does the target actually need this permission?
8229            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8230                // No need to grant the target this permission.
8231                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8232                        "Target " + targetPkg + " already has full permission to " + grantUri);
8233                return -1;
8234            }
8235        } else {
8236            // First...  there is no target package, so can anyone access it?
8237            boolean allowed = pi.exported;
8238            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8239                if (pi.readPermission != null) {
8240                    allowed = false;
8241                }
8242            }
8243            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8244                if (pi.writePermission != null) {
8245                    allowed = false;
8246                }
8247            }
8248            if (allowed) {
8249                return -1;
8250            }
8251        }
8252
8253        /* There is a special cross user grant if:
8254         * - The target is on another user.
8255         * - Apps on the current user can access the uri without any uid permissions.
8256         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8257         * grant uri permissions.
8258         */
8259        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8260                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8261                modeFlags, false /*without considering the uid permissions*/);
8262
8263        // Second...  is the provider allowing granting of URI permissions?
8264        if (!specialCrossUserGrant) {
8265            if (!pi.grantUriPermissions) {
8266                throw new SecurityException("Provider " + pi.packageName
8267                        + "/" + pi.name
8268                        + " does not allow granting of Uri permissions (uri "
8269                        + grantUri + ")");
8270            }
8271            if (pi.uriPermissionPatterns != null) {
8272                final int N = pi.uriPermissionPatterns.length;
8273                boolean allowed = false;
8274                for (int i=0; i<N; i++) {
8275                    if (pi.uriPermissionPatterns[i] != null
8276                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8277                        allowed = true;
8278                        break;
8279                    }
8280                }
8281                if (!allowed) {
8282                    throw new SecurityException("Provider " + pi.packageName
8283                            + "/" + pi.name
8284                            + " does not allow granting of permission to path of Uri "
8285                            + grantUri);
8286                }
8287            }
8288        }
8289
8290        // Third...  does the caller itself have permission to access
8291        // this uri?
8292        final int callingAppId = UserHandle.getAppId(callingUid);
8293        if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8294            Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8295                    + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8296            return -1;
8297        } else {
8298            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8299                // Require they hold a strong enough Uri permission
8300                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8301                    throw new SecurityException("Uid " + callingUid
8302                            + " does not have permission to uri " + grantUri);
8303                }
8304            }
8305        }
8306        return targetUid;
8307    }
8308
8309    /**
8310     * @param uri This uri must NOT contain an embedded userId.
8311     * @param userId The userId in which the uri is to be resolved.
8312     */
8313    @Override
8314    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8315            final int modeFlags, int userId) {
8316        enforceNotIsolatedCaller("checkGrantUriPermission");
8317        synchronized(this) {
8318            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8319                    new GrantUri(userId, uri, false), modeFlags, -1);
8320        }
8321    }
8322
8323    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8324            final int modeFlags, UriPermissionOwner owner) {
8325        if (!Intent.isAccessUriMode(modeFlags)) {
8326            return;
8327        }
8328
8329        // So here we are: the caller has the assumed permission
8330        // to the uri, and the target doesn't.  Let's now give this to
8331        // the target.
8332
8333        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8334                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8335
8336        final String authority = grantUri.uri.getAuthority();
8337        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8338                MATCH_DEBUG_TRIAGED_MISSING);
8339        if (pi == null) {
8340            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8341            return;
8342        }
8343
8344        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8345            grantUri.prefix = true;
8346        }
8347        final UriPermission perm = findOrCreateUriPermissionLocked(
8348                pi.packageName, targetPkg, targetUid, grantUri);
8349        perm.grantModes(modeFlags, owner);
8350    }
8351
8352    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8353            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8354        if (targetPkg == null) {
8355            throw new NullPointerException("targetPkg");
8356        }
8357        int targetUid;
8358        final IPackageManager pm = AppGlobals.getPackageManager();
8359        try {
8360            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8361        } catch (RemoteException ex) {
8362            return;
8363        }
8364
8365        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8366                targetUid);
8367        if (targetUid < 0) {
8368            return;
8369        }
8370
8371        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8372                owner);
8373    }
8374
8375    static class NeededUriGrants extends ArrayList<GrantUri> {
8376        final String targetPkg;
8377        final int targetUid;
8378        final int flags;
8379
8380        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8381            this.targetPkg = targetPkg;
8382            this.targetUid = targetUid;
8383            this.flags = flags;
8384        }
8385    }
8386
8387    /**
8388     * Like checkGrantUriPermissionLocked, but takes an Intent.
8389     */
8390    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8391            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8392        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8393                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8394                + " clip=" + (intent != null ? intent.getClipData() : null)
8395                + " from " + intent + "; flags=0x"
8396                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8397
8398        if (targetPkg == null) {
8399            throw new NullPointerException("targetPkg");
8400        }
8401
8402        if (intent == null) {
8403            return null;
8404        }
8405        Uri data = intent.getData();
8406        ClipData clip = intent.getClipData();
8407        if (data == null && clip == null) {
8408            return null;
8409        }
8410        // Default userId for uris in the intent (if they don't specify it themselves)
8411        int contentUserHint = intent.getContentUserHint();
8412        if (contentUserHint == UserHandle.USER_CURRENT) {
8413            contentUserHint = UserHandle.getUserId(callingUid);
8414        }
8415        final IPackageManager pm = AppGlobals.getPackageManager();
8416        int targetUid;
8417        if (needed != null) {
8418            targetUid = needed.targetUid;
8419        } else {
8420            try {
8421                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8422                        targetUserId);
8423            } catch (RemoteException ex) {
8424                return null;
8425            }
8426            if (targetUid < 0) {
8427                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8428                        "Can't grant URI permission no uid for: " + targetPkg
8429                        + " on user " + targetUserId);
8430                return null;
8431            }
8432        }
8433        if (data != null) {
8434            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8435            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8436                    targetUid);
8437            if (targetUid > 0) {
8438                if (needed == null) {
8439                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8440                }
8441                needed.add(grantUri);
8442            }
8443        }
8444        if (clip != null) {
8445            for (int i=0; i<clip.getItemCount(); i++) {
8446                Uri uri = clip.getItemAt(i).getUri();
8447                if (uri != null) {
8448                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8449                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8450                            targetUid);
8451                    if (targetUid > 0) {
8452                        if (needed == null) {
8453                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8454                        }
8455                        needed.add(grantUri);
8456                    }
8457                } else {
8458                    Intent clipIntent = clip.getItemAt(i).getIntent();
8459                    if (clipIntent != null) {
8460                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8461                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8462                        if (newNeeded != null) {
8463                            needed = newNeeded;
8464                        }
8465                    }
8466                }
8467            }
8468        }
8469
8470        return needed;
8471    }
8472
8473    /**
8474     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8475     */
8476    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8477            UriPermissionOwner owner) {
8478        if (needed != null) {
8479            for (int i=0; i<needed.size(); i++) {
8480                GrantUri grantUri = needed.get(i);
8481                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8482                        grantUri, needed.flags, owner);
8483            }
8484        }
8485    }
8486
8487    void grantUriPermissionFromIntentLocked(int callingUid,
8488            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8489        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8490                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8491        if (needed == null) {
8492            return;
8493        }
8494
8495        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8496    }
8497
8498    /**
8499     * @param uri This uri must NOT contain an embedded userId.
8500     * @param userId The userId in which the uri is to be resolved.
8501     */
8502    @Override
8503    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8504            final int modeFlags, int userId) {
8505        enforceNotIsolatedCaller("grantUriPermission");
8506        GrantUri grantUri = new GrantUri(userId, uri, false);
8507        synchronized(this) {
8508            final ProcessRecord r = getRecordForAppLocked(caller);
8509            if (r == null) {
8510                throw new SecurityException("Unable to find app for caller "
8511                        + caller
8512                        + " when granting permission to uri " + grantUri);
8513            }
8514            if (targetPkg == null) {
8515                throw new IllegalArgumentException("null target");
8516            }
8517            if (grantUri == null) {
8518                throw new IllegalArgumentException("null uri");
8519            }
8520
8521            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8522                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8523                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8524                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8525
8526            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8527                    UserHandle.getUserId(r.uid));
8528        }
8529    }
8530
8531    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8532        if (perm.modeFlags == 0) {
8533            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8534                    perm.targetUid);
8535            if (perms != null) {
8536                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8537                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8538
8539                perms.remove(perm.uri);
8540                if (perms.isEmpty()) {
8541                    mGrantedUriPermissions.remove(perm.targetUid);
8542                }
8543            }
8544        }
8545    }
8546
8547    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8548        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8549                "Revoking all granted permissions to " + grantUri);
8550
8551        final IPackageManager pm = AppGlobals.getPackageManager();
8552        final String authority = grantUri.uri.getAuthority();
8553        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8554                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8555        if (pi == null) {
8556            Slog.w(TAG, "No content provider found for permission revoke: "
8557                    + grantUri.toSafeString());
8558            return;
8559        }
8560
8561        // Does the caller have this permission on the URI?
8562        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8563            // If they don't have direct access to the URI, then revoke any
8564            // ownerless URI permissions that have been granted to them.
8565            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8566            if (perms != null) {
8567                boolean persistChanged = false;
8568                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8569                    final UriPermission perm = it.next();
8570                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8571                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8572                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8573                                "Revoking non-owned " + perm.targetUid
8574                                + " permission to " + perm.uri);
8575                        persistChanged |= perm.revokeModes(
8576                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8577                        if (perm.modeFlags == 0) {
8578                            it.remove();
8579                        }
8580                    }
8581                }
8582                if (perms.isEmpty()) {
8583                    mGrantedUriPermissions.remove(callingUid);
8584                }
8585                if (persistChanged) {
8586                    schedulePersistUriGrants();
8587                }
8588            }
8589            return;
8590        }
8591
8592        boolean persistChanged = false;
8593
8594        // Go through all of the permissions and remove any that match.
8595        int N = mGrantedUriPermissions.size();
8596        for (int i = 0; i < N; i++) {
8597            final int targetUid = mGrantedUriPermissions.keyAt(i);
8598            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8599
8600            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8601                final UriPermission perm = it.next();
8602                if (perm.uri.sourceUserId == grantUri.sourceUserId
8603                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8604                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8605                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
8606                    persistChanged |= perm.revokeModes(
8607                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8608                    if (perm.modeFlags == 0) {
8609                        it.remove();
8610                    }
8611                }
8612            }
8613
8614            if (perms.isEmpty()) {
8615                mGrantedUriPermissions.remove(targetUid);
8616                N--;
8617                i--;
8618            }
8619        }
8620
8621        if (persistChanged) {
8622            schedulePersistUriGrants();
8623        }
8624    }
8625
8626    /**
8627     * @param uri This uri must NOT contain an embedded userId.
8628     * @param userId The userId in which the uri is to be resolved.
8629     */
8630    @Override
8631    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8632            int userId) {
8633        enforceNotIsolatedCaller("revokeUriPermission");
8634        synchronized(this) {
8635            final ProcessRecord r = getRecordForAppLocked(caller);
8636            if (r == null) {
8637                throw new SecurityException("Unable to find app for caller "
8638                        + caller
8639                        + " when revoking permission to uri " + uri);
8640            }
8641            if (uri == null) {
8642                Slog.w(TAG, "revokeUriPermission: null uri");
8643                return;
8644            }
8645
8646            if (!Intent.isAccessUriMode(modeFlags)) {
8647                return;
8648            }
8649
8650            final String authority = uri.getAuthority();
8651            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8652                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8653            if (pi == null) {
8654                Slog.w(TAG, "No content provider found for permission revoke: "
8655                        + uri.toSafeString());
8656                return;
8657            }
8658
8659            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8660        }
8661    }
8662
8663    /**
8664     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8665     * given package.
8666     *
8667     * @param packageName Package name to match, or {@code null} to apply to all
8668     *            packages.
8669     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8670     *            to all users.
8671     * @param persistable If persistable grants should be removed.
8672     */
8673    private void removeUriPermissionsForPackageLocked(
8674            String packageName, int userHandle, boolean persistable) {
8675        if (userHandle == UserHandle.USER_ALL && packageName == null) {
8676            throw new IllegalArgumentException("Must narrow by either package or user");
8677        }
8678
8679        boolean persistChanged = false;
8680
8681        int N = mGrantedUriPermissions.size();
8682        for (int i = 0; i < N; i++) {
8683            final int targetUid = mGrantedUriPermissions.keyAt(i);
8684            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8685
8686            // Only inspect grants matching user
8687            if (userHandle == UserHandle.USER_ALL
8688                    || userHandle == UserHandle.getUserId(targetUid)) {
8689                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8690                    final UriPermission perm = it.next();
8691
8692                    // Only inspect grants matching package
8693                    if (packageName == null || perm.sourcePkg.equals(packageName)
8694                            || perm.targetPkg.equals(packageName)) {
8695                        // Hacky solution as part of fixing a security bug; ignore
8696                        // grants associated with DownloadManager so we don't have
8697                        // to immediately launch it to regrant the permissions
8698                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8699                                && !persistable) continue;
8700
8701                        persistChanged |= perm.revokeModes(persistable
8702                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8703
8704                        // Only remove when no modes remain; any persisted grants
8705                        // will keep this alive.
8706                        if (perm.modeFlags == 0) {
8707                            it.remove();
8708                        }
8709                    }
8710                }
8711
8712                if (perms.isEmpty()) {
8713                    mGrantedUriPermissions.remove(targetUid);
8714                    N--;
8715                    i--;
8716                }
8717            }
8718        }
8719
8720        if (persistChanged) {
8721            schedulePersistUriGrants();
8722        }
8723    }
8724
8725    @Override
8726    public IBinder newUriPermissionOwner(String name) {
8727        enforceNotIsolatedCaller("newUriPermissionOwner");
8728        synchronized(this) {
8729            UriPermissionOwner owner = new UriPermissionOwner(this, name);
8730            return owner.getExternalTokenLocked();
8731        }
8732    }
8733
8734    @Override
8735    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8736        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8737        synchronized(this) {
8738            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8739            if (r == null) {
8740                throw new IllegalArgumentException("Activity does not exist; token="
8741                        + activityToken);
8742            }
8743            return r.getUriPermissionsLocked().getExternalTokenLocked();
8744        }
8745    }
8746    /**
8747     * @param uri This uri must NOT contain an embedded userId.
8748     * @param sourceUserId The userId in which the uri is to be resolved.
8749     * @param targetUserId The userId of the app that receives the grant.
8750     */
8751    @Override
8752    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8753            final int modeFlags, int sourceUserId, int targetUserId) {
8754        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8755                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8756                "grantUriPermissionFromOwner", null);
8757        synchronized(this) {
8758            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8759            if (owner == null) {
8760                throw new IllegalArgumentException("Unknown owner: " + token);
8761            }
8762            if (fromUid != Binder.getCallingUid()) {
8763                if (Binder.getCallingUid() != Process.myUid()) {
8764                    // Only system code can grant URI permissions on behalf
8765                    // of other users.
8766                    throw new SecurityException("nice try");
8767                }
8768            }
8769            if (targetPkg == null) {
8770                throw new IllegalArgumentException("null target");
8771            }
8772            if (uri == null) {
8773                throw new IllegalArgumentException("null uri");
8774            }
8775
8776            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8777                    modeFlags, owner, targetUserId);
8778        }
8779    }
8780
8781    /**
8782     * @param uri This uri must NOT contain an embedded userId.
8783     * @param userId The userId in which the uri is to be resolved.
8784     */
8785    @Override
8786    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8787        synchronized(this) {
8788            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8789            if (owner == null) {
8790                throw new IllegalArgumentException("Unknown owner: " + token);
8791            }
8792
8793            if (uri == null) {
8794                owner.removeUriPermissionsLocked(mode);
8795            } else {
8796                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8797                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8798            }
8799        }
8800    }
8801
8802    private void schedulePersistUriGrants() {
8803        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8804            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8805                    10 * DateUtils.SECOND_IN_MILLIS);
8806        }
8807    }
8808
8809    private void writeGrantedUriPermissions() {
8810        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8811
8812        // Snapshot permissions so we can persist without lock
8813        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8814        synchronized (this) {
8815            final int size = mGrantedUriPermissions.size();
8816            for (int i = 0; i < size; i++) {
8817                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8818                for (UriPermission perm : perms.values()) {
8819                    if (perm.persistedModeFlags != 0) {
8820                        persist.add(perm.snapshot());
8821                    }
8822                }
8823            }
8824        }
8825
8826        FileOutputStream fos = null;
8827        try {
8828            fos = mGrantFile.startWrite();
8829
8830            XmlSerializer out = new FastXmlSerializer();
8831            out.setOutput(fos, StandardCharsets.UTF_8.name());
8832            out.startDocument(null, true);
8833            out.startTag(null, TAG_URI_GRANTS);
8834            for (UriPermission.Snapshot perm : persist) {
8835                out.startTag(null, TAG_URI_GRANT);
8836                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8837                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8838                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8839                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8840                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8841                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8842                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8843                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8844                out.endTag(null, TAG_URI_GRANT);
8845            }
8846            out.endTag(null, TAG_URI_GRANTS);
8847            out.endDocument();
8848
8849            mGrantFile.finishWrite(fos);
8850        } catch (IOException e) {
8851            if (fos != null) {
8852                mGrantFile.failWrite(fos);
8853            }
8854        }
8855    }
8856
8857    private void readGrantedUriPermissionsLocked() {
8858        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8859
8860        final long now = System.currentTimeMillis();
8861
8862        FileInputStream fis = null;
8863        try {
8864            fis = mGrantFile.openRead();
8865            final XmlPullParser in = Xml.newPullParser();
8866            in.setInput(fis, StandardCharsets.UTF_8.name());
8867
8868            int type;
8869            while ((type = in.next()) != END_DOCUMENT) {
8870                final String tag = in.getName();
8871                if (type == START_TAG) {
8872                    if (TAG_URI_GRANT.equals(tag)) {
8873                        final int sourceUserId;
8874                        final int targetUserId;
8875                        final int userHandle = readIntAttribute(in,
8876                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
8877                        if (userHandle != UserHandle.USER_NULL) {
8878                            // For backwards compatibility.
8879                            sourceUserId = userHandle;
8880                            targetUserId = userHandle;
8881                        } else {
8882                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8883                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8884                        }
8885                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8886                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8887                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8888                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8889                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8890                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8891
8892                        // Sanity check that provider still belongs to source package
8893                        // Both direct boot aware and unaware packages are fine as we
8894                        // will do filtering at query time to avoid multiple parsing.
8895                        final ProviderInfo pi = getProviderInfoLocked(
8896                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8897                                        | MATCH_DIRECT_BOOT_UNAWARE);
8898                        if (pi != null && sourcePkg.equals(pi.packageName)) {
8899                            int targetUid = -1;
8900                            try {
8901                                targetUid = AppGlobals.getPackageManager().getPackageUid(
8902                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8903                            } catch (RemoteException e) {
8904                            }
8905                            if (targetUid != -1) {
8906                                final UriPermission perm = findOrCreateUriPermissionLocked(
8907                                        sourcePkg, targetPkg, targetUid,
8908                                        new GrantUri(sourceUserId, uri, prefix));
8909                                perm.initPersistedModes(modeFlags, createdTime);
8910                            }
8911                        } else {
8912                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8913                                    + " but instead found " + pi);
8914                        }
8915                    }
8916                }
8917            }
8918        } catch (FileNotFoundException e) {
8919            // Missing grants is okay
8920        } catch (IOException e) {
8921            Slog.wtf(TAG, "Failed reading Uri grants", e);
8922        } catch (XmlPullParserException e) {
8923            Slog.wtf(TAG, "Failed reading Uri grants", e);
8924        } finally {
8925            IoUtils.closeQuietly(fis);
8926        }
8927    }
8928
8929    /**
8930     * @param uri This uri must NOT contain an embedded userId.
8931     * @param userId The userId in which the uri is to be resolved.
8932     */
8933    @Override
8934    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8935        enforceNotIsolatedCaller("takePersistableUriPermission");
8936
8937        Preconditions.checkFlagsArgument(modeFlags,
8938                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8939
8940        synchronized (this) {
8941            final int callingUid = Binder.getCallingUid();
8942            boolean persistChanged = false;
8943            GrantUri grantUri = new GrantUri(userId, uri, false);
8944
8945            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8946                    new GrantUri(userId, uri, false));
8947            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8948                    new GrantUri(userId, uri, true));
8949
8950            final boolean exactValid = (exactPerm != null)
8951                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8952            final boolean prefixValid = (prefixPerm != null)
8953                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8954
8955            if (!(exactValid || prefixValid)) {
8956                throw new SecurityException("No persistable permission grants found for UID "
8957                        + callingUid + " and Uri " + grantUri.toSafeString());
8958            }
8959
8960            if (exactValid) {
8961                persistChanged |= exactPerm.takePersistableModes(modeFlags);
8962            }
8963            if (prefixValid) {
8964                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8965            }
8966
8967            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8968
8969            if (persistChanged) {
8970                schedulePersistUriGrants();
8971            }
8972        }
8973    }
8974
8975    /**
8976     * @param uri This uri must NOT contain an embedded userId.
8977     * @param userId The userId in which the uri is to be resolved.
8978     */
8979    @Override
8980    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8981        enforceNotIsolatedCaller("releasePersistableUriPermission");
8982
8983        Preconditions.checkFlagsArgument(modeFlags,
8984                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8985
8986        synchronized (this) {
8987            final int callingUid = Binder.getCallingUid();
8988            boolean persistChanged = false;
8989
8990            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8991                    new GrantUri(userId, uri, false));
8992            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8993                    new GrantUri(userId, uri, true));
8994            if (exactPerm == null && prefixPerm == null) {
8995                throw new SecurityException("No permission grants found for UID " + callingUid
8996                        + " and Uri " + uri.toSafeString());
8997            }
8998
8999            if (exactPerm != null) {
9000                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9001                removeUriPermissionIfNeededLocked(exactPerm);
9002            }
9003            if (prefixPerm != null) {
9004                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9005                removeUriPermissionIfNeededLocked(prefixPerm);
9006            }
9007
9008            if (persistChanged) {
9009                schedulePersistUriGrants();
9010            }
9011        }
9012    }
9013
9014    /**
9015     * Prune any older {@link UriPermission} for the given UID until outstanding
9016     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9017     *
9018     * @return if any mutations occured that require persisting.
9019     */
9020    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9021        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9022        if (perms == null) return false;
9023        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9024
9025        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9026        for (UriPermission perm : perms.values()) {
9027            if (perm.persistedModeFlags != 0) {
9028                persisted.add(perm);
9029            }
9030        }
9031
9032        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9033        if (trimCount <= 0) return false;
9034
9035        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9036        for (int i = 0; i < trimCount; i++) {
9037            final UriPermission perm = persisted.get(i);
9038
9039            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9040                    "Trimming grant created at " + perm.persistedCreateTime);
9041
9042            perm.releasePersistableModes(~0);
9043            removeUriPermissionIfNeededLocked(perm);
9044        }
9045
9046        return true;
9047    }
9048
9049    @Override
9050    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9051            String packageName, boolean incoming) {
9052        enforceNotIsolatedCaller("getPersistedUriPermissions");
9053        Preconditions.checkNotNull(packageName, "packageName");
9054
9055        final int callingUid = Binder.getCallingUid();
9056        final int callingUserId = UserHandle.getUserId(callingUid);
9057        final IPackageManager pm = AppGlobals.getPackageManager();
9058        try {
9059            final int packageUid = pm.getPackageUid(packageName,
9060                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9061            if (packageUid != callingUid) {
9062                throw new SecurityException(
9063                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9064            }
9065        } catch (RemoteException e) {
9066            throw new SecurityException("Failed to verify package name ownership");
9067        }
9068
9069        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9070        synchronized (this) {
9071            if (incoming) {
9072                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9073                        callingUid);
9074                if (perms == null) {
9075                    Slog.w(TAG, "No permission grants found for " + packageName);
9076                } else {
9077                    for (UriPermission perm : perms.values()) {
9078                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9079                            result.add(perm.buildPersistedPublicApiObject());
9080                        }
9081                    }
9082                }
9083            } else {
9084                final int size = mGrantedUriPermissions.size();
9085                for (int i = 0; i < size; i++) {
9086                    final ArrayMap<GrantUri, UriPermission> perms =
9087                            mGrantedUriPermissions.valueAt(i);
9088                    for (UriPermission perm : perms.values()) {
9089                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9090                            result.add(perm.buildPersistedPublicApiObject());
9091                        }
9092                    }
9093                }
9094            }
9095        }
9096        return new ParceledListSlice<android.content.UriPermission>(result);
9097    }
9098
9099    @Override
9100    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9101            String packageName, int userId) {
9102        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9103                "getGrantedUriPermissions");
9104
9105        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9106        synchronized (this) {
9107            final int size = mGrantedUriPermissions.size();
9108            for (int i = 0; i < size; i++) {
9109                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9110                for (UriPermission perm : perms.values()) {
9111                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9112                            && perm.persistedModeFlags != 0) {
9113                        result.add(perm.buildPersistedPublicApiObject());
9114                    }
9115                }
9116            }
9117        }
9118        return new ParceledListSlice<android.content.UriPermission>(result);
9119    }
9120
9121    @Override
9122    public void clearGrantedUriPermissions(String packageName, int userId) {
9123        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9124                "clearGrantedUriPermissions");
9125        removeUriPermissionsForPackageLocked(packageName, userId, true);
9126    }
9127
9128    @Override
9129    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9130        synchronized (this) {
9131            ProcessRecord app =
9132                who != null ? getRecordForAppLocked(who) : null;
9133            if (app == null) return;
9134
9135            Message msg = Message.obtain();
9136            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9137            msg.obj = app;
9138            msg.arg1 = waiting ? 1 : 0;
9139            mUiHandler.sendMessage(msg);
9140        }
9141    }
9142
9143    @Override
9144    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9145        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9146        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9147        outInfo.availMem = Process.getFreeMemory();
9148        outInfo.totalMem = Process.getTotalMemory();
9149        outInfo.threshold = homeAppMem;
9150        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9151        outInfo.hiddenAppThreshold = cachedAppMem;
9152        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9153                ProcessList.SERVICE_ADJ);
9154        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9155                ProcessList.VISIBLE_APP_ADJ);
9156        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9157                ProcessList.FOREGROUND_APP_ADJ);
9158    }
9159
9160    // =========================================================
9161    // TASK MANAGEMENT
9162    // =========================================================
9163
9164    @Override
9165    public List<IBinder> getAppTasks(String callingPackage) {
9166        int callingUid = Binder.getCallingUid();
9167        long ident = Binder.clearCallingIdentity();
9168
9169        synchronized(this) {
9170            ArrayList<IBinder> list = new ArrayList<IBinder>();
9171            try {
9172                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9173
9174                final int N = mRecentTasks.size();
9175                for (int i = 0; i < N; i++) {
9176                    TaskRecord tr = mRecentTasks.get(i);
9177                    // Skip tasks that do not match the caller.  We don't need to verify
9178                    // callingPackage, because we are also limiting to callingUid and know
9179                    // that will limit to the correct security sandbox.
9180                    if (tr.effectiveUid != callingUid) {
9181                        continue;
9182                    }
9183                    Intent intent = tr.getBaseIntent();
9184                    if (intent == null ||
9185                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9186                        continue;
9187                    }
9188                    ActivityManager.RecentTaskInfo taskInfo =
9189                            createRecentTaskInfoFromTaskRecord(tr);
9190                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9191                    list.add(taskImpl.asBinder());
9192                }
9193            } finally {
9194                Binder.restoreCallingIdentity(ident);
9195            }
9196            return list;
9197        }
9198    }
9199
9200    @Override
9201    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9202        final int callingUid = Binder.getCallingUid();
9203        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9204
9205        synchronized(this) {
9206            if (DEBUG_ALL) Slog.v(
9207                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9208
9209            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9210                    callingUid);
9211
9212            // TODO: Improve with MRU list from all ActivityStacks.
9213            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9214        }
9215
9216        return list;
9217    }
9218
9219    /**
9220     * Creates a new RecentTaskInfo from a TaskRecord.
9221     */
9222    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9223        // Update the task description to reflect any changes in the task stack
9224        tr.updateTaskDescription();
9225
9226        // Compose the recent task info
9227        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9228        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9229        rti.persistentId = tr.taskId;
9230        rti.baseIntent = new Intent(tr.getBaseIntent());
9231        rti.origActivity = tr.origActivity;
9232        rti.realActivity = tr.realActivity;
9233        rti.description = tr.lastDescription;
9234        rti.stackId = tr.getStackId();
9235        rti.userId = tr.userId;
9236        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9237        rti.firstActiveTime = tr.firstActiveTime;
9238        rti.lastActiveTime = tr.lastActiveTime;
9239        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9240        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9241        rti.numActivities = 0;
9242        if (tr.mBounds != null) {
9243            rti.bounds = new Rect(tr.mBounds);
9244        }
9245        rti.isDockable = tr.canGoInDockedStack();
9246        rti.resizeMode = tr.mResizeMode;
9247
9248        ActivityRecord base = null;
9249        ActivityRecord top = null;
9250        ActivityRecord tmp;
9251
9252        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9253            tmp = tr.mActivities.get(i);
9254            if (tmp.finishing) {
9255                continue;
9256            }
9257            base = tmp;
9258            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9259                top = base;
9260            }
9261            rti.numActivities++;
9262        }
9263
9264        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9265        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9266
9267        return rti;
9268    }
9269
9270    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9271        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9272                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9273        if (!allowed) {
9274            if (checkPermission(android.Manifest.permission.GET_TASKS,
9275                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9276                // Temporary compatibility: some existing apps on the system image may
9277                // still be requesting the old permission and not switched to the new
9278                // one; if so, we'll still allow them full access.  This means we need
9279                // to see if they are holding the old permission and are a system app.
9280                try {
9281                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9282                        allowed = true;
9283                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9284                                + " is using old GET_TASKS but privileged; allowing");
9285                    }
9286                } catch (RemoteException e) {
9287                }
9288            }
9289        }
9290        if (!allowed) {
9291            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9292                    + " does not hold REAL_GET_TASKS; limiting output");
9293        }
9294        return allowed;
9295    }
9296
9297    @Override
9298    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9299            int userId) {
9300        final int callingUid = Binder.getCallingUid();
9301        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9302                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9303
9304        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9305        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9306        synchronized (this) {
9307            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9308                    callingUid);
9309            final boolean detailed = checkCallingPermission(
9310                    android.Manifest.permission.GET_DETAILED_TASKS)
9311                    == PackageManager.PERMISSION_GRANTED;
9312
9313            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9314                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9315                return ParceledListSlice.emptyList();
9316            }
9317            mRecentTasks.loadUserRecentsLocked(userId);
9318
9319            final int recentsCount = mRecentTasks.size();
9320            ArrayList<ActivityManager.RecentTaskInfo> res =
9321                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9322
9323            final Set<Integer> includedUsers;
9324            if (includeProfiles) {
9325                includedUsers = mUserController.getProfileIds(userId);
9326            } else {
9327                includedUsers = new HashSet<>();
9328            }
9329            includedUsers.add(Integer.valueOf(userId));
9330
9331            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9332                TaskRecord tr = mRecentTasks.get(i);
9333                // Only add calling user or related users recent tasks
9334                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9335                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9336                    continue;
9337                }
9338
9339                if (tr.realActivitySuspended) {
9340                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9341                    continue;
9342                }
9343
9344                // Return the entry if desired by the caller.  We always return
9345                // the first entry, because callers always expect this to be the
9346                // foreground app.  We may filter others if the caller has
9347                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9348                // we should exclude the entry.
9349
9350                if (i == 0
9351                        || withExcluded
9352                        || (tr.intent == null)
9353                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9354                                == 0)) {
9355                    if (!allowed) {
9356                        // If the caller doesn't have the GET_TASKS permission, then only
9357                        // allow them to see a small subset of tasks -- their own and home.
9358                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9359                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9360                            continue;
9361                        }
9362                    }
9363                    final ActivityStack stack = tr.getStack();
9364                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9365                        if (stack != null && stack.isHomeOrRecentsStack()) {
9366                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9367                                    "Skipping, home or recents stack task: " + tr);
9368                            continue;
9369                        }
9370                    }
9371                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9372                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9373                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9374                                    "Skipping, top task in docked stack: " + tr);
9375                            continue;
9376                        }
9377                    }
9378                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9379                        if (stack != null && stack.isPinnedStack()) {
9380                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9381                                    "Skipping, pinned stack task: " + tr);
9382                            continue;
9383                        }
9384                    }
9385                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9386                        // Don't include auto remove tasks that are finished or finishing.
9387                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9388                                "Skipping, auto-remove without activity: " + tr);
9389                        continue;
9390                    }
9391                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9392                            && !tr.isAvailable) {
9393                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9394                                "Skipping, unavail real act: " + tr);
9395                        continue;
9396                    }
9397
9398                    if (!tr.mUserSetupComplete) {
9399                        // Don't include task launched while user is not done setting-up.
9400                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9401                                "Skipping, user setup not complete: " + tr);
9402                        continue;
9403                    }
9404
9405                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9406                    if (!detailed) {
9407                        rti.baseIntent.replaceExtras((Bundle)null);
9408                    }
9409
9410                    res.add(rti);
9411                    maxNum--;
9412                }
9413            }
9414            return new ParceledListSlice<>(res);
9415        }
9416    }
9417
9418    @Override
9419    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9420        synchronized (this) {
9421            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9422                    "getTaskThumbnail()");
9423            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9424                    id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9425            if (tr != null) {
9426                return tr.getTaskThumbnailLocked();
9427            }
9428        }
9429        return null;
9430    }
9431
9432    @Override
9433    public int addAppTask(IBinder activityToken, Intent intent,
9434            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9435        final int callingUid = Binder.getCallingUid();
9436        final long callingIdent = Binder.clearCallingIdentity();
9437
9438        try {
9439            synchronized (this) {
9440                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9441                if (r == null) {
9442                    throw new IllegalArgumentException("Activity does not exist; token="
9443                            + activityToken);
9444                }
9445                ComponentName comp = intent.getComponent();
9446                if (comp == null) {
9447                    throw new IllegalArgumentException("Intent " + intent
9448                            + " must specify explicit component");
9449                }
9450                if (thumbnail.getWidth() != mThumbnailWidth
9451                        || thumbnail.getHeight() != mThumbnailHeight) {
9452                    throw new IllegalArgumentException("Bad thumbnail size: got "
9453                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9454                            + mThumbnailWidth + "x" + mThumbnailHeight);
9455                }
9456                if (intent.getSelector() != null) {
9457                    intent.setSelector(null);
9458                }
9459                if (intent.getSourceBounds() != null) {
9460                    intent.setSourceBounds(null);
9461                }
9462                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9463                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9464                        // The caller has added this as an auto-remove task...  that makes no
9465                        // sense, so turn off auto-remove.
9466                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9467                    }
9468                }
9469                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9470                    mLastAddedTaskActivity = null;
9471                }
9472                ActivityInfo ainfo = mLastAddedTaskActivity;
9473                if (ainfo == null) {
9474                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9475                            comp, 0, UserHandle.getUserId(callingUid));
9476                    if (ainfo.applicationInfo.uid != callingUid) {
9477                        throw new SecurityException(
9478                                "Can't add task for another application: target uid="
9479                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9480                    }
9481                }
9482
9483                TaskRecord task = new TaskRecord(this,
9484                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9485                        ainfo, intent, description, new TaskThumbnailInfo());
9486
9487                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9488                if (trimIdx >= 0) {
9489                    // If this would have caused a trim, then we'll abort because that
9490                    // means it would be added at the end of the list but then just removed.
9491                    return INVALID_TASK_ID;
9492                }
9493
9494                final int N = mRecentTasks.size();
9495                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9496                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9497                    tr.removedFromRecents();
9498                }
9499
9500                task.inRecents = true;
9501                mRecentTasks.add(task);
9502                r.getStack().addTask(task, false, "addAppTask");
9503
9504                task.setLastThumbnailLocked(thumbnail);
9505                task.freeLastThumbnail();
9506                return task.taskId;
9507            }
9508        } finally {
9509            Binder.restoreCallingIdentity(callingIdent);
9510        }
9511    }
9512
9513    @Override
9514    public Point getAppTaskThumbnailSize() {
9515        synchronized (this) {
9516            return new Point(mThumbnailWidth,  mThumbnailHeight);
9517        }
9518    }
9519
9520    @Override
9521    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9522        synchronized (this) {
9523            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9524            if (r != null) {
9525                r.setTaskDescription(td);
9526                r.task.updateTaskDescription();
9527                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
9528            }
9529        }
9530    }
9531
9532    @Override
9533    public void setTaskResizeable(int taskId, int resizeableMode) {
9534        synchronized (this) {
9535            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9536                    taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9537            if (task == null) {
9538                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9539                return;
9540            }
9541            task.setResizeMode(resizeableMode);
9542        }
9543    }
9544
9545    @Override
9546    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9547        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9548        long ident = Binder.clearCallingIdentity();
9549        try {
9550            synchronized (this) {
9551                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9552                if (task == null) {
9553                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9554                    return;
9555                }
9556                // Place the task in the right stack if it isn't there already based on
9557                // the requested bounds.
9558                // The stack transition logic is:
9559                // - a null bounds on a freeform task moves that task to fullscreen
9560                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9561                //   that task to freeform
9562                // - otherwise the task is not moved
9563                int stackId = task.getStackId();
9564                if (!StackId.isTaskResizeAllowed(stackId)) {
9565                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9566                }
9567                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9568                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9569                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9570                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9571                }
9572                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9573                if (stackId != task.getStackId()) {
9574                    mStackSupervisor.moveTaskToStackUncheckedLocked(task, stackId, ON_TOP,
9575                            !FORCE_FOCUS, "resizeTask");
9576                    preserveWindow = false;
9577                }
9578
9579                task.resize(bounds, resizeMode, preserveWindow, false /* deferResume */);
9580            }
9581        } finally {
9582            Binder.restoreCallingIdentity(ident);
9583        }
9584    }
9585
9586    @Override
9587    public Rect getTaskBounds(int taskId) {
9588        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9589        long ident = Binder.clearCallingIdentity();
9590        Rect rect = new Rect();
9591        try {
9592            synchronized (this) {
9593                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9594                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9595                if (task == null) {
9596                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9597                    return rect;
9598                }
9599                if (task.getStack() != null) {
9600                    // Return the bounds from window manager since it will be adjusted for various
9601                    // things like the presense of a docked stack for tasks that aren't resizeable.
9602                    task.getWindowContainerBounds(rect);
9603                } else {
9604                    // Task isn't in window manager yet since it isn't associated with a stack.
9605                    // Return the persist value from activity manager
9606                    if (task.mBounds != null) {
9607                        rect.set(task.mBounds);
9608                    } else if (task.mLastNonFullscreenBounds != null) {
9609                        rect.set(task.mLastNonFullscreenBounds);
9610                    }
9611                }
9612            }
9613        } finally {
9614            Binder.restoreCallingIdentity(ident);
9615        }
9616        return rect;
9617    }
9618
9619    @Override
9620    public void cancelTaskWindowTransition(int taskId) {
9621        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
9622        final long ident = Binder.clearCallingIdentity();
9623        try {
9624            synchronized (this) {
9625                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9626                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9627                if (task == null) {
9628                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
9629                    return;
9630                }
9631                task.cancelWindowTransition();
9632            }
9633        } finally {
9634            Binder.restoreCallingIdentity(ident);
9635        }
9636    }
9637
9638    @Override
9639    public void cancelTaskThumbnailTransition(int taskId) {
9640        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
9641        final long ident = Binder.clearCallingIdentity();
9642        try {
9643            synchronized (this) {
9644                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9645                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9646                if (task == null) {
9647                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
9648                    return;
9649                }
9650                task.cancelThumbnailTransition();
9651            }
9652        } finally {
9653            Binder.restoreCallingIdentity(ident);
9654        }
9655    }
9656
9657    @Override
9658    public TaskSnapshot getTaskSnapshot(int taskId) {
9659        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
9660        final long ident = Binder.clearCallingIdentity();
9661        try {
9662            synchronized (this) {
9663                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9664                        taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9665                if (task == null) {
9666                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
9667                    return null;
9668                }
9669                return task.getSnapshot();
9670            }
9671        } finally {
9672            Binder.restoreCallingIdentity(ident);
9673        }
9674    }
9675
9676    @Override
9677    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9678        if (userId != UserHandle.getCallingUserId()) {
9679            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9680                    "getTaskDescriptionIcon");
9681        }
9682        final File passedIconFile = new File(filePath);
9683        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9684                passedIconFile.getName());
9685        if (!legitIconFile.getPath().equals(filePath)
9686                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9687            throw new IllegalArgumentException("Bad file path: " + filePath
9688                    + " passed for userId " + userId);
9689        }
9690        return mRecentTasks.getTaskDescriptionIcon(filePath);
9691    }
9692
9693    @Override
9694    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
9695            throws RemoteException {
9696        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
9697        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9698                activityOptions.getCustomInPlaceResId() == 0) {
9699            throw new IllegalArgumentException("Expected in-place ActivityOption " +
9700                    "with valid animation");
9701        }
9702        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9703        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
9704                activityOptions.getCustomInPlaceResId());
9705        mWindowManager.executeAppTransition();
9706    }
9707
9708    private void removeTasksByPackageNameLocked(String packageName, int userId) {
9709        // Remove all tasks with activities in the specified package from the list of recent tasks
9710        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9711            TaskRecord tr = mRecentTasks.get(i);
9712            if (tr.userId != userId) continue;
9713
9714            ComponentName cn = tr.intent.getComponent();
9715            if (cn != null && cn.getPackageName().equals(packageName)) {
9716                // If the package name matches, remove the task.
9717                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9718            }
9719        }
9720    }
9721
9722    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9723            int userId) {
9724
9725        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9726            TaskRecord tr = mRecentTasks.get(i);
9727            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9728                continue;
9729            }
9730
9731            ComponentName cn = tr.intent.getComponent();
9732            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9733                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9734            if (sameComponent) {
9735                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9736            }
9737        }
9738    }
9739
9740    @Override
9741    public void removeStack(int stackId) {
9742        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9743        if (StackId.isHomeOrRecentsStack(stackId)) {
9744            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
9745        }
9746
9747        synchronized (this) {
9748            final long ident = Binder.clearCallingIdentity();
9749            try {
9750                mStackSupervisor.removeStackLocked(stackId);
9751            } finally {
9752                Binder.restoreCallingIdentity(ident);
9753            }
9754        }
9755    }
9756
9757    @Override
9758    public void moveStackToDisplay(int stackId, int displayId) {
9759        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
9760
9761        synchronized (this) {
9762            final long ident = Binder.clearCallingIdentity();
9763            try {
9764                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
9765                        + " to displayId=" + displayId);
9766                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId);
9767            } finally {
9768                Binder.restoreCallingIdentity(ident);
9769            }
9770        }
9771    }
9772
9773    @Override
9774    public boolean removeTask(int taskId) {
9775        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9776        synchronized (this) {
9777            final long ident = Binder.clearCallingIdentity();
9778            try {
9779                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9780            } finally {
9781                Binder.restoreCallingIdentity(ident);
9782            }
9783        }
9784    }
9785
9786    /**
9787     * TODO: Add mController hook
9788     */
9789    @Override
9790    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9791        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9792
9793        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9794        synchronized(this) {
9795            moveTaskToFrontLocked(taskId, flags, bOptions);
9796        }
9797    }
9798
9799    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9800        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9801
9802        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9803                Binder.getCallingUid(), -1, -1, "Task to front")) {
9804            ActivityOptions.abort(options);
9805            return;
9806        }
9807        final long origId = Binder.clearCallingIdentity();
9808        try {
9809            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9810            if (task == null) {
9811                Slog.d(TAG, "Could not find task for id: "+ taskId);
9812                return;
9813            }
9814            if (mStackSupervisor.isLockTaskModeViolation(task)) {
9815                mStackSupervisor.showLockTaskToast();
9816                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9817                return;
9818            }
9819            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9820            if (prev != null && prev.isRecentsActivity()) {
9821                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9822            }
9823            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9824                    false /* forceNonResizable */);
9825
9826            final ActivityRecord topActivity = task.getTopActivity();
9827            if (topActivity != null) {
9828
9829                // We are reshowing a task, use a starting window to hide the initial draw delay
9830                // so the transition can start earlier.
9831                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
9832                        true /* taskSwitch */);
9833            }
9834        } finally {
9835            Binder.restoreCallingIdentity(origId);
9836        }
9837        ActivityOptions.abort(options);
9838    }
9839
9840    /**
9841     * Moves an activity, and all of the other activities within the same task, to the bottom
9842     * of the history stack.  The activity's order within the task is unchanged.
9843     *
9844     * @param token A reference to the activity we wish to move
9845     * @param nonRoot If false then this only works if the activity is the root
9846     *                of a task; if true it will work for any activity in a task.
9847     * @return Returns true if the move completed, false if not.
9848     */
9849    @Override
9850    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9851        enforceNotIsolatedCaller("moveActivityTaskToBack");
9852        synchronized(this) {
9853            final long origId = Binder.clearCallingIdentity();
9854            try {
9855                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9856                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9857                if (task != null) {
9858                    if (mStackSupervisor.isLockedTask(task)) {
9859                        mStackSupervisor.showLockTaskToast();
9860                        return false;
9861                    }
9862                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9863                }
9864            } finally {
9865                Binder.restoreCallingIdentity(origId);
9866            }
9867        }
9868        return false;
9869    }
9870
9871    @Override
9872    public void moveTaskBackwards(int task) {
9873        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9874                "moveTaskBackwards()");
9875
9876        synchronized(this) {
9877            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9878                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
9879                return;
9880            }
9881            final long origId = Binder.clearCallingIdentity();
9882            moveTaskBackwardsLocked(task);
9883            Binder.restoreCallingIdentity(origId);
9884        }
9885    }
9886
9887    private final void moveTaskBackwardsLocked(int task) {
9888        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9889    }
9890
9891    @Override
9892    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9893            IActivityContainerCallback callback) throws RemoteException {
9894        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9895        synchronized (this) {
9896            if (parentActivityToken == null) {
9897                throw new IllegalArgumentException("parent token must not be null");
9898            }
9899            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9900            if (r == null) {
9901                return null;
9902            }
9903            if (callback == null) {
9904                throw new IllegalArgumentException("callback must not be null");
9905            }
9906            return mStackSupervisor.createVirtualActivityContainer(r, callback);
9907        }
9908    }
9909
9910    @Override
9911    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9912        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9913        synchronized (this) {
9914            final int stackId = mStackSupervisor.getNextStackId();
9915            final ActivityStack stack =
9916                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9917            if (stack == null) {
9918                return null;
9919            }
9920            return stack.mActivityContainer;
9921        }
9922    }
9923
9924    @Override
9925    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9926        synchronized (this) {
9927            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9928            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9929                return stack.mActivityContainer.getDisplayId();
9930            }
9931            return DEFAULT_DISPLAY;
9932        }
9933    }
9934
9935    @Override
9936    public int getActivityStackId(IBinder token) throws RemoteException {
9937        synchronized (this) {
9938            ActivityStack stack = ActivityRecord.getStackLocked(token);
9939            if (stack == null) {
9940                return INVALID_STACK_ID;
9941            }
9942            return stack.mStackId;
9943        }
9944    }
9945
9946    @Override
9947    public void exitFreeformMode(IBinder token) throws RemoteException {
9948        synchronized (this) {
9949            long ident = Binder.clearCallingIdentity();
9950            try {
9951                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9952                if (r == null) {
9953                    throw new IllegalArgumentException(
9954                            "exitFreeformMode: No activity record matching token=" + token);
9955                }
9956                final ActivityStack stack = r.getStackLocked(token);
9957                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9958                    throw new IllegalStateException(
9959                            "exitFreeformMode: You can only go fullscreen from freeform.");
9960                }
9961                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9962                mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9963                        ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9964            } finally {
9965                Binder.restoreCallingIdentity(ident);
9966            }
9967        }
9968    }
9969
9970    @Override
9971    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9972        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9973        if (StackId.isHomeOrRecentsStack(stackId)) {
9974            throw new IllegalArgumentException(
9975                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
9976        }
9977        synchronized (this) {
9978            long ident = Binder.clearCallingIdentity();
9979            try {
9980                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9981                        + " to stackId=" + stackId + " toTop=" + toTop);
9982                if (stackId == DOCKED_STACK_ID) {
9983                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9984                            null /* initialBounds */);
9985                }
9986                boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9987                        !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9988                if (result && stackId == DOCKED_STACK_ID) {
9989                    // If task moved to docked stack - show recents if needed.
9990                    mWindowManager.showRecentApps(false /* fromHome */);
9991                }
9992            } finally {
9993                Binder.restoreCallingIdentity(ident);
9994            }
9995        }
9996    }
9997
9998    @Override
9999    public void swapDockedAndFullscreenStack() throws RemoteException {
10000        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10001        synchronized (this) {
10002            long ident = Binder.clearCallingIdentity();
10003            try {
10004                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10005                        FULLSCREEN_WORKSPACE_STACK_ID);
10006                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10007                        : null;
10008                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10009                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10010                        : null;
10011                if (topTask == null || tasks == null || tasks.size() == 0) {
10012                    Slog.w(TAG,
10013                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10014                    return;
10015                }
10016
10017                // TODO: App transition
10018                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10019
10020                // Defer the resume so resume/pausing while moving stacks is dangerous.
10021                mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
10022                        false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
10023                        ANIMATE, true /* deferResume */);
10024                final int size = tasks.size();
10025                for (int i = 0; i < size; i++) {
10026                    final int id = tasks.get(i).taskId;
10027                    if (id == topTask.taskId) {
10028                        continue;
10029                    }
10030                    mStackSupervisor.moveTaskToStackLocked(id,
10031                            FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
10032                            "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
10033                }
10034
10035                // Because we deferred the resume, to avoid conflicts with stack switches while
10036                // resuming, we need to do it after all the tasks are moved.
10037                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10038                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10039
10040                mWindowManager.executeAppTransition();
10041            } finally {
10042                Binder.restoreCallingIdentity(ident);
10043            }
10044        }
10045    }
10046
10047    /**
10048     * Moves the input task to the docked stack.
10049     *
10050     * @param taskId Id of task to move.
10051     * @param createMode The mode the docked stack should be created in if it doesn't exist
10052     *                   already. See
10053     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10054     *                   and
10055     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10056     * @param toTop If the task and stack should be moved to the top.
10057     * @param animate Whether we should play an animation for the moving the task
10058     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10059     *                      docked stack. Pass {@code null} to use default bounds.
10060     */
10061    @Override
10062    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10063            Rect initialBounds, boolean moveHomeStackFront) {
10064        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10065        synchronized (this) {
10066            long ident = Binder.clearCallingIdentity();
10067            try {
10068                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10069                        + " to createMode=" + createMode + " toTop=" + toTop);
10070                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10071                final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10072                        taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10073                        animate, DEFER_RESUME);
10074                if (moved) {
10075                    if (moveHomeStackFront) {
10076                        mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10077                    }
10078                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10079                }
10080                return moved;
10081            } finally {
10082                Binder.restoreCallingIdentity(ident);
10083            }
10084        }
10085    }
10086
10087    /**
10088     * Moves the top activity in the input stackId to the pinned stack.
10089     *
10090     * @param stackId Id of stack to move the top activity to pinned stack.
10091     * @param bounds Bounds to use for pinned stack.
10092     *
10093     * @return True if the top activity of the input stack was successfully moved to the pinned
10094     *          stack.
10095     */
10096    @Override
10097    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10098        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10099        synchronized (this) {
10100            if (!mSupportsPictureInPicture) {
10101                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10102                        + "Device doesn't support picture-in-pciture mode");
10103            }
10104
10105            long ident = Binder.clearCallingIdentity();
10106            try {
10107                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10108            } finally {
10109                Binder.restoreCallingIdentity(ident);
10110            }
10111        }
10112    }
10113
10114    @Override
10115    public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10116            boolean preserveWindows, boolean animate, int animationDuration) {
10117        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10118        long ident = Binder.clearCallingIdentity();
10119        try {
10120            synchronized (this) {
10121                if (animate) {
10122                    if (stackId == PINNED_STACK_ID) {
10123                        mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10124                    } else {
10125                        throw new IllegalArgumentException("Stack: " + stackId
10126                                + " doesn't support animated resize.");
10127                    }
10128                } else {
10129                    mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10130                            null /* tempTaskInsetBounds */, preserveWindows,
10131                            allowResizeInDockedMode, !DEFER_RESUME);
10132                }
10133            }
10134        } finally {
10135            Binder.restoreCallingIdentity(ident);
10136        }
10137    }
10138
10139    @Override
10140    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10141            Rect tempDockedTaskInsetBounds,
10142            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10143        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10144                "resizeDockedStack()");
10145        long ident = Binder.clearCallingIdentity();
10146        try {
10147            synchronized (this) {
10148                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10149                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10150                        PRESERVE_WINDOWS);
10151            }
10152        } finally {
10153            Binder.restoreCallingIdentity(ident);
10154        }
10155    }
10156
10157    @Override
10158    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10159        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10160                "resizePinnedStack()");
10161        final long ident = Binder.clearCallingIdentity();
10162        try {
10163            synchronized (this) {
10164                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10165            }
10166        } finally {
10167            Binder.restoreCallingIdentity(ident);
10168        }
10169    }
10170
10171    /**
10172     * Try to place task to provided position. The final position might be different depending on
10173     * current user and stacks state. The task will be moved to target stack if it's currently in
10174     * different stack.
10175     */
10176    @Override
10177    public void positionTaskInStack(int taskId, int stackId, int position) {
10178        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10179        if (StackId.isHomeOrRecentsStack(stackId)) {
10180            throw new IllegalArgumentException(
10181                    "positionTaskInStack: Attempt to change the position of task "
10182                    + taskId + " in/to home/recents stack");
10183        }
10184        synchronized (this) {
10185            long ident = Binder.clearCallingIdentity();
10186            try {
10187                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10188                        + taskId + " in stackId=" + stackId + " at position=" + position);
10189                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10190                if (task == null) {
10191                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10192                            + taskId);
10193                }
10194
10195                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10196                        !ON_TOP);
10197
10198                // TODO: Have the callers of this API call a separate reparent method if that is
10199                // what they intended to do vs. having this method also do reparenting.
10200                if (task.getStack() == stack) {
10201                    // Change position in current stack.
10202                    stack.positionChildAt(task, position);
10203                } else {
10204                    // Reparent to new stack.
10205                    task.reparent(stackId, position, "positionTaskInStack");
10206                }
10207            } finally {
10208                Binder.restoreCallingIdentity(ident);
10209            }
10210        }
10211    }
10212
10213    @Override
10214    public List<StackInfo> getAllStackInfos() {
10215        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10216        long ident = Binder.clearCallingIdentity();
10217        try {
10218            synchronized (this) {
10219                return mStackSupervisor.getAllStackInfosLocked();
10220            }
10221        } finally {
10222            Binder.restoreCallingIdentity(ident);
10223        }
10224    }
10225
10226    @Override
10227    public StackInfo getStackInfo(int stackId) {
10228        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10229        long ident = Binder.clearCallingIdentity();
10230        try {
10231            synchronized (this) {
10232                return mStackSupervisor.getStackInfoLocked(stackId);
10233            }
10234        } finally {
10235            Binder.restoreCallingIdentity(ident);
10236        }
10237    }
10238
10239    @Override
10240    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10241        synchronized(this) {
10242            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10243        }
10244    }
10245
10246    @Override
10247    public void updateDeviceOwner(String packageName) {
10248        final int callingUid = Binder.getCallingUid();
10249        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10250            throw new SecurityException("updateDeviceOwner called from non-system process");
10251        }
10252        synchronized (this) {
10253            mDeviceOwnerName = packageName;
10254        }
10255    }
10256
10257    @Override
10258    public void updateLockTaskPackages(int userId, String[] packages) {
10259        final int callingUid = Binder.getCallingUid();
10260        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10261            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10262                    "updateLockTaskPackages()");
10263        }
10264        synchronized (this) {
10265            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10266                    Arrays.toString(packages));
10267            mLockTaskPackages.put(userId, packages);
10268            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10269        }
10270    }
10271
10272
10273    void startLockTaskModeLocked(TaskRecord task) {
10274        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10275        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10276            return;
10277        }
10278
10279        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10280        // is initiated by system after the pinning request was shown and locked mode is initiated
10281        // by an authorized app directly
10282        final int callingUid = Binder.getCallingUid();
10283        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10284        long ident = Binder.clearCallingIdentity();
10285        try {
10286            if (!isSystemInitiated) {
10287                task.mLockTaskUid = callingUid;
10288                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10289                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10290                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10291                    StatusBarManagerInternal statusBarManager =
10292                            LocalServices.getService(StatusBarManagerInternal.class);
10293                    if (statusBarManager != null) {
10294                        statusBarManager.showScreenPinningRequest(task.taskId);
10295                    }
10296                    return;
10297                }
10298
10299                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10300                if (stack == null || task != stack.topTask()) {
10301                    throw new IllegalArgumentException("Invalid task, not in foreground");
10302                }
10303            }
10304            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10305                    "Locking fully");
10306            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10307                    ActivityManager.LOCK_TASK_MODE_PINNED :
10308                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10309                    "startLockTask", true);
10310        } finally {
10311            Binder.restoreCallingIdentity(ident);
10312        }
10313    }
10314
10315    @Override
10316    public void startLockTaskModeById(int taskId) {
10317        synchronized (this) {
10318            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10319            if (task != null) {
10320                startLockTaskModeLocked(task);
10321            }
10322        }
10323    }
10324
10325    @Override
10326    public void startLockTaskModeByToken(IBinder token) {
10327        synchronized (this) {
10328            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10329            if (r == null) {
10330                return;
10331            }
10332            final TaskRecord task = r.task;
10333            if (task != null) {
10334                startLockTaskModeLocked(task);
10335            }
10336        }
10337    }
10338
10339    @Override
10340    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10341        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10342        // This makes inner call to look as if it was initiated by system.
10343        long ident = Binder.clearCallingIdentity();
10344        try {
10345            synchronized (this) {
10346                startLockTaskModeById(taskId);
10347            }
10348        } finally {
10349            Binder.restoreCallingIdentity(ident);
10350        }
10351    }
10352
10353    @Override
10354    public void stopLockTaskMode() {
10355        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10356        if (lockTask == null) {
10357            // Our work here is done.
10358            return;
10359        }
10360
10361        final int callingUid = Binder.getCallingUid();
10362        final int lockTaskUid = lockTask.mLockTaskUid;
10363        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10364        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10365            // Done.
10366            return;
10367        } else {
10368            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10369            // It is possible lockTaskMode was started by the system process because
10370            // android:lockTaskMode is set to a locking value in the application manifest
10371            // instead of the app calling startLockTaskMode. In this case
10372            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10373            // {@link TaskRecord.effectiveUid} instead. Also caller with
10374            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10375            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10376                    && callingUid != lockTaskUid
10377                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10378                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10379                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10380            }
10381        }
10382        long ident = Binder.clearCallingIdentity();
10383        try {
10384            Log.d(TAG, "stopLockTaskMode");
10385            // Stop lock task
10386            synchronized (this) {
10387                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10388                        "stopLockTask", true);
10389            }
10390            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10391            if (tm != null) {
10392                tm.showInCallScreen(false);
10393            }
10394        } finally {
10395            Binder.restoreCallingIdentity(ident);
10396        }
10397    }
10398
10399    /**
10400     * This API should be called by SystemUI only when user perform certain action to dismiss
10401     * lock task mode. We should only dismiss pinned lock task mode in this case.
10402     */
10403    @Override
10404    public void stopSystemLockTaskMode() throws RemoteException {
10405        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10406            stopLockTaskMode();
10407        } else {
10408            mStackSupervisor.showLockTaskToast();
10409        }
10410    }
10411
10412    @Override
10413    public boolean isInLockTaskMode() {
10414        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10415    }
10416
10417    @Override
10418    public int getLockTaskModeState() {
10419        synchronized (this) {
10420            return mStackSupervisor.getLockTaskModeState();
10421        }
10422    }
10423
10424    @Override
10425    public void showLockTaskEscapeMessage(IBinder token) {
10426        synchronized (this) {
10427            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10428            if (r == null) {
10429                return;
10430            }
10431            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10432        }
10433    }
10434
10435    // =========================================================
10436    // CONTENT PROVIDERS
10437    // =========================================================
10438
10439    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10440        List<ProviderInfo> providers = null;
10441        try {
10442            providers = AppGlobals.getPackageManager()
10443                    .queryContentProviders(app.processName, app.uid,
10444                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10445                                    | MATCH_DEBUG_TRIAGED_MISSING)
10446                    .getList();
10447        } catch (RemoteException ex) {
10448        }
10449        if (DEBUG_MU) Slog.v(TAG_MU,
10450                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10451        int userId = app.userId;
10452        if (providers != null) {
10453            int N = providers.size();
10454            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10455            for (int i=0; i<N; i++) {
10456                // TODO: keep logic in sync with installEncryptionUnawareProviders
10457                ProviderInfo cpi =
10458                    (ProviderInfo)providers.get(i);
10459                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10460                        cpi.name, cpi.flags);
10461                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10462                    // This is a singleton provider, but a user besides the
10463                    // default user is asking to initialize a process it runs
10464                    // in...  well, no, it doesn't actually run in this process,
10465                    // it runs in the process of the default user.  Get rid of it.
10466                    providers.remove(i);
10467                    N--;
10468                    i--;
10469                    continue;
10470                }
10471
10472                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10473                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10474                if (cpr == null) {
10475                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10476                    mProviderMap.putProviderByClass(comp, cpr);
10477                }
10478                if (DEBUG_MU) Slog.v(TAG_MU,
10479                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10480                app.pubProviders.put(cpi.name, cpr);
10481                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10482                    // Don't add this if it is a platform component that is marked
10483                    // to run in multiple processes, because this is actually
10484                    // part of the framework so doesn't make sense to track as a
10485                    // separate apk in the process.
10486                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10487                            mProcessStats);
10488                }
10489                notifyPackageUse(cpi.applicationInfo.packageName,
10490                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10491            }
10492        }
10493        return providers;
10494    }
10495
10496    /**
10497     * Check if the calling UID has a possible chance at accessing the provider
10498     * at the given authority and user.
10499     */
10500    public String checkContentProviderAccess(String authority, int userId) {
10501        if (userId == UserHandle.USER_ALL) {
10502            mContext.enforceCallingOrSelfPermission(
10503                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10504            userId = UserHandle.getCallingUserId();
10505        }
10506
10507        ProviderInfo cpi = null;
10508        try {
10509            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10510                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10511                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10512                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10513                    userId);
10514        } catch (RemoteException ignored) {
10515        }
10516        if (cpi == null) {
10517            // TODO: make this an outright failure in a future platform release;
10518            // until then anonymous content notifications are unprotected
10519            //return "Failed to find provider " + authority + " for user " + userId;
10520            return null;
10521        }
10522
10523        ProcessRecord r = null;
10524        synchronized (mPidsSelfLocked) {
10525            r = mPidsSelfLocked.get(Binder.getCallingPid());
10526        }
10527        if (r == null) {
10528            return "Failed to find PID " + Binder.getCallingPid();
10529        }
10530
10531        synchronized (this) {
10532            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10533        }
10534    }
10535
10536    /**
10537     * Check if {@link ProcessRecord} has a possible chance at accessing the
10538     * given {@link ProviderInfo}. Final permission checking is always done
10539     * in {@link ContentProvider}.
10540     */
10541    private final String checkContentProviderPermissionLocked(
10542            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10543        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10544        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10545        boolean checkedGrants = false;
10546        if (checkUser) {
10547            // Looking for cross-user grants before enforcing the typical cross-users permissions
10548            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10549            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10550                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10551                    return null;
10552                }
10553                checkedGrants = true;
10554            }
10555            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10556                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10557            if (userId != tmpTargetUserId) {
10558                // When we actually went to determine the final targer user ID, this ended
10559                // up different than our initial check for the authority.  This is because
10560                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10561                // SELF.  So we need to re-check the grants again.
10562                checkedGrants = false;
10563            }
10564        }
10565        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10566                cpi.applicationInfo.uid, cpi.exported)
10567                == PackageManager.PERMISSION_GRANTED) {
10568            return null;
10569        }
10570        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10571                cpi.applicationInfo.uid, cpi.exported)
10572                == PackageManager.PERMISSION_GRANTED) {
10573            return null;
10574        }
10575
10576        PathPermission[] pps = cpi.pathPermissions;
10577        if (pps != null) {
10578            int i = pps.length;
10579            while (i > 0) {
10580                i--;
10581                PathPermission pp = pps[i];
10582                String pprperm = pp.getReadPermission();
10583                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10584                        cpi.applicationInfo.uid, cpi.exported)
10585                        == PackageManager.PERMISSION_GRANTED) {
10586                    return null;
10587                }
10588                String ppwperm = pp.getWritePermission();
10589                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10590                        cpi.applicationInfo.uid, cpi.exported)
10591                        == PackageManager.PERMISSION_GRANTED) {
10592                    return null;
10593                }
10594            }
10595        }
10596        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10597            return null;
10598        }
10599
10600        String msg;
10601        if (!cpi.exported) {
10602            msg = "Permission Denial: opening provider " + cpi.name
10603                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10604                    + ", uid=" + callingUid + ") that is not exported from uid "
10605                    + cpi.applicationInfo.uid;
10606        } else {
10607            msg = "Permission Denial: opening provider " + cpi.name
10608                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10609                    + ", uid=" + callingUid + ") requires "
10610                    + cpi.readPermission + " or " + cpi.writePermission;
10611        }
10612        Slog.w(TAG, msg);
10613        return msg;
10614    }
10615
10616    /**
10617     * Returns if the ContentProvider has granted a uri to callingUid
10618     */
10619    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10620        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10621        if (perms != null) {
10622            for (int i=perms.size()-1; i>=0; i--) {
10623                GrantUri grantUri = perms.keyAt(i);
10624                if (grantUri.sourceUserId == userId || !checkUser) {
10625                    if (matchesProvider(grantUri.uri, cpi)) {
10626                        return true;
10627                    }
10628                }
10629            }
10630        }
10631        return false;
10632    }
10633
10634    /**
10635     * Returns true if the uri authority is one of the authorities specified in the provider.
10636     */
10637    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10638        String uriAuth = uri.getAuthority();
10639        String cpiAuth = cpi.authority;
10640        if (cpiAuth.indexOf(';') == -1) {
10641            return cpiAuth.equals(uriAuth);
10642        }
10643        String[] cpiAuths = cpiAuth.split(";");
10644        int length = cpiAuths.length;
10645        for (int i = 0; i < length; i++) {
10646            if (cpiAuths[i].equals(uriAuth)) return true;
10647        }
10648        return false;
10649    }
10650
10651    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10652            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10653        if (r != null) {
10654            for (int i=0; i<r.conProviders.size(); i++) {
10655                ContentProviderConnection conn = r.conProviders.get(i);
10656                if (conn.provider == cpr) {
10657                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10658                            "Adding provider requested by "
10659                            + r.processName + " from process "
10660                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10661                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10662                    if (stable) {
10663                        conn.stableCount++;
10664                        conn.numStableIncs++;
10665                    } else {
10666                        conn.unstableCount++;
10667                        conn.numUnstableIncs++;
10668                    }
10669                    return conn;
10670                }
10671            }
10672            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10673            if (stable) {
10674                conn.stableCount = 1;
10675                conn.numStableIncs = 1;
10676            } else {
10677                conn.unstableCount = 1;
10678                conn.numUnstableIncs = 1;
10679            }
10680            cpr.connections.add(conn);
10681            r.conProviders.add(conn);
10682            startAssociationLocked(r.uid, r.processName, r.curProcState,
10683                    cpr.uid, cpr.name, cpr.info.processName);
10684            return conn;
10685        }
10686        cpr.addExternalProcessHandleLocked(externalProcessToken);
10687        return null;
10688    }
10689
10690    boolean decProviderCountLocked(ContentProviderConnection conn,
10691            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10692        if (conn != null) {
10693            cpr = conn.provider;
10694            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10695                    "Removing provider requested by "
10696                    + conn.client.processName + " from process "
10697                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10698                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10699            if (stable) {
10700                conn.stableCount--;
10701            } else {
10702                conn.unstableCount--;
10703            }
10704            if (conn.stableCount == 0 && conn.unstableCount == 0) {
10705                cpr.connections.remove(conn);
10706                conn.client.conProviders.remove(conn);
10707                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10708                    // The client is more important than last activity -- note the time this
10709                    // is happening, so we keep the old provider process around a bit as last
10710                    // activity to avoid thrashing it.
10711                    if (cpr.proc != null) {
10712                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10713                    }
10714                }
10715                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10716                return true;
10717            }
10718            return false;
10719        }
10720        cpr.removeExternalProcessHandleLocked(externalProcessToken);
10721        return false;
10722    }
10723
10724    private void checkTime(long startTime, String where) {
10725        long now = SystemClock.uptimeMillis();
10726        if ((now-startTime) > 50) {
10727            // If we are taking more than 50ms, log about it.
10728            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10729        }
10730    }
10731
10732    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10733            PROC_SPACE_TERM,
10734            PROC_SPACE_TERM|PROC_PARENS,
10735            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10736    };
10737
10738    private final long[] mProcessStateStatsLongs = new long[1];
10739
10740    boolean isProcessAliveLocked(ProcessRecord proc) {
10741        if (proc.procStatFile == null) {
10742            proc.procStatFile = "/proc/" + proc.pid + "/stat";
10743        }
10744        mProcessStateStatsLongs[0] = 0;
10745        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10746                mProcessStateStatsLongs, null)) {
10747            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10748            return false;
10749        }
10750        final long state = mProcessStateStatsLongs[0];
10751        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10752                + (char)state);
10753        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10754    }
10755
10756    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10757            String name, IBinder token, boolean stable, int userId) {
10758        ContentProviderRecord cpr;
10759        ContentProviderConnection conn = null;
10760        ProviderInfo cpi = null;
10761
10762        synchronized(this) {
10763            long startTime = SystemClock.uptimeMillis();
10764
10765            ProcessRecord r = null;
10766            if (caller != null) {
10767                r = getRecordForAppLocked(caller);
10768                if (r == null) {
10769                    throw new SecurityException(
10770                            "Unable to find app for caller " + caller
10771                          + " (pid=" + Binder.getCallingPid()
10772                          + ") when getting content provider " + name);
10773                }
10774            }
10775
10776            boolean checkCrossUser = true;
10777
10778            checkTime(startTime, "getContentProviderImpl: getProviderByName");
10779
10780            // First check if this content provider has been published...
10781            cpr = mProviderMap.getProviderByName(name, userId);
10782            // If that didn't work, check if it exists for user 0 and then
10783            // verify that it's a singleton provider before using it.
10784            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10785                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10786                if (cpr != null) {
10787                    cpi = cpr.info;
10788                    if (isSingleton(cpi.processName, cpi.applicationInfo,
10789                            cpi.name, cpi.flags)
10790                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10791                        userId = UserHandle.USER_SYSTEM;
10792                        checkCrossUser = false;
10793                    } else {
10794                        cpr = null;
10795                        cpi = null;
10796                    }
10797                }
10798            }
10799
10800            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10801            if (providerRunning) {
10802                cpi = cpr.info;
10803                String msg;
10804                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10805                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10806                        != null) {
10807                    throw new SecurityException(msg);
10808                }
10809                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10810
10811                if (r != null && cpr.canRunHere(r)) {
10812                    // This provider has been published or is in the process
10813                    // of being published...  but it is also allowed to run
10814                    // in the caller's process, so don't make a connection
10815                    // and just let the caller instantiate its own instance.
10816                    ContentProviderHolder holder = cpr.newHolder(null);
10817                    // don't give caller the provider object, it needs
10818                    // to make its own.
10819                    holder.provider = null;
10820                    return holder;
10821                }
10822
10823                final long origId = Binder.clearCallingIdentity();
10824
10825                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10826
10827                // In this case the provider instance already exists, so we can
10828                // return it right away.
10829                conn = incProviderCountLocked(r, cpr, token, stable);
10830                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10831                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10832                        // If this is a perceptible app accessing the provider,
10833                        // make sure to count it as being accessed and thus
10834                        // back up on the LRU list.  This is good because
10835                        // content providers are often expensive to start.
10836                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10837                        updateLruProcessLocked(cpr.proc, false, null);
10838                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10839                    }
10840                }
10841
10842                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10843                final int verifiedAdj = cpr.proc.verifiedAdj;
10844                boolean success = updateOomAdjLocked(cpr.proc);
10845                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10846                // if the process has been successfully adjusted.  So to reduce races with
10847                // it, we will check whether the process still exists.  Note that this doesn't
10848                // completely get rid of races with LMK killing the process, but should make
10849                // them much smaller.
10850                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10851                    success = false;
10852                }
10853                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10854                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10855                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10856                // NOTE: there is still a race here where a signal could be
10857                // pending on the process even though we managed to update its
10858                // adj level.  Not sure what to do about this, but at least
10859                // the race is now smaller.
10860                if (!success) {
10861                    // Uh oh...  it looks like the provider's process
10862                    // has been killed on us.  We need to wait for a new
10863                    // process to be started, and make sure its death
10864                    // doesn't kill our process.
10865                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10866                            + " is crashing; detaching " + r);
10867                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10868                    checkTime(startTime, "getContentProviderImpl: before appDied");
10869                    appDiedLocked(cpr.proc);
10870                    checkTime(startTime, "getContentProviderImpl: after appDied");
10871                    if (!lastRef) {
10872                        // This wasn't the last ref our process had on
10873                        // the provider...  we have now been killed, bail.
10874                        return null;
10875                    }
10876                    providerRunning = false;
10877                    conn = null;
10878                } else {
10879                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
10880                }
10881
10882                Binder.restoreCallingIdentity(origId);
10883            }
10884
10885            if (!providerRunning) {
10886                try {
10887                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10888                    cpi = AppGlobals.getPackageManager().
10889                        resolveContentProvider(name,
10890                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10891                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10892                } catch (RemoteException ex) {
10893                }
10894                if (cpi == null) {
10895                    return null;
10896                }
10897                // If the provider is a singleton AND
10898                // (it's a call within the same user || the provider is a
10899                // privileged app)
10900                // Then allow connecting to the singleton provider
10901                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10902                        cpi.name, cpi.flags)
10903                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10904                if (singleton) {
10905                    userId = UserHandle.USER_SYSTEM;
10906                }
10907                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10908                checkTime(startTime, "getContentProviderImpl: got app info for user");
10909
10910                String msg;
10911                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10912                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10913                        != null) {
10914                    throw new SecurityException(msg);
10915                }
10916                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10917
10918                if (!mProcessesReady
10919                        && !cpi.processName.equals("system")) {
10920                    // If this content provider does not run in the system
10921                    // process, and the system is not yet ready to run other
10922                    // processes, then fail fast instead of hanging.
10923                    throw new IllegalArgumentException(
10924                            "Attempt to launch content provider before system ready");
10925                }
10926
10927                // Make sure that the user who owns this provider is running.  If not,
10928                // we don't want to allow it to run.
10929                if (!mUserController.isUserRunningLocked(userId, 0)) {
10930                    Slog.w(TAG, "Unable to launch app "
10931                            + cpi.applicationInfo.packageName + "/"
10932                            + cpi.applicationInfo.uid + " for provider "
10933                            + name + ": user " + userId + " is stopped");
10934                    return null;
10935                }
10936
10937                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10938                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10939                cpr = mProviderMap.getProviderByClass(comp, userId);
10940                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10941                final boolean firstClass = cpr == null;
10942                if (firstClass) {
10943                    final long ident = Binder.clearCallingIdentity();
10944
10945                    // If permissions need a review before any of the app components can run,
10946                    // we return no provider and launch a review activity if the calling app
10947                    // is in the foreground.
10948                    if (mPermissionReviewRequired) {
10949                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10950                            return null;
10951                        }
10952                    }
10953
10954                    try {
10955                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10956                        ApplicationInfo ai =
10957                            AppGlobals.getPackageManager().
10958                                getApplicationInfo(
10959                                        cpi.applicationInfo.packageName,
10960                                        STOCK_PM_FLAGS, userId);
10961                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10962                        if (ai == null) {
10963                            Slog.w(TAG, "No package info for content provider "
10964                                    + cpi.name);
10965                            return null;
10966                        }
10967                        ai = getAppInfoForUser(ai, userId);
10968                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10969                    } catch (RemoteException ex) {
10970                        // pm is in same process, this will never happen.
10971                    } finally {
10972                        Binder.restoreCallingIdentity(ident);
10973                    }
10974                }
10975
10976                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10977
10978                if (r != null && cpr.canRunHere(r)) {
10979                    // If this is a multiprocess provider, then just return its
10980                    // info and allow the caller to instantiate it.  Only do
10981                    // this if the provider is the same user as the caller's
10982                    // process, or can run as root (so can be in any process).
10983                    return cpr.newHolder(null);
10984                }
10985
10986                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10987                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10988                            + cpr.info.name + " callers=" + Debug.getCallers(6));
10989
10990                // This is single process, and our app is now connecting to it.
10991                // See if we are already in the process of launching this
10992                // provider.
10993                final int N = mLaunchingProviders.size();
10994                int i;
10995                for (i = 0; i < N; i++) {
10996                    if (mLaunchingProviders.get(i) == cpr) {
10997                        break;
10998                    }
10999                }
11000
11001                // If the provider is not already being launched, then get it
11002                // started.
11003                if (i >= N) {
11004                    final long origId = Binder.clearCallingIdentity();
11005
11006                    try {
11007                        // Content provider is now in use, its package can't be stopped.
11008                        try {
11009                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11010                            AppGlobals.getPackageManager().setPackageStoppedState(
11011                                    cpr.appInfo.packageName, false, userId);
11012                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11013                        } catch (RemoteException e) {
11014                        } catch (IllegalArgumentException e) {
11015                            Slog.w(TAG, "Failed trying to unstop package "
11016                                    + cpr.appInfo.packageName + ": " + e);
11017                        }
11018
11019                        // Use existing process if already started
11020                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11021                        ProcessRecord proc = getProcessRecordLocked(
11022                                cpi.processName, cpr.appInfo.uid, false);
11023                        if (proc != null && proc.thread != null && !proc.killed) {
11024                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11025                                    "Installing in existing process " + proc);
11026                            if (!proc.pubProviders.containsKey(cpi.name)) {
11027                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11028                                proc.pubProviders.put(cpi.name, cpr);
11029                                try {
11030                                    proc.thread.scheduleInstallProvider(cpi);
11031                                } catch (RemoteException e) {
11032                                }
11033                            }
11034                        } else {
11035                            checkTime(startTime, "getContentProviderImpl: before start process");
11036                            proc = startProcessLocked(cpi.processName,
11037                                    cpr.appInfo, false, 0, "content provider",
11038                                    new ComponentName(cpi.applicationInfo.packageName,
11039                                            cpi.name), false, false, false);
11040                            checkTime(startTime, "getContentProviderImpl: after start process");
11041                            if (proc == null) {
11042                                Slog.w(TAG, "Unable to launch app "
11043                                        + cpi.applicationInfo.packageName + "/"
11044                                        + cpi.applicationInfo.uid + " for provider "
11045                                        + name + ": process is bad");
11046                                return null;
11047                            }
11048                        }
11049                        cpr.launchingApp = proc;
11050                        mLaunchingProviders.add(cpr);
11051                    } finally {
11052                        Binder.restoreCallingIdentity(origId);
11053                    }
11054                }
11055
11056                checkTime(startTime, "getContentProviderImpl: updating data structures");
11057
11058                // Make sure the provider is published (the same provider class
11059                // may be published under multiple names).
11060                if (firstClass) {
11061                    mProviderMap.putProviderByClass(comp, cpr);
11062                }
11063
11064                mProviderMap.putProviderByName(name, cpr);
11065                conn = incProviderCountLocked(r, cpr, token, stable);
11066                if (conn != null) {
11067                    conn.waiting = true;
11068                }
11069            }
11070            checkTime(startTime, "getContentProviderImpl: done!");
11071        }
11072
11073        // Wait for the provider to be published...
11074        synchronized (cpr) {
11075            while (cpr.provider == null) {
11076                if (cpr.launchingApp == null) {
11077                    Slog.w(TAG, "Unable to launch app "
11078                            + cpi.applicationInfo.packageName + "/"
11079                            + cpi.applicationInfo.uid + " for provider "
11080                            + name + ": launching app became null");
11081                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11082                            UserHandle.getUserId(cpi.applicationInfo.uid),
11083                            cpi.applicationInfo.packageName,
11084                            cpi.applicationInfo.uid, name);
11085                    return null;
11086                }
11087                try {
11088                    if (DEBUG_MU) Slog.v(TAG_MU,
11089                            "Waiting to start provider " + cpr
11090                            + " launchingApp=" + cpr.launchingApp);
11091                    if (conn != null) {
11092                        conn.waiting = true;
11093                    }
11094                    cpr.wait();
11095                } catch (InterruptedException ex) {
11096                } finally {
11097                    if (conn != null) {
11098                        conn.waiting = false;
11099                    }
11100                }
11101            }
11102        }
11103        return cpr != null ? cpr.newHolder(conn) : null;
11104    }
11105
11106    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11107            ProcessRecord r, final int userId) {
11108        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11109                cpi.packageName, userId)) {
11110
11111            final boolean callerForeground = r == null || r.setSchedGroup
11112                    != ProcessList.SCHED_GROUP_BACKGROUND;
11113
11114            // Show a permission review UI only for starting from a foreground app
11115            if (!callerForeground) {
11116                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11117                        + cpi.packageName + " requires a permissions review");
11118                return false;
11119            }
11120
11121            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11122            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11123                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11124            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11125
11126            if (DEBUG_PERMISSIONS_REVIEW) {
11127                Slog.i(TAG, "u" + userId + " Launching permission review "
11128                        + "for package " + cpi.packageName);
11129            }
11130
11131            final UserHandle userHandle = new UserHandle(userId);
11132            mHandler.post(new Runnable() {
11133                @Override
11134                public void run() {
11135                    mContext.startActivityAsUser(intent, userHandle);
11136                }
11137            });
11138
11139            return false;
11140        }
11141
11142        return true;
11143    }
11144
11145    PackageManagerInternal getPackageManagerInternalLocked() {
11146        if (mPackageManagerInt == null) {
11147            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11148        }
11149        return mPackageManagerInt;
11150    }
11151
11152    @Override
11153    public final ContentProviderHolder getContentProvider(
11154            IApplicationThread caller, String name, int userId, boolean stable) {
11155        enforceNotIsolatedCaller("getContentProvider");
11156        if (caller == null) {
11157            String msg = "null IApplicationThread when getting content provider "
11158                    + name;
11159            Slog.w(TAG, msg);
11160            throw new SecurityException(msg);
11161        }
11162        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11163        // with cross-user grant.
11164        return getContentProviderImpl(caller, name, null, stable, userId);
11165    }
11166
11167    public ContentProviderHolder getContentProviderExternal(
11168            String name, int userId, IBinder token) {
11169        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11170            "Do not have permission in call getContentProviderExternal()");
11171        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11172                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11173        return getContentProviderExternalUnchecked(name, token, userId);
11174    }
11175
11176    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11177            IBinder token, int userId) {
11178        return getContentProviderImpl(null, name, token, true, userId);
11179    }
11180
11181    /**
11182     * Drop a content provider from a ProcessRecord's bookkeeping
11183     */
11184    public void removeContentProvider(IBinder connection, boolean stable) {
11185        enforceNotIsolatedCaller("removeContentProvider");
11186        long ident = Binder.clearCallingIdentity();
11187        try {
11188            synchronized (this) {
11189                ContentProviderConnection conn;
11190                try {
11191                    conn = (ContentProviderConnection)connection;
11192                } catch (ClassCastException e) {
11193                    String msg ="removeContentProvider: " + connection
11194                            + " not a ContentProviderConnection";
11195                    Slog.w(TAG, msg);
11196                    throw new IllegalArgumentException(msg);
11197                }
11198                if (conn == null) {
11199                    throw new NullPointerException("connection is null");
11200                }
11201                if (decProviderCountLocked(conn, null, null, stable)) {
11202                    updateOomAdjLocked();
11203                }
11204            }
11205        } finally {
11206            Binder.restoreCallingIdentity(ident);
11207        }
11208    }
11209
11210    public void removeContentProviderExternal(String name, IBinder token) {
11211        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11212            "Do not have permission in call removeContentProviderExternal()");
11213        int userId = UserHandle.getCallingUserId();
11214        long ident = Binder.clearCallingIdentity();
11215        try {
11216            removeContentProviderExternalUnchecked(name, token, userId);
11217        } finally {
11218            Binder.restoreCallingIdentity(ident);
11219        }
11220    }
11221
11222    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11223        synchronized (this) {
11224            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11225            if(cpr == null) {
11226                //remove from mProvidersByClass
11227                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11228                return;
11229            }
11230
11231            //update content provider record entry info
11232            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11233            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11234            if (localCpr.hasExternalProcessHandles()) {
11235                if (localCpr.removeExternalProcessHandleLocked(token)) {
11236                    updateOomAdjLocked();
11237                } else {
11238                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11239                            + " with no external reference for token: "
11240                            + token + ".");
11241                }
11242            } else {
11243                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11244                        + " with no external references.");
11245            }
11246        }
11247    }
11248
11249    public final void publishContentProviders(IApplicationThread caller,
11250            List<ContentProviderHolder> providers) {
11251        if (providers == null) {
11252            return;
11253        }
11254
11255        enforceNotIsolatedCaller("publishContentProviders");
11256        synchronized (this) {
11257            final ProcessRecord r = getRecordForAppLocked(caller);
11258            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11259            if (r == null) {
11260                throw new SecurityException(
11261                        "Unable to find app for caller " + caller
11262                      + " (pid=" + Binder.getCallingPid()
11263                      + ") when publishing content providers");
11264            }
11265
11266            final long origId = Binder.clearCallingIdentity();
11267
11268            final int N = providers.size();
11269            for (int i = 0; i < N; i++) {
11270                ContentProviderHolder src = providers.get(i);
11271                if (src == null || src.info == null || src.provider == null) {
11272                    continue;
11273                }
11274                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11275                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11276                if (dst != null) {
11277                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11278                    mProviderMap.putProviderByClass(comp, dst);
11279                    String names[] = dst.info.authority.split(";");
11280                    for (int j = 0; j < names.length; j++) {
11281                        mProviderMap.putProviderByName(names[j], dst);
11282                    }
11283
11284                    int launchingCount = mLaunchingProviders.size();
11285                    int j;
11286                    boolean wasInLaunchingProviders = false;
11287                    for (j = 0; j < launchingCount; j++) {
11288                        if (mLaunchingProviders.get(j) == dst) {
11289                            mLaunchingProviders.remove(j);
11290                            wasInLaunchingProviders = true;
11291                            j--;
11292                            launchingCount--;
11293                        }
11294                    }
11295                    if (wasInLaunchingProviders) {
11296                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11297                    }
11298                    synchronized (dst) {
11299                        dst.provider = src.provider;
11300                        dst.proc = r;
11301                        dst.notifyAll();
11302                    }
11303                    updateOomAdjLocked(r);
11304                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11305                            src.info.authority);
11306                }
11307            }
11308
11309            Binder.restoreCallingIdentity(origId);
11310        }
11311    }
11312
11313    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11314        ContentProviderConnection conn;
11315        try {
11316            conn = (ContentProviderConnection)connection;
11317        } catch (ClassCastException e) {
11318            String msg ="refContentProvider: " + connection
11319                    + " not a ContentProviderConnection";
11320            Slog.w(TAG, msg);
11321            throw new IllegalArgumentException(msg);
11322        }
11323        if (conn == null) {
11324            throw new NullPointerException("connection is null");
11325        }
11326
11327        synchronized (this) {
11328            if (stable > 0) {
11329                conn.numStableIncs += stable;
11330            }
11331            stable = conn.stableCount + stable;
11332            if (stable < 0) {
11333                throw new IllegalStateException("stableCount < 0: " + stable);
11334            }
11335
11336            if (unstable > 0) {
11337                conn.numUnstableIncs += unstable;
11338            }
11339            unstable = conn.unstableCount + unstable;
11340            if (unstable < 0) {
11341                throw new IllegalStateException("unstableCount < 0: " + unstable);
11342            }
11343
11344            if ((stable+unstable) <= 0) {
11345                throw new IllegalStateException("ref counts can't go to zero here: stable="
11346                        + stable + " unstable=" + unstable);
11347            }
11348            conn.stableCount = stable;
11349            conn.unstableCount = unstable;
11350            return !conn.dead;
11351        }
11352    }
11353
11354    public void unstableProviderDied(IBinder connection) {
11355        ContentProviderConnection conn;
11356        try {
11357            conn = (ContentProviderConnection)connection;
11358        } catch (ClassCastException e) {
11359            String msg ="refContentProvider: " + connection
11360                    + " not a ContentProviderConnection";
11361            Slog.w(TAG, msg);
11362            throw new IllegalArgumentException(msg);
11363        }
11364        if (conn == null) {
11365            throw new NullPointerException("connection is null");
11366        }
11367
11368        // Safely retrieve the content provider associated with the connection.
11369        IContentProvider provider;
11370        synchronized (this) {
11371            provider = conn.provider.provider;
11372        }
11373
11374        if (provider == null) {
11375            // Um, yeah, we're way ahead of you.
11376            return;
11377        }
11378
11379        // Make sure the caller is being honest with us.
11380        if (provider.asBinder().pingBinder()) {
11381            // Er, no, still looks good to us.
11382            synchronized (this) {
11383                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11384                        + " says " + conn + " died, but we don't agree");
11385                return;
11386            }
11387        }
11388
11389        // Well look at that!  It's dead!
11390        synchronized (this) {
11391            if (conn.provider.provider != provider) {
11392                // But something changed...  good enough.
11393                return;
11394            }
11395
11396            ProcessRecord proc = conn.provider.proc;
11397            if (proc == null || proc.thread == null) {
11398                // Seems like the process is already cleaned up.
11399                return;
11400            }
11401
11402            // As far as we're concerned, this is just like receiving a
11403            // death notification...  just a bit prematurely.
11404            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11405                    + ") early provider death");
11406            final long ident = Binder.clearCallingIdentity();
11407            try {
11408                appDiedLocked(proc);
11409            } finally {
11410                Binder.restoreCallingIdentity(ident);
11411            }
11412        }
11413    }
11414
11415    @Override
11416    public void appNotRespondingViaProvider(IBinder connection) {
11417        enforceCallingPermission(
11418                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11419
11420        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11421        if (conn == null) {
11422            Slog.w(TAG, "ContentProviderConnection is null");
11423            return;
11424        }
11425
11426        final ProcessRecord host = conn.provider.proc;
11427        if (host == null) {
11428            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11429            return;
11430        }
11431
11432        mHandler.post(new Runnable() {
11433            @Override
11434            public void run() {
11435                mAppErrors.appNotResponding(host, null, null, false,
11436                        "ContentProvider not responding");
11437            }
11438        });
11439    }
11440
11441    public final void installSystemProviders() {
11442        List<ProviderInfo> providers;
11443        synchronized (this) {
11444            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11445            providers = generateApplicationProvidersLocked(app);
11446            if (providers != null) {
11447                for (int i=providers.size()-1; i>=0; i--) {
11448                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11449                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11450                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11451                                + ": not system .apk");
11452                        providers.remove(i);
11453                    }
11454                }
11455            }
11456        }
11457        if (providers != null) {
11458            mSystemThread.installSystemProviders(providers);
11459        }
11460
11461        mCoreSettingsObserver = new CoreSettingsObserver(this);
11462        mFontScaleSettingObserver = new FontScaleSettingObserver();
11463
11464        //mUsageStatsService.monitorPackages();
11465    }
11466
11467    private void startPersistentApps(int matchFlags) {
11468        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11469
11470        synchronized (this) {
11471            try {
11472                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11473                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11474                for (ApplicationInfo app : apps) {
11475                    if (!"android".equals(app.packageName)) {
11476                        addAppLocked(app, false, null /* ABI override */);
11477                    }
11478                }
11479            } catch (RemoteException ex) {
11480            }
11481        }
11482    }
11483
11484    /**
11485     * When a user is unlocked, we need to install encryption-unaware providers
11486     * belonging to any running apps.
11487     */
11488    private void installEncryptionUnawareProviders(int userId) {
11489        // We're only interested in providers that are encryption unaware, and
11490        // we don't care about uninstalled apps, since there's no way they're
11491        // running at this point.
11492        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11493
11494        synchronized (this) {
11495            final int NP = mProcessNames.getMap().size();
11496            for (int ip = 0; ip < NP; ip++) {
11497                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11498                final int NA = apps.size();
11499                for (int ia = 0; ia < NA; ia++) {
11500                    final ProcessRecord app = apps.valueAt(ia);
11501                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11502
11503                    final int NG = app.pkgList.size();
11504                    for (int ig = 0; ig < NG; ig++) {
11505                        try {
11506                            final String pkgName = app.pkgList.keyAt(ig);
11507                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11508                                    .getPackageInfo(pkgName, matchFlags, userId);
11509                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11510                                for (ProviderInfo pi : pkgInfo.providers) {
11511                                    // TODO: keep in sync with generateApplicationProvidersLocked
11512                                    final boolean processMatch = Objects.equals(pi.processName,
11513                                            app.processName) || pi.multiprocess;
11514                                    final boolean userMatch = isSingleton(pi.processName,
11515                                            pi.applicationInfo, pi.name, pi.flags)
11516                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11517                                    if (processMatch && userMatch) {
11518                                        Log.v(TAG, "Installing " + pi);
11519                                        app.thread.scheduleInstallProvider(pi);
11520                                    } else {
11521                                        Log.v(TAG, "Skipping " + pi);
11522                                    }
11523                                }
11524                            }
11525                        } catch (RemoteException ignored) {
11526                        }
11527                    }
11528                }
11529            }
11530        }
11531    }
11532
11533    /**
11534     * Allows apps to retrieve the MIME type of a URI.
11535     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11536     * users, then it does not need permission to access the ContentProvider.
11537     * Either, it needs cross-user uri grants.
11538     *
11539     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11540     *
11541     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11542     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11543     */
11544    public String getProviderMimeType(Uri uri, int userId) {
11545        enforceNotIsolatedCaller("getProviderMimeType");
11546        final String name = uri.getAuthority();
11547        int callingUid = Binder.getCallingUid();
11548        int callingPid = Binder.getCallingPid();
11549        long ident = 0;
11550        boolean clearedIdentity = false;
11551        synchronized (this) {
11552            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11553        }
11554        if (canClearIdentity(callingPid, callingUid, userId)) {
11555            clearedIdentity = true;
11556            ident = Binder.clearCallingIdentity();
11557        }
11558        ContentProviderHolder holder = null;
11559        try {
11560            holder = getContentProviderExternalUnchecked(name, null, userId);
11561            if (holder != null) {
11562                return holder.provider.getType(uri);
11563            }
11564        } catch (RemoteException e) {
11565            Log.w(TAG, "Content provider dead retrieving " + uri, e);
11566            return null;
11567        } catch (Exception e) {
11568            Log.w(TAG, "Exception while determining type of " + uri, e);
11569            return null;
11570        } finally {
11571            // We need to clear the identity to call removeContentProviderExternalUnchecked
11572            if (!clearedIdentity) {
11573                ident = Binder.clearCallingIdentity();
11574            }
11575            try {
11576                if (holder != null) {
11577                    removeContentProviderExternalUnchecked(name, null, userId);
11578                }
11579            } finally {
11580                Binder.restoreCallingIdentity(ident);
11581            }
11582        }
11583
11584        return null;
11585    }
11586
11587    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11588        if (UserHandle.getUserId(callingUid) == userId) {
11589            return true;
11590        }
11591        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11592                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11593                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11594                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11595                return true;
11596        }
11597        return false;
11598    }
11599
11600    // =========================================================
11601    // GLOBAL MANAGEMENT
11602    // =========================================================
11603
11604    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11605            boolean isolated, int isolatedUid) {
11606        String proc = customProcess != null ? customProcess : info.processName;
11607        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11608        final int userId = UserHandle.getUserId(info.uid);
11609        int uid = info.uid;
11610        if (isolated) {
11611            if (isolatedUid == 0) {
11612                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11613                while (true) {
11614                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11615                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11616                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11617                    }
11618                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11619                    mNextIsolatedProcessUid++;
11620                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11621                        // No process for this uid, use it.
11622                        break;
11623                    }
11624                    stepsLeft--;
11625                    if (stepsLeft <= 0) {
11626                        return null;
11627                    }
11628                }
11629            } else {
11630                // Special case for startIsolatedProcess (internal only), where
11631                // the uid of the isolated process is specified by the caller.
11632                uid = isolatedUid;
11633            }
11634
11635            // Register the isolated UID with this application so BatteryStats knows to
11636            // attribute resource usage to the application.
11637            //
11638            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11639            // about the process state of the isolated UID *before* it is registered with the
11640            // owning application.
11641            mBatteryStatsService.addIsolatedUid(uid, info.uid);
11642        }
11643        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11644        if (!mBooted && !mBooting
11645                && userId == UserHandle.USER_SYSTEM
11646                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11647            r.persistent = true;
11648            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11649        }
11650        addProcessNameLocked(r);
11651        return r;
11652    }
11653
11654    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11655            String abiOverride) {
11656        ProcessRecord app;
11657        if (!isolated) {
11658            app = getProcessRecordLocked(info.processName, info.uid, true);
11659        } else {
11660            app = null;
11661        }
11662
11663        if (app == null) {
11664            app = newProcessRecordLocked(info, null, isolated, 0);
11665            updateLruProcessLocked(app, false, null);
11666            updateOomAdjLocked();
11667        }
11668
11669        // This package really, really can not be stopped.
11670        try {
11671            AppGlobals.getPackageManager().setPackageStoppedState(
11672                    info.packageName, false, UserHandle.getUserId(app.uid));
11673        } catch (RemoteException e) {
11674        } catch (IllegalArgumentException e) {
11675            Slog.w(TAG, "Failed trying to unstop package "
11676                    + info.packageName + ": " + e);
11677        }
11678
11679        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11680            app.persistent = true;
11681            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11682        }
11683        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11684            mPersistentStartingProcesses.add(app);
11685            startProcessLocked(app, "added application", app.processName, abiOverride,
11686                    null /* entryPoint */, null /* entryPointArgs */);
11687        }
11688
11689        return app;
11690    }
11691
11692    public void unhandledBack() {
11693        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11694                "unhandledBack()");
11695
11696        synchronized(this) {
11697            final long origId = Binder.clearCallingIdentity();
11698            try {
11699                getFocusedStack().unhandledBackLocked();
11700            } finally {
11701                Binder.restoreCallingIdentity(origId);
11702            }
11703        }
11704    }
11705
11706    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
11707        enforceNotIsolatedCaller("openContentUri");
11708        final int userId = UserHandle.getCallingUserId();
11709        final Uri uri = Uri.parse(uriString);
11710        String name = uri.getAuthority();
11711        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11712        ParcelFileDescriptor pfd = null;
11713        if (cph != null) {
11714            // We record the binder invoker's uid in thread-local storage before
11715            // going to the content provider to open the file.  Later, in the code
11716            // that handles all permissions checks, we look for this uid and use
11717            // that rather than the Activity Manager's own uid.  The effect is that
11718            // we do the check against the caller's permissions even though it looks
11719            // to the content provider like the Activity Manager itself is making
11720            // the request.
11721            Binder token = new Binder();
11722            sCallerIdentity.set(new Identity(
11723                    token, Binder.getCallingPid(), Binder.getCallingUid()));
11724            try {
11725                pfd = cph.provider.openFile(null, uri, "r", null, token);
11726            } catch (FileNotFoundException e) {
11727                // do nothing; pfd will be returned null
11728            } finally {
11729                // Ensure that whatever happens, we clean up the identity state
11730                sCallerIdentity.remove();
11731                // Ensure we're done with the provider.
11732                removeContentProviderExternalUnchecked(name, null, userId);
11733            }
11734        } else {
11735            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11736        }
11737        return pfd;
11738    }
11739
11740    // Actually is sleeping or shutting down or whatever else in the future
11741    // is an inactive state.
11742    boolean isSleepingOrShuttingDownLocked() {
11743        return isSleepingLocked() || mShuttingDown;
11744    }
11745
11746    boolean isShuttingDownLocked() {
11747        return mShuttingDown;
11748    }
11749
11750    boolean isSleepingLocked() {
11751        return mSleeping;
11752    }
11753
11754    void onWakefulnessChanged(int wakefulness) {
11755        synchronized(this) {
11756            mWakefulness = wakefulness;
11757            updateSleepIfNeededLocked();
11758        }
11759    }
11760
11761    void finishRunningVoiceLocked() {
11762        if (mRunningVoice != null) {
11763            mRunningVoice = null;
11764            mVoiceWakeLock.release();
11765            updateSleepIfNeededLocked();
11766        }
11767    }
11768
11769    void startTimeTrackingFocusedActivityLocked() {
11770        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
11771        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
11772            mCurAppTimeTracker.start(resumedActivity.packageName);
11773        }
11774    }
11775
11776    void updateSleepIfNeededLocked() {
11777        if (mSleeping && !shouldSleepLocked()) {
11778            mSleeping = false;
11779            startTimeTrackingFocusedActivityLocked();
11780            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11781            mStackSupervisor.comeOutOfSleepIfNeededLocked();
11782            sendNotifyVrManagerOfSleepState(false);
11783            updateOomAdjLocked();
11784        } else if (!mSleeping && shouldSleepLocked()) {
11785            mSleeping = true;
11786            if (mCurAppTimeTracker != null) {
11787                mCurAppTimeTracker.stop();
11788            }
11789            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11790            mStackSupervisor.goingToSleepLocked();
11791            sendNotifyVrManagerOfSleepState(true);
11792            updateOomAdjLocked();
11793
11794            // Initialize the wake times of all processes.
11795            checkExcessivePowerUsageLocked(false);
11796            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11797            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11798            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11799        }
11800    }
11801
11802    private boolean shouldSleepLocked() {
11803        // Resume applications while running a voice interactor.
11804        if (mRunningVoice != null) {
11805            return false;
11806        }
11807
11808        // TODO: Transform the lock screen state into a sleep token instead.
11809        switch (mWakefulness) {
11810            case PowerManagerInternal.WAKEFULNESS_AWAKE:
11811            case PowerManagerInternal.WAKEFULNESS_DREAMING:
11812            case PowerManagerInternal.WAKEFULNESS_DOZING:
11813                // Pause applications whenever the lock screen is shown or any sleep
11814                // tokens have been acquired.
11815                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
11816            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11817            default:
11818                // If we're asleep then pause applications unconditionally.
11819                return true;
11820        }
11821    }
11822
11823    /** Pokes the task persister. */
11824    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11825        mRecentTasks.notifyTaskPersisterLocked(task, flush);
11826    }
11827
11828    /** Notifies all listeners when the pinned stack animation ends. */
11829    @Override
11830    public void notifyPinnedStackAnimationEnded() {
11831        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
11832    }
11833
11834    @Override
11835    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11836        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11837    }
11838
11839    @Override
11840    public boolean shutdown(int timeout) {
11841        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11842                != PackageManager.PERMISSION_GRANTED) {
11843            throw new SecurityException("Requires permission "
11844                    + android.Manifest.permission.SHUTDOWN);
11845        }
11846
11847        boolean timedout = false;
11848
11849        synchronized(this) {
11850            mShuttingDown = true;
11851            updateEventDispatchingLocked();
11852            timedout = mStackSupervisor.shutdownLocked(timeout);
11853        }
11854
11855        mAppOpsService.shutdown();
11856        if (mUsageStatsService != null) {
11857            mUsageStatsService.prepareShutdown();
11858        }
11859        mBatteryStatsService.shutdown();
11860        synchronized (this) {
11861            mProcessStats.shutdownLocked();
11862            notifyTaskPersisterLocked(null, true);
11863        }
11864
11865        return timedout;
11866    }
11867
11868    public final void activitySlept(IBinder token) {
11869        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11870
11871        final long origId = Binder.clearCallingIdentity();
11872
11873        synchronized (this) {
11874            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11875            if (r != null) {
11876                mStackSupervisor.activitySleptLocked(r);
11877            }
11878        }
11879
11880        Binder.restoreCallingIdentity(origId);
11881    }
11882
11883    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11884        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11885        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11886        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11887            boolean wasRunningVoice = mRunningVoice != null;
11888            mRunningVoice = session;
11889            if (!wasRunningVoice) {
11890                mVoiceWakeLock.acquire();
11891                updateSleepIfNeededLocked();
11892            }
11893        }
11894    }
11895
11896    private void updateEventDispatchingLocked() {
11897        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11898    }
11899
11900    @Override
11901    public void setLockScreenShown(boolean showing) {
11902        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11903                != PackageManager.PERMISSION_GRANTED) {
11904            throw new SecurityException("Requires permission "
11905                    + android.Manifest.permission.DEVICE_POWER);
11906        }
11907
11908        synchronized(this) {
11909            long ident = Binder.clearCallingIdentity();
11910            try {
11911                mKeyguardController.setKeyguardShown(showing);
11912            } finally {
11913                Binder.restoreCallingIdentity(ident);
11914            }
11915        }
11916    }
11917
11918    @Override
11919    public void notifyLockedProfile(@UserIdInt int userId) {
11920        try {
11921            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11922                throw new SecurityException("Only privileged app can call notifyLockedProfile");
11923            }
11924        } catch (RemoteException ex) {
11925            throw new SecurityException("Fail to check is caller a privileged app", ex);
11926        }
11927
11928        synchronized (this) {
11929            final long ident = Binder.clearCallingIdentity();
11930            try {
11931                if (mUserController.shouldConfirmCredentials(userId)) {
11932                    final int currentUserId = mUserController.getCurrentUserIdLocked();
11933                    if (!mKeyguardController.isKeyguardLocked()) {
11934                        // If the device is not locked, we will prompt for credentials immediately.
11935                        mStackSupervisor.lockAllProfileTasks(userId);
11936                    } else {
11937                        // Showing launcher to avoid user entering credential twice.
11938                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11939                    }
11940                }
11941            } finally {
11942                Binder.restoreCallingIdentity(ident);
11943            }
11944        }
11945    }
11946
11947    @Override
11948    public void startConfirmDeviceCredentialIntent(Intent intent) {
11949        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11950        synchronized (this) {
11951            final long ident = Binder.clearCallingIdentity();
11952            try {
11953                mActivityStarter.startConfirmCredentialIntent(intent);
11954            } finally {
11955                Binder.restoreCallingIdentity(ident);
11956            }
11957        }
11958    }
11959
11960    @Override
11961    public void stopAppSwitches() {
11962        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11963                != PackageManager.PERMISSION_GRANTED) {
11964            throw new SecurityException("viewquires permission "
11965                    + android.Manifest.permission.STOP_APP_SWITCHES);
11966        }
11967
11968        synchronized(this) {
11969            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11970                    + APP_SWITCH_DELAY_TIME;
11971            mDidAppSwitch = false;
11972            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11973            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11974            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11975        }
11976    }
11977
11978    public void resumeAppSwitches() {
11979        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11980                != PackageManager.PERMISSION_GRANTED) {
11981            throw new SecurityException("Requires permission "
11982                    + android.Manifest.permission.STOP_APP_SWITCHES);
11983        }
11984
11985        synchronized(this) {
11986            // Note that we don't execute any pending app switches... we will
11987            // let those wait until either the timeout, or the next start
11988            // activity request.
11989            mAppSwitchesAllowedTime = 0;
11990        }
11991    }
11992
11993    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11994            int callingPid, int callingUid, String name) {
11995        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11996            return true;
11997        }
11998
11999        int perm = checkComponentPermission(
12000                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12001                sourceUid, -1, true);
12002        if (perm == PackageManager.PERMISSION_GRANTED) {
12003            return true;
12004        }
12005
12006        // If the actual IPC caller is different from the logical source, then
12007        // also see if they are allowed to control app switches.
12008        if (callingUid != -1 && callingUid != sourceUid) {
12009            perm = checkComponentPermission(
12010                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12011                    callingUid, -1, true);
12012            if (perm == PackageManager.PERMISSION_GRANTED) {
12013                return true;
12014            }
12015        }
12016
12017        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12018        return false;
12019    }
12020
12021    public void setDebugApp(String packageName, boolean waitForDebugger,
12022            boolean persistent) {
12023        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12024                "setDebugApp()");
12025
12026        long ident = Binder.clearCallingIdentity();
12027        try {
12028            // Note that this is not really thread safe if there are multiple
12029            // callers into it at the same time, but that's not a situation we
12030            // care about.
12031            if (persistent) {
12032                final ContentResolver resolver = mContext.getContentResolver();
12033                Settings.Global.putString(
12034                    resolver, Settings.Global.DEBUG_APP,
12035                    packageName);
12036                Settings.Global.putInt(
12037                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12038                    waitForDebugger ? 1 : 0);
12039            }
12040
12041            synchronized (this) {
12042                if (!persistent) {
12043                    mOrigDebugApp = mDebugApp;
12044                    mOrigWaitForDebugger = mWaitForDebugger;
12045                }
12046                mDebugApp = packageName;
12047                mWaitForDebugger = waitForDebugger;
12048                mDebugTransient = !persistent;
12049                if (packageName != null) {
12050                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12051                            false, UserHandle.USER_ALL, "set debug app");
12052                }
12053            }
12054        } finally {
12055            Binder.restoreCallingIdentity(ident);
12056        }
12057    }
12058
12059    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12060        synchronized (this) {
12061            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12062            if (!isDebuggable) {
12063                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12064                    throw new SecurityException("Process not debuggable: " + app.packageName);
12065                }
12066            }
12067
12068            mTrackAllocationApp = processName;
12069        }
12070    }
12071
12072    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12073        synchronized (this) {
12074            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12075            if (!isDebuggable) {
12076                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12077                    throw new SecurityException("Process not debuggable: " + app.packageName);
12078                }
12079            }
12080            mProfileApp = processName;
12081            mProfileFile = profilerInfo.profileFile;
12082            if (mProfileFd != null) {
12083                try {
12084                    mProfileFd.close();
12085                } catch (IOException e) {
12086                }
12087                mProfileFd = null;
12088            }
12089            mProfileFd = profilerInfo.profileFd;
12090            mSamplingInterval = profilerInfo.samplingInterval;
12091            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12092            mProfileType = 0;
12093        }
12094    }
12095
12096    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12097        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12098        if (!isDebuggable) {
12099            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12100                throw new SecurityException("Process not debuggable: " + app.packageName);
12101            }
12102        }
12103        mNativeDebuggingApp = processName;
12104    }
12105
12106    @Override
12107    public void setAlwaysFinish(boolean enabled) {
12108        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12109                "setAlwaysFinish()");
12110
12111        long ident = Binder.clearCallingIdentity();
12112        try {
12113            Settings.Global.putInt(
12114                    mContext.getContentResolver(),
12115                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12116
12117            synchronized (this) {
12118                mAlwaysFinishActivities = enabled;
12119            }
12120        } finally {
12121            Binder.restoreCallingIdentity(ident);
12122        }
12123    }
12124
12125    @Override
12126    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12127        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12128                "setActivityController()");
12129        synchronized (this) {
12130            mController = controller;
12131            mControllerIsAMonkey = imAMonkey;
12132            Watchdog.getInstance().setActivityController(controller);
12133        }
12134    }
12135
12136    @Override
12137    public void setUserIsMonkey(boolean userIsMonkey) {
12138        synchronized (this) {
12139            synchronized (mPidsSelfLocked) {
12140                final int callingPid = Binder.getCallingPid();
12141                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12142                if (precessRecord == null) {
12143                    throw new SecurityException("Unknown process: " + callingPid);
12144                }
12145                if (precessRecord.instrumentationUiAutomationConnection  == null) {
12146                    throw new SecurityException("Only an instrumentation process "
12147                            + "with a UiAutomation can call setUserIsMonkey");
12148                }
12149            }
12150            mUserIsMonkey = userIsMonkey;
12151        }
12152    }
12153
12154    @Override
12155    public boolean isUserAMonkey() {
12156        synchronized (this) {
12157            // If there is a controller also implies the user is a monkey.
12158            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12159        }
12160    }
12161
12162    /**
12163     * @deprecated This method is only used by a few internal components and it will soon be
12164     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12165     * No new code should be calling it.
12166     */
12167    @Deprecated
12168    public void requestBugReport(int bugreportType) {
12169        String extraOptions = null;
12170        switch (bugreportType) {
12171            case ActivityManager.BUGREPORT_OPTION_FULL:
12172                // Default options.
12173                break;
12174            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12175                extraOptions = "bugreportplus";
12176                break;
12177            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12178                extraOptions = "bugreportremote";
12179                break;
12180            case ActivityManager.BUGREPORT_OPTION_WEAR:
12181                extraOptions = "bugreportwear";
12182                break;
12183            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12184                extraOptions = "bugreporttelephony";
12185                break;
12186            default:
12187                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12188                        + bugreportType);
12189        }
12190        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12191        if (extraOptions != null) {
12192            SystemProperties.set("dumpstate.options", extraOptions);
12193        }
12194        SystemProperties.set("ctl.start", "bugreport");
12195    }
12196
12197    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12198        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12199    }
12200
12201    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12202        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12203            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12204        }
12205        return KEY_DISPATCHING_TIMEOUT;
12206    }
12207
12208    @Override
12209    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12210        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12211                != PackageManager.PERMISSION_GRANTED) {
12212            throw new SecurityException("Requires permission "
12213                    + android.Manifest.permission.FILTER_EVENTS);
12214        }
12215        ProcessRecord proc;
12216        long timeout;
12217        synchronized (this) {
12218            synchronized (mPidsSelfLocked) {
12219                proc = mPidsSelfLocked.get(pid);
12220            }
12221            timeout = getInputDispatchingTimeoutLocked(proc);
12222        }
12223
12224        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12225            return -1;
12226        }
12227
12228        return timeout;
12229    }
12230
12231    /**
12232     * Handle input dispatching timeouts.
12233     * Returns whether input dispatching should be aborted or not.
12234     */
12235    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12236            final ActivityRecord activity, final ActivityRecord parent,
12237            final boolean aboveSystem, String reason) {
12238        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12239                != PackageManager.PERMISSION_GRANTED) {
12240            throw new SecurityException("Requires permission "
12241                    + android.Manifest.permission.FILTER_EVENTS);
12242        }
12243
12244        final String annotation;
12245        if (reason == null) {
12246            annotation = "Input dispatching timed out";
12247        } else {
12248            annotation = "Input dispatching timed out (" + reason + ")";
12249        }
12250
12251        if (proc != null) {
12252            synchronized (this) {
12253                if (proc.debugging) {
12254                    return false;
12255                }
12256
12257                if (mDidDexOpt) {
12258                    // Give more time since we were dexopting.
12259                    mDidDexOpt = false;
12260                    return false;
12261                }
12262
12263                if (proc.instrumentationClass != null) {
12264                    Bundle info = new Bundle();
12265                    info.putString("shortMsg", "keyDispatchingTimedOut");
12266                    info.putString("longMsg", annotation);
12267                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12268                    return true;
12269                }
12270            }
12271            mHandler.post(new Runnable() {
12272                @Override
12273                public void run() {
12274                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12275                }
12276            });
12277        }
12278
12279        return true;
12280    }
12281
12282    @Override
12283    public Bundle getAssistContextExtras(int requestType) {
12284        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12285                null, 0, null, true /* focused */, true /* newSessionId */,
12286                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
12287        if (pae == null) {
12288            return null;
12289        }
12290        synchronized (pae) {
12291            while (!pae.haveResult) {
12292                try {
12293                    pae.wait();
12294                } catch (InterruptedException e) {
12295                }
12296            }
12297        }
12298        synchronized (this) {
12299            buildAssistBundleLocked(pae, pae.result);
12300            mPendingAssistExtras.remove(pae);
12301            mUiHandler.removeCallbacks(pae);
12302        }
12303        return pae.extras;
12304    }
12305
12306    @Override
12307    public boolean isAssistDataAllowedOnCurrentActivity() {
12308        int userId;
12309        synchronized (this) {
12310            userId = mUserController.getCurrentUserIdLocked();
12311            ActivityRecord activity = getFocusedStack().topActivity();
12312            if (activity == null) {
12313                return false;
12314            }
12315            userId = activity.userId;
12316        }
12317        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12318                Context.DEVICE_POLICY_SERVICE);
12319        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12320    }
12321
12322    @Override
12323    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12324        long ident = Binder.clearCallingIdentity();
12325        try {
12326            synchronized (this) {
12327                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12328                ActivityRecord top = getFocusedStack().topActivity();
12329                if (top != caller) {
12330                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12331                            + " is not current top " + top);
12332                    return false;
12333                }
12334                if (!top.nowVisible) {
12335                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12336                            + " is not visible");
12337                    return false;
12338                }
12339            }
12340            AssistUtils utils = new AssistUtils(mContext);
12341            return utils.showSessionForActiveService(args,
12342                    VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12343        } finally {
12344            Binder.restoreCallingIdentity(ident);
12345        }
12346    }
12347
12348    @Override
12349    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12350            Bundle receiverExtras,
12351            IBinder activityToken, boolean focused, boolean newSessionId) {
12352        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12353                0, activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
12354                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
12355    }
12356
12357    @Override
12358    public boolean requestAutoFillData(IResultReceiver receiver, Bundle receiverExtras,
12359            int resultCode, IBinder activityToken, int flags) {
12360        final boolean forFill = (flags & View.AUTO_FILL_FLAG_TYPE_FILL) != 0;
12361        final boolean forSave = (flags & View.AUTO_FILL_FLAG_TYPE_SAVE) != 0;
12362        if ((forFill && forSave) || (!forFill) && !(forSave)) {
12363            // There can be only one!
12364            Slog.w(TAG,  "requestAutoFillData(): invalid flags (" + flags + ")");
12365            return false;
12366        }
12367
12368        // NOTE: we could always use ActivityManager.ASSIST_CONTEXT_FULL and let ActivityThread
12369        // rely on the flags to decide whether the handleRequestAssistContextExtras() is for
12370        // auto-fill, but it's safer to explicitly use new AutoFill types, in case the Assist
12371        // requests use flags in the future as well (since their flags value might collide with the
12372        // auto-fill flag values).
12373        final int type = forFill?
12374                ActivityManager.ASSIST_CONTEXT_AUTO_FILL :
12375                    ActivityManager.ASSIST_CONTEXT_AUTO_FILL_SAVE;
12376
12377        return enqueueAssistContext(type, null, null, receiver, receiverExtras, resultCode,
12378                activityToken, true, true, UserHandle.getCallingUserId(), null,
12379                PENDING_AUTO_FILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
12380    }
12381
12382    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12383            IResultReceiver receiver, Bundle receiverExtras, int resultCode, IBinder activityToken,
12384            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
12385            int flags) {
12386        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12387                "enqueueAssistContext()");
12388        synchronized (this) {
12389            ActivityRecord activity = getFocusedStack().topActivity();
12390            if (activity == null) {
12391                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12392                return null;
12393            }
12394            if (activity.app == null || activity.app.thread == null) {
12395                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12396                return null;
12397            }
12398            if (focused) {
12399                if (activityToken != null) {
12400                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12401                    if (activity != caller) {
12402                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12403                                + " is not current top " + activity);
12404                        return null;
12405                    }
12406                }
12407            } else {
12408                activity = ActivityRecord.forTokenLocked(activityToken);
12409                if (activity == null) {
12410                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12411                            + " couldn't be found");
12412                    return null;
12413                }
12414            }
12415
12416            PendingAssistExtras pae;
12417            Bundle extras = new Bundle();
12418            if (args != null) {
12419                extras.putAll(args);
12420            }
12421            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12422            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12423            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12424                    resultCode, userHandle, flags);
12425            // Increment the sessionId if necessary
12426            if (newSessionId) {
12427                mViSessionId++;
12428            }
12429            try {
12430                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12431                        requestType, mViSessionId, flags);
12432                mPendingAssistExtras.add(pae);
12433                mUiHandler.postDelayed(pae, timeout);
12434            } catch (RemoteException e) {
12435                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12436                return null;
12437            }
12438            return pae;
12439        }
12440    }
12441
12442    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12443        IResultReceiver receiver;
12444        synchronized (this) {
12445            mPendingAssistExtras.remove(pae);
12446            receiver = pae.receiver;
12447        }
12448        if (receiver != null) {
12449            // Caller wants result sent back to them.
12450            Bundle sendBundle = new Bundle();
12451            // At least return the receiver extras
12452            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12453                    pae.receiverExtras);
12454            try {
12455                pae.receiver.send(0, sendBundle);
12456            } catch (RemoteException e) {
12457            }
12458        }
12459    }
12460
12461    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12462        if (result != null) {
12463            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12464        }
12465        if (pae.hint != null) {
12466            pae.extras.putBoolean(pae.hint, true);
12467        }
12468    }
12469
12470    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12471            AssistContent content, Uri referrer) {
12472        PendingAssistExtras pae = (PendingAssistExtras)token;
12473        synchronized (pae) {
12474            pae.result = extras;
12475            pae.structure = structure;
12476            pae.content = content;
12477            if (referrer != null) {
12478                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12479            }
12480            pae.haveResult = true;
12481            pae.notifyAll();
12482            if (pae.intent == null && pae.receiver == null) {
12483                // Caller is just waiting for the result.
12484                return;
12485            }
12486        }
12487
12488        // We are now ready to launch the assist activity.
12489        IResultReceiver sendReceiver = null;
12490        Bundle sendBundle = null;
12491        synchronized (this) {
12492            buildAssistBundleLocked(pae, extras);
12493            boolean exists = mPendingAssistExtras.remove(pae);
12494            mUiHandler.removeCallbacks(pae);
12495            if (!exists) {
12496                // Timed out.
12497                return;
12498            }
12499            if ((sendReceiver=pae.receiver) != null) {
12500                // Caller wants result sent back to them.
12501                sendBundle = new Bundle();
12502                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12503                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12504                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12505                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12506                        pae.receiverExtras);
12507                if (pae.flags > 0) {
12508                    sendBundle.putInt(VoiceInteractionSession.KEY_FLAGS, pae.flags);
12509                }
12510                IBinder cb = extras.getBinder(AutoFillService.KEY_CALLBACK);
12511                if (cb != null) {
12512                    sendBundle.putBinder(AutoFillService.KEY_CALLBACK, cb);
12513                }
12514            }
12515        }
12516        if (sendReceiver != null) {
12517            try {
12518                sendReceiver.send(pae.resultCode, sendBundle);
12519            } catch (RemoteException e) {
12520            }
12521            return;
12522        }
12523
12524        long ident = Binder.clearCallingIdentity();
12525        try {
12526            pae.intent.replaceExtras(pae.extras);
12527            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12528                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
12529                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12530            closeSystemDialogs("assist");
12531            try {
12532                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12533            } catch (ActivityNotFoundException e) {
12534                Slog.w(TAG, "No activity to handle assist action.", e);
12535            }
12536        } finally {
12537            Binder.restoreCallingIdentity(ident);
12538        }
12539    }
12540
12541    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12542            Bundle args) {
12543        return enqueueAssistContext(requestType, intent, hint, null, null, 0, null,
12544                true /* focused */, true /* newSessionId */, userHandle, args,
12545                PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
12546    }
12547
12548    public void registerProcessObserver(IProcessObserver observer) {
12549        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12550                "registerProcessObserver()");
12551        synchronized (this) {
12552            mProcessObservers.register(observer);
12553        }
12554    }
12555
12556    @Override
12557    public void unregisterProcessObserver(IProcessObserver observer) {
12558        synchronized (this) {
12559            mProcessObservers.unregister(observer);
12560        }
12561    }
12562
12563    @Override
12564    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
12565            String callingPackage) {
12566        if (!hasUsageStatsPermission(callingPackage)) {
12567            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
12568                    "registerUidObserver");
12569        }
12570        synchronized (this) {
12571            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
12572                    callingPackage, which, cutpoint));
12573        }
12574    }
12575
12576    @Override
12577    public void unregisterUidObserver(IUidObserver observer) {
12578        synchronized (this) {
12579            mUidObservers.unregister(observer);
12580        }
12581    }
12582
12583    @Override
12584    public boolean convertFromTranslucent(IBinder token) {
12585        final long origId = Binder.clearCallingIdentity();
12586        try {
12587            synchronized (this) {
12588                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12589                if (r == null) {
12590                    return false;
12591                }
12592                final boolean translucentChanged = r.changeWindowTranslucency(true);
12593                if (translucentChanged) {
12594                    r.getStack().releaseBackgroundResources(r);
12595                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12596                }
12597                mWindowManager.setAppFullscreen(token, true);
12598                return translucentChanged;
12599            }
12600        } finally {
12601            Binder.restoreCallingIdentity(origId);
12602        }
12603    }
12604
12605    @Override
12606    public boolean convertToTranslucent(IBinder token, Bundle options) {
12607        final long origId = Binder.clearCallingIdentity();
12608        try {
12609            synchronized (this) {
12610                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12611                if (r == null) {
12612                    return false;
12613                }
12614                int index = r.task.mActivities.lastIndexOf(r);
12615                if (index > 0) {
12616                    ActivityRecord under = r.task.mActivities.get(index - 1);
12617                    under.returningOptions = ActivityOptions.fromBundle(options);
12618                }
12619                final boolean translucentChanged = r.changeWindowTranslucency(false);
12620                if (translucentChanged) {
12621                    r.getStack().convertActivityToTranslucent(r);
12622                }
12623                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12624                mWindowManager.setAppFullscreen(token, false);
12625                return translucentChanged;
12626            }
12627        } finally {
12628            Binder.restoreCallingIdentity(origId);
12629        }
12630    }
12631
12632    @Override
12633    public boolean requestVisibleBehind(IBinder token, boolean visible) {
12634        final long origId = Binder.clearCallingIdentity();
12635        try {
12636            synchronized (this) {
12637                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12638                if (r != null) {
12639                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12640                }
12641            }
12642            return false;
12643        } finally {
12644            Binder.restoreCallingIdentity(origId);
12645        }
12646    }
12647
12648    @Override
12649    public boolean isBackgroundVisibleBehind(IBinder token) {
12650        final long origId = Binder.clearCallingIdentity();
12651        try {
12652            synchronized (this) {
12653                final ActivityStack stack = ActivityRecord.getStackLocked(token);
12654                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12655                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12656                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12657                return visible;
12658            }
12659        } finally {
12660            Binder.restoreCallingIdentity(origId);
12661        }
12662    }
12663
12664    @Override
12665    public Bundle getActivityOptions(IBinder token) {
12666        final long origId = Binder.clearCallingIdentity();
12667        try {
12668            synchronized (this) {
12669                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12670                if (r != null) {
12671                    final ActivityOptions activityOptions = r.pendingOptions;
12672                    r.pendingOptions = null;
12673                    return activityOptions == null ? null : activityOptions.toBundle();
12674                }
12675                return null;
12676            }
12677        } finally {
12678            Binder.restoreCallingIdentity(origId);
12679        }
12680    }
12681
12682    @Override
12683    public void setImmersive(IBinder token, boolean immersive) {
12684        synchronized(this) {
12685            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12686            if (r == null) {
12687                throw new IllegalArgumentException();
12688            }
12689            r.immersive = immersive;
12690
12691            // update associated state if we're frontmost
12692            if (r == mStackSupervisor.getResumedActivityLocked()) {
12693                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12694                applyUpdateLockStateLocked(r);
12695            }
12696        }
12697    }
12698
12699    @Override
12700    public boolean isImmersive(IBinder token) {
12701        synchronized (this) {
12702            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12703            if (r == null) {
12704                throw new IllegalArgumentException();
12705            }
12706            return r.immersive;
12707        }
12708    }
12709
12710    public void setVrThread(int tid) {
12711        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12712            throw new UnsupportedOperationException("VR mode not supported on this device!");
12713        }
12714
12715        synchronized (this) {
12716            ProcessRecord proc;
12717            synchronized (mPidsSelfLocked) {
12718                final int pid = Binder.getCallingPid();
12719                proc = mPidsSelfLocked.get(pid);
12720
12721                if (proc != null && mInVrMode && tid >= 0) {
12722                    // ensure the tid belongs to the process
12723                    if (!Process.isThreadInProcess(pid, tid)) {
12724                        throw new IllegalArgumentException("VR thread does not belong to process");
12725                    }
12726
12727                    // reset existing VR thread to CFS if this thread still exists and belongs to
12728                    // the calling process
12729                    if (proc.vrThreadTid != 0
12730                            && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12731                        try {
12732                            Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12733                        } catch (IllegalArgumentException e) {
12734                            // Ignore this.  Only occurs in race condition where previous VR thread
12735                            // was destroyed during this method call.
12736                        }
12737                    }
12738
12739                    proc.vrThreadTid = tid;
12740
12741                    // promote to FIFO now if the tid is non-zero
12742                    try {
12743                        if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12744                            proc.vrThreadTid > 0) {
12745                            Process.setThreadScheduler(proc.vrThreadTid,
12746                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12747                        }
12748                    } catch (IllegalArgumentException e) {
12749                        Slog.e(TAG, "Failed to set scheduling policy, thread does"
12750                               + " not exist:\n" + e);
12751                    }
12752                }
12753            }
12754        }
12755    }
12756
12757    @Override
12758    public void setRenderThread(int tid) {
12759        synchronized (this) {
12760            ProcessRecord proc;
12761            synchronized (mPidsSelfLocked) {
12762                int pid = Binder.getCallingPid();
12763                proc = mPidsSelfLocked.get(pid);
12764                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12765                    // ensure the tid belongs to the process
12766                    if (!Process.isThreadInProcess(pid, tid)) {
12767                        throw new IllegalArgumentException(
12768                            "Render thread does not belong to process");
12769                    }
12770                    proc.renderThreadTid = tid;
12771                    if (DEBUG_OOM_ADJ) {
12772                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12773                    }
12774                    // promote to FIFO now
12775                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12776                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12777                        if (mUseFifoUiScheduling) {
12778                            Process.setThreadScheduler(proc.renderThreadTid,
12779                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12780                        } else {
12781                            Process.setThreadPriority(proc.renderThreadTid, -10);
12782                        }
12783                    }
12784                } else {
12785                    if (DEBUG_OOM_ADJ) {
12786                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12787                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
12788                               mUseFifoUiScheduling);
12789                    }
12790                }
12791            }
12792        }
12793    }
12794
12795    @Override
12796    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12797        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12798            throw new UnsupportedOperationException("VR mode not supported on this device!");
12799        }
12800
12801        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12802
12803        ActivityRecord r;
12804        synchronized (this) {
12805            r = ActivityRecord.isInStackLocked(token);
12806        }
12807
12808        if (r == null) {
12809            throw new IllegalArgumentException();
12810        }
12811
12812        int err;
12813        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12814                VrManagerInternal.NO_ERROR) {
12815            return err;
12816        }
12817
12818        synchronized(this) {
12819            r.requestedVrComponent = (enabled) ? packageName : null;
12820
12821            // Update associated state if this activity is currently focused
12822            if (r == mStackSupervisor.getResumedActivityLocked()) {
12823                applyUpdateVrModeLocked(r);
12824            }
12825            return 0;
12826        }
12827    }
12828
12829    @Override
12830    public boolean isVrModePackageEnabled(ComponentName packageName) {
12831        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12832            throw new UnsupportedOperationException("VR mode not supported on this device!");
12833        }
12834
12835        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12836
12837        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12838                VrManagerInternal.NO_ERROR;
12839    }
12840
12841    public boolean isTopActivityImmersive() {
12842        enforceNotIsolatedCaller("startActivity");
12843        synchronized (this) {
12844            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12845            return (r != null) ? r.immersive : false;
12846        }
12847    }
12848
12849    @Override
12850    public boolean isTopOfTask(IBinder token) {
12851        synchronized (this) {
12852            ActivityRecord r = ActivityRecord.isInStackLocked(token);
12853            if (r == null) {
12854                throw new IllegalArgumentException();
12855            }
12856            return r.task.getTopActivity() == r;
12857        }
12858    }
12859
12860    @Override
12861    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12862        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12863            String msg = "Permission Denial: setHasTopUi() from pid="
12864                    + Binder.getCallingPid()
12865                    + ", uid=" + Binder.getCallingUid()
12866                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12867            Slog.w(TAG, msg);
12868            throw new SecurityException(msg);
12869        }
12870        final int pid = Binder.getCallingPid();
12871        final long origId = Binder.clearCallingIdentity();
12872        try {
12873            synchronized (this) {
12874                boolean changed = false;
12875                ProcessRecord pr;
12876                synchronized (mPidsSelfLocked) {
12877                    pr = mPidsSelfLocked.get(pid);
12878                    if (pr == null) {
12879                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12880                        return;
12881                    }
12882                    if (pr.hasTopUi != hasTopUi) {
12883                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12884                        pr.hasTopUi = hasTopUi;
12885                        changed = true;
12886                    }
12887                }
12888                if (changed) {
12889                    updateOomAdjLocked(pr);
12890                }
12891            }
12892        } finally {
12893            Binder.restoreCallingIdentity(origId);
12894        }
12895    }
12896
12897    public final void enterSafeMode() {
12898        synchronized(this) {
12899            // It only makes sense to do this before the system is ready
12900            // and started launching other packages.
12901            if (!mSystemReady) {
12902                try {
12903                    AppGlobals.getPackageManager().enterSafeMode();
12904                } catch (RemoteException e) {
12905                }
12906            }
12907
12908            mSafeMode = true;
12909        }
12910    }
12911
12912    public final void showSafeModeOverlay() {
12913        View v = LayoutInflater.from(mContext).inflate(
12914                com.android.internal.R.layout.safe_mode, null);
12915        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12916        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12917        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12918        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12919        lp.gravity = Gravity.BOTTOM | Gravity.START;
12920        lp.format = v.getBackground().getOpacity();
12921        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12922                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12923        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12924        ((WindowManager)mContext.getSystemService(
12925                Context.WINDOW_SERVICE)).addView(v, lp);
12926    }
12927
12928    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12929        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12930            return;
12931        }
12932        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12933        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12934        synchronized (stats) {
12935            if (mBatteryStatsService.isOnBattery()) {
12936                mBatteryStatsService.enforceCallingPermission();
12937                int MY_UID = Binder.getCallingUid();
12938                final int uid;
12939                if (sender == null) {
12940                    uid = sourceUid;
12941                } else {
12942                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12943                }
12944                BatteryStatsImpl.Uid.Pkg pkg =
12945                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12946                            sourcePkg != null ? sourcePkg : rec.key.packageName);
12947                pkg.noteWakeupAlarmLocked(tag);
12948            }
12949        }
12950    }
12951
12952    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12953        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12954            return;
12955        }
12956        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12957        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12958        synchronized (stats) {
12959            mBatteryStatsService.enforceCallingPermission();
12960            int MY_UID = Binder.getCallingUid();
12961            final int uid;
12962            if (sender == null) {
12963                uid = sourceUid;
12964            } else {
12965                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12966            }
12967            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12968        }
12969    }
12970
12971    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12972        if (sender != null && !(sender instanceof PendingIntentRecord)) {
12973            return;
12974        }
12975        final PendingIntentRecord rec = (PendingIntentRecord)sender;
12976        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12977        synchronized (stats) {
12978            mBatteryStatsService.enforceCallingPermission();
12979            int MY_UID = Binder.getCallingUid();
12980            final int uid;
12981            if (sender == null) {
12982                uid = sourceUid;
12983            } else {
12984                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12985            }
12986            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12987        }
12988    }
12989
12990    public boolean killPids(int[] pids, String pReason, boolean secure) {
12991        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12992            throw new SecurityException("killPids only available to the system");
12993        }
12994        String reason = (pReason == null) ? "Unknown" : pReason;
12995        // XXX Note: don't acquire main activity lock here, because the window
12996        // manager calls in with its locks held.
12997
12998        boolean killed = false;
12999        synchronized (mPidsSelfLocked) {
13000            int worstType = 0;
13001            for (int i=0; i<pids.length; i++) {
13002                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13003                if (proc != null) {
13004                    int type = proc.setAdj;
13005                    if (type > worstType) {
13006                        worstType = type;
13007                    }
13008                }
13009            }
13010
13011            // If the worst oom_adj is somewhere in the cached proc LRU range,
13012            // then constrain it so we will kill all cached procs.
13013            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13014                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13015                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13016            }
13017
13018            // If this is not a secure call, don't let it kill processes that
13019            // are important.
13020            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13021                worstType = ProcessList.SERVICE_ADJ;
13022            }
13023
13024            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13025            for (int i=0; i<pids.length; i++) {
13026                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13027                if (proc == null) {
13028                    continue;
13029                }
13030                int adj = proc.setAdj;
13031                if (adj >= worstType && !proc.killedByAm) {
13032                    proc.kill(reason, true);
13033                    killed = true;
13034                }
13035            }
13036        }
13037        return killed;
13038    }
13039
13040    @Override
13041    public void killUid(int appId, int userId, String reason) {
13042        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13043        synchronized (this) {
13044            final long identity = Binder.clearCallingIdentity();
13045            try {
13046                killPackageProcessesLocked(null, appId, userId,
13047                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13048                        reason != null ? reason : "kill uid");
13049            } finally {
13050                Binder.restoreCallingIdentity(identity);
13051            }
13052        }
13053    }
13054
13055    @Override
13056    public boolean killProcessesBelowForeground(String reason) {
13057        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13058            throw new SecurityException("killProcessesBelowForeground() only available to system");
13059        }
13060
13061        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13062    }
13063
13064    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13065        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13066            throw new SecurityException("killProcessesBelowAdj() only available to system");
13067        }
13068
13069        boolean killed = false;
13070        synchronized (mPidsSelfLocked) {
13071            final int size = mPidsSelfLocked.size();
13072            for (int i = 0; i < size; i++) {
13073                final int pid = mPidsSelfLocked.keyAt(i);
13074                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13075                if (proc == null) continue;
13076
13077                final int adj = proc.setAdj;
13078                if (adj > belowAdj && !proc.killedByAm) {
13079                    proc.kill(reason, true);
13080                    killed = true;
13081                }
13082            }
13083        }
13084        return killed;
13085    }
13086
13087    @Override
13088    public void hang(final IBinder who, boolean allowRestart) {
13089        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13090                != PackageManager.PERMISSION_GRANTED) {
13091            throw new SecurityException("Requires permission "
13092                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13093        }
13094
13095        final IBinder.DeathRecipient death = new DeathRecipient() {
13096            @Override
13097            public void binderDied() {
13098                synchronized (this) {
13099                    notifyAll();
13100                }
13101            }
13102        };
13103
13104        try {
13105            who.linkToDeath(death, 0);
13106        } catch (RemoteException e) {
13107            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13108            return;
13109        }
13110
13111        synchronized (this) {
13112            Watchdog.getInstance().setAllowRestart(allowRestart);
13113            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13114            synchronized (death) {
13115                while (who.isBinderAlive()) {
13116                    try {
13117                        death.wait();
13118                    } catch (InterruptedException e) {
13119                    }
13120                }
13121            }
13122            Watchdog.getInstance().setAllowRestart(true);
13123        }
13124    }
13125
13126    @Override
13127    public void restart() {
13128        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13129                != PackageManager.PERMISSION_GRANTED) {
13130            throw new SecurityException("Requires permission "
13131                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13132        }
13133
13134        Log.i(TAG, "Sending shutdown broadcast...");
13135
13136        BroadcastReceiver br = new BroadcastReceiver() {
13137            @Override public void onReceive(Context context, Intent intent) {
13138                // Now the broadcast is done, finish up the low-level shutdown.
13139                Log.i(TAG, "Shutting down activity manager...");
13140                shutdown(10000);
13141                Log.i(TAG, "Shutdown complete, restarting!");
13142                Process.killProcess(Process.myPid());
13143                System.exit(10);
13144            }
13145        };
13146
13147        // First send the high-level shut down broadcast.
13148        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13149        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13150        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13151        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13152        mContext.sendOrderedBroadcastAsUser(intent,
13153                UserHandle.ALL, null, br, mHandler, 0, null, null);
13154        */
13155        br.onReceive(mContext, intent);
13156    }
13157
13158    private long getLowRamTimeSinceIdle(long now) {
13159        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13160    }
13161
13162    @Override
13163    public void performIdleMaintenance() {
13164        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13165                != PackageManager.PERMISSION_GRANTED) {
13166            throw new SecurityException("Requires permission "
13167                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13168        }
13169
13170        synchronized (this) {
13171            final long now = SystemClock.uptimeMillis();
13172            final long timeSinceLastIdle = now - mLastIdleTime;
13173            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13174            mLastIdleTime = now;
13175            mLowRamTimeSinceLastIdle = 0;
13176            if (mLowRamStartTime != 0) {
13177                mLowRamStartTime = now;
13178            }
13179
13180            StringBuilder sb = new StringBuilder(128);
13181            sb.append("Idle maintenance over ");
13182            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13183            sb.append(" low RAM for ");
13184            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13185            Slog.i(TAG, sb.toString());
13186
13187            // If at least 1/3 of our time since the last idle period has been spent
13188            // with RAM low, then we want to kill processes.
13189            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13190
13191            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13192                ProcessRecord proc = mLruProcesses.get(i);
13193                if (proc.notCachedSinceIdle) {
13194                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13195                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13196                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13197                        if (doKilling && proc.initialIdlePss != 0
13198                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13199                            sb = new StringBuilder(128);
13200                            sb.append("Kill");
13201                            sb.append(proc.processName);
13202                            sb.append(" in idle maint: pss=");
13203                            sb.append(proc.lastPss);
13204                            sb.append(", swapPss=");
13205                            sb.append(proc.lastSwapPss);
13206                            sb.append(", initialPss=");
13207                            sb.append(proc.initialIdlePss);
13208                            sb.append(", period=");
13209                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13210                            sb.append(", lowRamPeriod=");
13211                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13212                            Slog.wtfQuiet(TAG, sb.toString());
13213                            proc.kill("idle maint (pss " + proc.lastPss
13214                                    + " from " + proc.initialIdlePss + ")", true);
13215                        }
13216                    }
13217                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13218                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13219                    proc.notCachedSinceIdle = true;
13220                    proc.initialIdlePss = 0;
13221                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13222                            mTestPssMode, isSleepingLocked(), now);
13223                }
13224            }
13225
13226            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13227            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13228        }
13229    }
13230
13231    @Override
13232    public void sendIdleJobTrigger() {
13233        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13234                != PackageManager.PERMISSION_GRANTED) {
13235            throw new SecurityException("Requires permission "
13236                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13237        }
13238
13239        final long ident = Binder.clearCallingIdentity();
13240        try {
13241            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13242                    .setPackage("android")
13243                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13244            broadcastIntent(null, intent, null, null, 0, null, null, null,
13245                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13246        } finally {
13247            Binder.restoreCallingIdentity(ident);
13248        }
13249    }
13250
13251    private void retrieveSettings() {
13252        final ContentResolver resolver = mContext.getContentResolver();
13253        final boolean freeformWindowManagement =
13254                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13255                        || Settings.Global.getInt(
13256                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13257        final boolean supportsPictureInPicture =
13258                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13259
13260        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13261        final boolean supportsSplitScreenMultiWindow =
13262                ActivityManager.supportsSplitScreenMultiWindow();
13263        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13264        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13265        final boolean alwaysFinishActivities =
13266                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13267        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13268        final boolean forceResizable = Settings.Global.getInt(
13269                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13270        final boolean supportsLeanbackOnly =
13271                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13272
13273        // Transfer any global setting for forcing RTL layout, into a System Property
13274        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13275
13276        final Configuration configuration = new Configuration();
13277        Settings.System.getConfiguration(resolver, configuration);
13278        if (forceRtl) {
13279            // This will take care of setting the correct layout direction flags
13280            configuration.setLayoutDirection(configuration.locale);
13281        }
13282
13283        synchronized (this) {
13284            mDebugApp = mOrigDebugApp = debugApp;
13285            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13286            mAlwaysFinishActivities = alwaysFinishActivities;
13287            mSupportsLeanbackOnly = supportsLeanbackOnly;
13288            mForceResizableActivities = forceResizable;
13289            if (supportsMultiWindow || forceResizable) {
13290                mSupportsMultiWindow = true;
13291                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13292                mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13293            } else {
13294                mSupportsMultiWindow = false;
13295                mSupportsFreeformWindowManagement = false;
13296                mSupportsPictureInPicture = false;
13297            }
13298            mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13299            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13300            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13301            // This happens before any activities are started, so we can change global configuration
13302            // in-place.
13303            updateConfigurationLocked(configuration, null, true);
13304            final Configuration globalConfig = getGlobalConfiguration();
13305            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13306
13307            // Load resources only after the current configuration has been set.
13308            final Resources res = mContext.getResources();
13309            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13310            mThumbnailWidth = res.getDimensionPixelSize(
13311                    com.android.internal.R.dimen.thumbnail_width);
13312            mThumbnailHeight = res.getDimensionPixelSize(
13313                    com.android.internal.R.dimen.thumbnail_height);
13314            mMinPipAspectRatio = res.getFloat(
13315                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
13316            mMaxPipAspectRatio = res.getFloat(
13317                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
13318            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13319                    com.android.internal.R.string.config_appsNotReportingCrashes));
13320            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13321                    com.android.internal.R.bool.config_customUserSwitchUi);
13322            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13323                mFullscreenThumbnailScale = (float) res
13324                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13325                    (float) globalConfig.screenWidthDp;
13326            } else {
13327                mFullscreenThumbnailScale = res.getFraction(
13328                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13329            }
13330        }
13331    }
13332
13333    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
13334        traceLog.traceBegin("PhaseActivityManagerReady");
13335        synchronized(this) {
13336            if (mSystemReady) {
13337                // If we're done calling all the receivers, run the next "boot phase" passed in
13338                // by the SystemServer
13339                if (goingCallback != null) {
13340                    goingCallback.run();
13341                }
13342                return;
13343            }
13344
13345            mLocalDeviceIdleController
13346                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13347
13348            // Make sure we have the current profile info, since it is needed for security checks.
13349            mUserController.onSystemReady();
13350            mRecentTasks.onSystemReadyLocked();
13351            mAppOpsService.systemReady();
13352            mSystemReady = true;
13353        }
13354
13355        ArrayList<ProcessRecord> procsToKill = null;
13356        synchronized(mPidsSelfLocked) {
13357            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13358                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13359                if (!isAllowedWhileBooting(proc.info)){
13360                    if (procsToKill == null) {
13361                        procsToKill = new ArrayList<ProcessRecord>();
13362                    }
13363                    procsToKill.add(proc);
13364                }
13365            }
13366        }
13367
13368        synchronized(this) {
13369            if (procsToKill != null) {
13370                for (int i=procsToKill.size()-1; i>=0; i--) {
13371                    ProcessRecord proc = procsToKill.get(i);
13372                    Slog.i(TAG, "Removing system update proc: " + proc);
13373                    removeProcessLocked(proc, true, false, "system update done");
13374                }
13375            }
13376
13377            // Now that we have cleaned up any update processes, we
13378            // are ready to start launching real processes and know that
13379            // we won't trample on them any more.
13380            mProcessesReady = true;
13381        }
13382
13383        Slog.i(TAG, "System now ready");
13384        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13385            SystemClock.uptimeMillis());
13386
13387        synchronized(this) {
13388            // Make sure we have no pre-ready processes sitting around.
13389
13390            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13391                ResolveInfo ri = mContext.getPackageManager()
13392                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13393                                STOCK_PM_FLAGS);
13394                CharSequence errorMsg = null;
13395                if (ri != null) {
13396                    ActivityInfo ai = ri.activityInfo;
13397                    ApplicationInfo app = ai.applicationInfo;
13398                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13399                        mTopAction = Intent.ACTION_FACTORY_TEST;
13400                        mTopData = null;
13401                        mTopComponent = new ComponentName(app.packageName,
13402                                ai.name);
13403                    } else {
13404                        errorMsg = mContext.getResources().getText(
13405                                com.android.internal.R.string.factorytest_not_system);
13406                    }
13407                } else {
13408                    errorMsg = mContext.getResources().getText(
13409                            com.android.internal.R.string.factorytest_no_action);
13410                }
13411                if (errorMsg != null) {
13412                    mTopAction = null;
13413                    mTopData = null;
13414                    mTopComponent = null;
13415                    Message msg = Message.obtain();
13416                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13417                    msg.getData().putCharSequence("msg", errorMsg);
13418                    mUiHandler.sendMessage(msg);
13419                }
13420            }
13421        }
13422
13423        retrieveSettings();
13424        final int currentUserId;
13425        synchronized (this) {
13426            currentUserId = mUserController.getCurrentUserIdLocked();
13427            readGrantedUriPermissionsLocked();
13428        }
13429
13430        if (goingCallback != null) goingCallback.run();
13431        traceLog.traceBegin("ActivityManagerStartApps");
13432        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13433                Integer.toString(currentUserId), currentUserId);
13434        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13435                Integer.toString(currentUserId), currentUserId);
13436        mSystemServiceManager.startUser(currentUserId);
13437
13438        synchronized (this) {
13439            // Only start up encryption-aware persistent apps; once user is
13440            // unlocked we'll come back around and start unaware apps
13441            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13442
13443            // Start up initial activity.
13444            mBooting = true;
13445            // Enable home activity for system user, so that the system can always boot. We don't
13446            // do this when the system user is not setup since the setup wizard should be the one
13447            // to handle home activity in this case.
13448            if (UserManager.isSplitSystemUser() &&
13449                    Settings.Secure.getInt(mContext.getContentResolver(),
13450                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
13451                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13452                try {
13453                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13454                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13455                            UserHandle.USER_SYSTEM);
13456                } catch (RemoteException e) {
13457                    throw e.rethrowAsRuntimeException();
13458                }
13459            }
13460            startHomeActivityLocked(currentUserId, "systemReady");
13461
13462            try {
13463                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13464                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13465                            + " data partition or your device will be unstable.");
13466                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13467                }
13468            } catch (RemoteException e) {
13469            }
13470
13471            if (!Build.isBuildConsistent()) {
13472                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13473                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13474            }
13475
13476            long ident = Binder.clearCallingIdentity();
13477            try {
13478                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13479                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13480                        | Intent.FLAG_RECEIVER_FOREGROUND);
13481                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13482                broadcastIntentLocked(null, null, intent,
13483                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13484                        null, false, false, MY_PID, Process.SYSTEM_UID,
13485                        currentUserId);
13486                intent = new Intent(Intent.ACTION_USER_STARTING);
13487                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13488                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13489                broadcastIntentLocked(null, null, intent,
13490                        null, new IIntentReceiver.Stub() {
13491                            @Override
13492                            public void performReceive(Intent intent, int resultCode, String data,
13493                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13494                                    throws RemoteException {
13495                            }
13496                        }, 0, null, null,
13497                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13498                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13499            } catch (Throwable t) {
13500                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13501            } finally {
13502                Binder.restoreCallingIdentity(ident);
13503            }
13504            mStackSupervisor.resumeFocusedStackTopActivityLocked();
13505            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13506            traceLog.traceEnd(); // ActivityManagerStartApps
13507            traceLog.traceEnd(); // PhaseActivityManagerReady
13508        }
13509    }
13510
13511    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13512        synchronized (this) {
13513            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13514        }
13515    }
13516
13517    void skipCurrentReceiverLocked(ProcessRecord app) {
13518        for (BroadcastQueue queue : mBroadcastQueues) {
13519            queue.skipCurrentReceiverLocked(app);
13520        }
13521    }
13522
13523    /**
13524     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13525     * The application process will exit immediately after this call returns.
13526     * @param app object of the crashing app, null for the system server
13527     * @param crashInfo describing the exception
13528     */
13529    public void handleApplicationCrash(IBinder app,
13530            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13531        ProcessRecord r = findAppProcess(app, "Crash");
13532        final String processName = app == null ? "system_server"
13533                : (r == null ? "unknown" : r.processName);
13534
13535        handleApplicationCrashInner("crash", r, processName, crashInfo);
13536    }
13537
13538    /* Native crash reporting uses this inner version because it needs to be somewhat
13539     * decoupled from the AM-managed cleanup lifecycle
13540     */
13541    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13542            ApplicationErrorReport.CrashInfo crashInfo) {
13543        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13544                UserHandle.getUserId(Binder.getCallingUid()), processName,
13545                r == null ? -1 : r.info.flags,
13546                crashInfo.exceptionClassName,
13547                crashInfo.exceptionMessage,
13548                crashInfo.throwFileName,
13549                crashInfo.throwLineNumber);
13550
13551        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13552
13553        mAppErrors.crashApplication(r, crashInfo);
13554    }
13555
13556    public void handleApplicationStrictModeViolation(
13557            IBinder app,
13558            int violationMask,
13559            StrictMode.ViolationInfo info) {
13560        ProcessRecord r = findAppProcess(app, "StrictMode");
13561        if (r == null) {
13562            return;
13563        }
13564
13565        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13566            Integer stackFingerprint = info.hashCode();
13567            boolean logIt = true;
13568            synchronized (mAlreadyLoggedViolatedStacks) {
13569                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13570                    logIt = false;
13571                    // TODO: sub-sample into EventLog for these, with
13572                    // the info.durationMillis?  Then we'd get
13573                    // the relative pain numbers, without logging all
13574                    // the stack traces repeatedly.  We'd want to do
13575                    // likewise in the client code, which also does
13576                    // dup suppression, before the Binder call.
13577                } else {
13578                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13579                        mAlreadyLoggedViolatedStacks.clear();
13580                    }
13581                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13582                }
13583            }
13584            if (logIt) {
13585                logStrictModeViolationToDropBox(r, info);
13586            }
13587        }
13588
13589        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13590            AppErrorResult result = new AppErrorResult();
13591            synchronized (this) {
13592                final long origId = Binder.clearCallingIdentity();
13593
13594                Message msg = Message.obtain();
13595                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13596                HashMap<String, Object> data = new HashMap<String, Object>();
13597                data.put("result", result);
13598                data.put("app", r);
13599                data.put("violationMask", violationMask);
13600                data.put("info", info);
13601                msg.obj = data;
13602                mUiHandler.sendMessage(msg);
13603
13604                Binder.restoreCallingIdentity(origId);
13605            }
13606            int res = result.get();
13607            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13608        }
13609    }
13610
13611    // Depending on the policy in effect, there could be a bunch of
13612    // these in quick succession so we try to batch these together to
13613    // minimize disk writes, number of dropbox entries, and maximize
13614    // compression, by having more fewer, larger records.
13615    private void logStrictModeViolationToDropBox(
13616            ProcessRecord process,
13617            StrictMode.ViolationInfo info) {
13618        if (info == null) {
13619            return;
13620        }
13621        final boolean isSystemApp = process == null ||
13622                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13623                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13624        final String processName = process == null ? "unknown" : process.processName;
13625        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13626        final DropBoxManager dbox = (DropBoxManager)
13627                mContext.getSystemService(Context.DROPBOX_SERVICE);
13628
13629        // Exit early if the dropbox isn't configured to accept this report type.
13630        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13631
13632        boolean bufferWasEmpty;
13633        boolean needsFlush;
13634        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13635        synchronized (sb) {
13636            bufferWasEmpty = sb.length() == 0;
13637            appendDropBoxProcessHeaders(process, processName, sb);
13638            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13639            sb.append("System-App: ").append(isSystemApp).append("\n");
13640            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13641            if (info.violationNumThisLoop != 0) {
13642                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13643            }
13644            if (info.numAnimationsRunning != 0) {
13645                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13646            }
13647            if (info.broadcastIntentAction != null) {
13648                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13649            }
13650            if (info.durationMillis != -1) {
13651                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13652            }
13653            if (info.numInstances != -1) {
13654                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13655            }
13656            if (info.tags != null) {
13657                for (String tag : info.tags) {
13658                    sb.append("Span-Tag: ").append(tag).append("\n");
13659                }
13660            }
13661            sb.append("\n");
13662            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13663                sb.append(info.crashInfo.stackTrace);
13664                sb.append("\n");
13665            }
13666            if (info.message != null) {
13667                sb.append(info.message);
13668                sb.append("\n");
13669            }
13670
13671            // Only buffer up to ~64k.  Various logging bits truncate
13672            // things at 128k.
13673            needsFlush = (sb.length() > 64 * 1024);
13674        }
13675
13676        // Flush immediately if the buffer's grown too large, or this
13677        // is a non-system app.  Non-system apps are isolated with a
13678        // different tag & policy and not batched.
13679        //
13680        // Batching is useful during internal testing with
13681        // StrictMode settings turned up high.  Without batching,
13682        // thousands of separate files could be created on boot.
13683        if (!isSystemApp || needsFlush) {
13684            new Thread("Error dump: " + dropboxTag) {
13685                @Override
13686                public void run() {
13687                    String report;
13688                    synchronized (sb) {
13689                        report = sb.toString();
13690                        sb.delete(0, sb.length());
13691                        sb.trimToSize();
13692                    }
13693                    if (report.length() != 0) {
13694                        dbox.addText(dropboxTag, report);
13695                    }
13696                }
13697            }.start();
13698            return;
13699        }
13700
13701        // System app batching:
13702        if (!bufferWasEmpty) {
13703            // An existing dropbox-writing thread is outstanding, so
13704            // we don't need to start it up.  The existing thread will
13705            // catch the buffer appends we just did.
13706            return;
13707        }
13708
13709        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13710        // (After this point, we shouldn't access AMS internal data structures.)
13711        new Thread("Error dump: " + dropboxTag) {
13712            @Override
13713            public void run() {
13714                // 5 second sleep to let stacks arrive and be batched together
13715                try {
13716                    Thread.sleep(5000);  // 5 seconds
13717                } catch (InterruptedException e) {}
13718
13719                String errorReport;
13720                synchronized (mStrictModeBuffer) {
13721                    errorReport = mStrictModeBuffer.toString();
13722                    if (errorReport.length() == 0) {
13723                        return;
13724                    }
13725                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13726                    mStrictModeBuffer.trimToSize();
13727                }
13728                dbox.addText(dropboxTag, errorReport);
13729            }
13730        }.start();
13731    }
13732
13733    /**
13734     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13735     * @param app object of the crashing app, null for the system server
13736     * @param tag reported by the caller
13737     * @param system whether this wtf is coming from the system
13738     * @param crashInfo describing the context of the error
13739     * @return true if the process should exit immediately (WTF is fatal)
13740     */
13741    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13742            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
13743        final int callingUid = Binder.getCallingUid();
13744        final int callingPid = Binder.getCallingPid();
13745
13746        if (system) {
13747            // If this is coming from the system, we could very well have low-level
13748            // system locks held, so we want to do this all asynchronously.  And we
13749            // never want this to become fatal, so there is that too.
13750            mHandler.post(new Runnable() {
13751                @Override public void run() {
13752                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13753                }
13754            });
13755            return false;
13756        }
13757
13758        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13759                crashInfo);
13760
13761        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
13762                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
13763        final boolean isSystem = (r == null) || r.persistent;
13764
13765        if (isFatal && !isSystem) {
13766            mAppErrors.crashApplication(r, crashInfo);
13767            return true;
13768        } else {
13769            return false;
13770        }
13771    }
13772
13773    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13774            final ApplicationErrorReport.CrashInfo crashInfo) {
13775        final ProcessRecord r = findAppProcess(app, "WTF");
13776        final String processName = app == null ? "system_server"
13777                : (r == null ? "unknown" : r.processName);
13778
13779        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13780                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13781
13782        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13783
13784        return r;
13785    }
13786
13787    /**
13788     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13789     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13790     */
13791    private ProcessRecord findAppProcess(IBinder app, String reason) {
13792        if (app == null) {
13793            return null;
13794        }
13795
13796        synchronized (this) {
13797            final int NP = mProcessNames.getMap().size();
13798            for (int ip=0; ip<NP; ip++) {
13799                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13800                final int NA = apps.size();
13801                for (int ia=0; ia<NA; ia++) {
13802                    ProcessRecord p = apps.valueAt(ia);
13803                    if (p.thread != null && p.thread.asBinder() == app) {
13804                        return p;
13805                    }
13806                }
13807            }
13808
13809            Slog.w(TAG, "Can't find mystery application for " + reason
13810                    + " from pid=" + Binder.getCallingPid()
13811                    + " uid=" + Binder.getCallingUid() + ": " + app);
13812            return null;
13813        }
13814    }
13815
13816    /**
13817     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13818     * to append various headers to the dropbox log text.
13819     */
13820    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13821            StringBuilder sb) {
13822        // Watchdog thread ends up invoking this function (with
13823        // a null ProcessRecord) to add the stack file to dropbox.
13824        // Do not acquire a lock on this (am) in such cases, as it
13825        // could cause a potential deadlock, if and when watchdog
13826        // is invoked due to unavailability of lock on am and it
13827        // would prevent watchdog from killing system_server.
13828        if (process == null) {
13829            sb.append("Process: ").append(processName).append("\n");
13830            return;
13831        }
13832        // Note: ProcessRecord 'process' is guarded by the service
13833        // instance.  (notably process.pkgList, which could otherwise change
13834        // concurrently during execution of this method)
13835        synchronized (this) {
13836            sb.append("Process: ").append(processName).append("\n");
13837            int flags = process.info.flags;
13838            IPackageManager pm = AppGlobals.getPackageManager();
13839            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13840            for (int ip=0; ip<process.pkgList.size(); ip++) {
13841                String pkg = process.pkgList.keyAt(ip);
13842                sb.append("Package: ").append(pkg);
13843                try {
13844                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13845                    if (pi != null) {
13846                        sb.append(" v").append(pi.versionCode);
13847                        if (pi.versionName != null) {
13848                            sb.append(" (").append(pi.versionName).append(")");
13849                        }
13850                    }
13851                } catch (RemoteException e) {
13852                    Slog.e(TAG, "Error getting package info: " + pkg, e);
13853                }
13854                sb.append("\n");
13855            }
13856        }
13857    }
13858
13859    private static String processClass(ProcessRecord process) {
13860        if (process == null || process.pid == MY_PID) {
13861            return "system_server";
13862        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13863            return "system_app";
13864        } else {
13865            return "data_app";
13866        }
13867    }
13868
13869    private volatile long mWtfClusterStart;
13870    private volatile int mWtfClusterCount;
13871
13872    /**
13873     * Write a description of an error (crash, WTF, ANR) to the drop box.
13874     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13875     * @param process which caused the error, null means the system server
13876     * @param activity which triggered the error, null if unknown
13877     * @param parent activity related to the error, null if unknown
13878     * @param subject line related to the error, null if absent
13879     * @param report in long form describing the error, null if absent
13880     * @param dataFile text file to include in the report, null if none
13881     * @param crashInfo giving an application stack trace, null if absent
13882     */
13883    public void addErrorToDropBox(String eventType,
13884            ProcessRecord process, String processName, ActivityRecord activity,
13885            ActivityRecord parent, String subject,
13886            final String report, final File dataFile,
13887            final ApplicationErrorReport.CrashInfo crashInfo) {
13888        // NOTE -- this must never acquire the ActivityManagerService lock,
13889        // otherwise the watchdog may be prevented from resetting the system.
13890
13891        // Bail early if not published yet
13892        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
13893        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
13894
13895        // Exit early if the dropbox isn't configured to accept this report type.
13896        final String dropboxTag = processClass(process) + "_" + eventType;
13897        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13898
13899        // Rate-limit how often we're willing to do the heavy lifting below to
13900        // collect and record logs; currently 5 logs per 10 second period.
13901        final long now = SystemClock.elapsedRealtime();
13902        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13903            mWtfClusterStart = now;
13904            mWtfClusterCount = 1;
13905        } else {
13906            if (mWtfClusterCount++ >= 5) return;
13907        }
13908
13909        final StringBuilder sb = new StringBuilder(1024);
13910        appendDropBoxProcessHeaders(process, processName, sb);
13911        if (process != null) {
13912            sb.append("Foreground: ")
13913                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13914                    .append("\n");
13915        }
13916        if (activity != null) {
13917            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13918        }
13919        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13920            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13921        }
13922        if (parent != null && parent != activity) {
13923            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13924        }
13925        if (subject != null) {
13926            sb.append("Subject: ").append(subject).append("\n");
13927        }
13928        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13929        if (Debug.isDebuggerConnected()) {
13930            sb.append("Debugger: Connected\n");
13931        }
13932        sb.append("\n");
13933
13934        // Do the rest in a worker thread to avoid blocking the caller on I/O
13935        // (After this point, we shouldn't access AMS internal data structures.)
13936        Thread worker = new Thread("Error dump: " + dropboxTag) {
13937            @Override
13938            public void run() {
13939                if (report != null) {
13940                    sb.append(report);
13941                }
13942
13943                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13944                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13945                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13946                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13947
13948                if (dataFile != null && maxDataFileSize > 0) {
13949                    try {
13950                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13951                                    "\n\n[[TRUNCATED]]"));
13952                    } catch (IOException e) {
13953                        Slog.e(TAG, "Error reading " + dataFile, e);
13954                    }
13955                }
13956                if (crashInfo != null && crashInfo.stackTrace != null) {
13957                    sb.append(crashInfo.stackTrace);
13958                }
13959
13960                if (lines > 0) {
13961                    sb.append("\n");
13962
13963                    // Merge several logcat streams, and take the last N lines
13964                    InputStreamReader input = null;
13965                    try {
13966                        java.lang.Process logcat = new ProcessBuilder(
13967                                "/system/bin/timeout", "-k", "15s", "10s",
13968                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13969                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13970                                        .redirectErrorStream(true).start();
13971
13972                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
13973                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
13974                        input = new InputStreamReader(logcat.getInputStream());
13975
13976                        int num;
13977                        char[] buf = new char[8192];
13978                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13979                    } catch (IOException e) {
13980                        Slog.e(TAG, "Error running logcat", e);
13981                    } finally {
13982                        if (input != null) try { input.close(); } catch (IOException e) {}
13983                    }
13984                }
13985
13986                dbox.addText(dropboxTag, sb.toString());
13987            }
13988        };
13989
13990        if (process == null) {
13991            // If process is null, we are being called from some internal code
13992            // and may be about to die -- run this synchronously.
13993            worker.run();
13994        } else {
13995            worker.start();
13996        }
13997    }
13998
13999    @Override
14000    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14001        enforceNotIsolatedCaller("getProcessesInErrorState");
14002        // assume our apps are happy - lazy create the list
14003        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14004
14005        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14006                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14007        int userId = UserHandle.getUserId(Binder.getCallingUid());
14008
14009        synchronized (this) {
14010
14011            // iterate across all processes
14012            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14013                ProcessRecord app = mLruProcesses.get(i);
14014                if (!allUsers && app.userId != userId) {
14015                    continue;
14016                }
14017                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14018                    // This one's in trouble, so we'll generate a report for it
14019                    // crashes are higher priority (in case there's a crash *and* an anr)
14020                    ActivityManager.ProcessErrorStateInfo report = null;
14021                    if (app.crashing) {
14022                        report = app.crashingReport;
14023                    } else if (app.notResponding) {
14024                        report = app.notRespondingReport;
14025                    }
14026
14027                    if (report != null) {
14028                        if (errList == null) {
14029                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14030                        }
14031                        errList.add(report);
14032                    } else {
14033                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14034                                " crashing = " + app.crashing +
14035                                " notResponding = " + app.notResponding);
14036                    }
14037                }
14038            }
14039        }
14040
14041        return errList;
14042    }
14043
14044    static int procStateToImportance(int procState, int memAdj,
14045            ActivityManager.RunningAppProcessInfo currApp) {
14046        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
14047        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14048            currApp.lru = memAdj;
14049        } else {
14050            currApp.lru = 0;
14051        }
14052        return imp;
14053    }
14054
14055    private void fillInProcMemInfo(ProcessRecord app,
14056            ActivityManager.RunningAppProcessInfo outInfo) {
14057        outInfo.pid = app.pid;
14058        outInfo.uid = app.info.uid;
14059        if (mHeavyWeightProcess == app) {
14060            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14061        }
14062        if (app.persistent) {
14063            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14064        }
14065        if (app.activities.size() > 0) {
14066            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14067        }
14068        outInfo.lastTrimLevel = app.trimMemoryLevel;
14069        int adj = app.curAdj;
14070        int procState = app.curProcState;
14071        outInfo.importance = procStateToImportance(procState, adj, outInfo);
14072        outInfo.importanceReasonCode = app.adjTypeCode;
14073        outInfo.processState = app.curProcState;
14074    }
14075
14076    @Override
14077    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14078        enforceNotIsolatedCaller("getRunningAppProcesses");
14079
14080        final int callingUid = Binder.getCallingUid();
14081
14082        // Lazy instantiation of list
14083        List<ActivityManager.RunningAppProcessInfo> runList = null;
14084        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14085                callingUid) == PackageManager.PERMISSION_GRANTED;
14086        final int userId = UserHandle.getUserId(callingUid);
14087        final boolean allUids = isGetTasksAllowed(
14088                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14089
14090        synchronized (this) {
14091            // Iterate across all processes
14092            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14093                ProcessRecord app = mLruProcesses.get(i);
14094                if ((!allUsers && app.userId != userId)
14095                        || (!allUids && app.uid != callingUid)) {
14096                    continue;
14097                }
14098                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14099                    // Generate process state info for running application
14100                    ActivityManager.RunningAppProcessInfo currApp =
14101                        new ActivityManager.RunningAppProcessInfo(app.processName,
14102                                app.pid, app.getPackageList());
14103                    fillInProcMemInfo(app, currApp);
14104                    if (app.adjSource instanceof ProcessRecord) {
14105                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14106                        currApp.importanceReasonImportance =
14107                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14108                                        app.adjSourceProcState);
14109                    } else if (app.adjSource instanceof ActivityRecord) {
14110                        ActivityRecord r = (ActivityRecord)app.adjSource;
14111                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14112                    }
14113                    if (app.adjTarget instanceof ComponentName) {
14114                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14115                    }
14116                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14117                    //        + " lru=" + currApp.lru);
14118                    if (runList == null) {
14119                        runList = new ArrayList<>();
14120                    }
14121                    runList.add(currApp);
14122                }
14123            }
14124        }
14125        return runList;
14126    }
14127
14128    @Override
14129    public List<ApplicationInfo> getRunningExternalApplications() {
14130        enforceNotIsolatedCaller("getRunningExternalApplications");
14131        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14132        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14133        if (runningApps != null && runningApps.size() > 0) {
14134            Set<String> extList = new HashSet<String>();
14135            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14136                if (app.pkgList != null) {
14137                    for (String pkg : app.pkgList) {
14138                        extList.add(pkg);
14139                    }
14140                }
14141            }
14142            IPackageManager pm = AppGlobals.getPackageManager();
14143            for (String pkg : extList) {
14144                try {
14145                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14146                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14147                        retList.add(info);
14148                    }
14149                } catch (RemoteException e) {
14150                }
14151            }
14152        }
14153        return retList;
14154    }
14155
14156    @Override
14157    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14158        enforceNotIsolatedCaller("getMyMemoryState");
14159        synchronized (this) {
14160            ProcessRecord proc;
14161            synchronized (mPidsSelfLocked) {
14162                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14163            }
14164            fillInProcMemInfo(proc, outInfo);
14165        }
14166    }
14167
14168    @Override
14169    public int getMemoryTrimLevel() {
14170        enforceNotIsolatedCaller("getMyMemoryState");
14171        synchronized (this) {
14172            return mLastMemoryLevel;
14173        }
14174    }
14175
14176    @Override
14177    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14178            FileDescriptor err, String[] args, ShellCallback callback,
14179            ResultReceiver resultReceiver) {
14180        (new ActivityManagerShellCommand(this, false)).exec(
14181                this, in, out, err, args, callback, resultReceiver);
14182    }
14183
14184    @Override
14185    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14186        if (checkCallingPermission(android.Manifest.permission.DUMP)
14187                != PackageManager.PERMISSION_GRANTED) {
14188            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14189                    + Binder.getCallingPid()
14190                    + ", uid=" + Binder.getCallingUid()
14191                    + " without permission "
14192                    + android.Manifest.permission.DUMP);
14193            return;
14194        }
14195
14196        boolean dumpAll = false;
14197        boolean dumpClient = false;
14198        boolean dumpCheckin = false;
14199        boolean dumpCheckinFormat = false;
14200        boolean dumpVisibleStacks = false;
14201        String dumpPackage = null;
14202
14203        int opti = 0;
14204        while (opti < args.length) {
14205            String opt = args[opti];
14206            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14207                break;
14208            }
14209            opti++;
14210            if ("-a".equals(opt)) {
14211                dumpAll = true;
14212            } else if ("-c".equals(opt)) {
14213                dumpClient = true;
14214            } else if ("-v".equals(opt)) {
14215                dumpVisibleStacks = true;
14216            } else if ("-p".equals(opt)) {
14217                if (opti < args.length) {
14218                    dumpPackage = args[opti];
14219                    opti++;
14220                } else {
14221                    pw.println("Error: -p option requires package argument");
14222                    return;
14223                }
14224                dumpClient = true;
14225            } else if ("--checkin".equals(opt)) {
14226                dumpCheckin = dumpCheckinFormat = true;
14227            } else if ("-C".equals(opt)) {
14228                dumpCheckinFormat = true;
14229            } else if ("-h".equals(opt)) {
14230                ActivityManagerShellCommand.dumpHelp(pw, true);
14231                return;
14232            } else {
14233                pw.println("Unknown argument: " + opt + "; use -h for help");
14234            }
14235        }
14236
14237        long origId = Binder.clearCallingIdentity();
14238        boolean more = false;
14239        // Is the caller requesting to dump a particular piece of data?
14240        if (opti < args.length) {
14241            String cmd = args[opti];
14242            opti++;
14243            if ("activities".equals(cmd) || "a".equals(cmd)) {
14244                synchronized (this) {
14245                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14246                }
14247            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14248                synchronized (this) {
14249                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14250                }
14251            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14252                String[] newArgs;
14253                String name;
14254                if (opti >= args.length) {
14255                    name = null;
14256                    newArgs = EMPTY_STRING_ARRAY;
14257                } else {
14258                    dumpPackage = args[opti];
14259                    opti++;
14260                    newArgs = new String[args.length - opti];
14261                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14262                            args.length - opti);
14263                }
14264                synchronized (this) {
14265                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14266                }
14267            } else if ("broadcast-stats".equals(cmd)) {
14268                String[] newArgs;
14269                String name;
14270                if (opti >= args.length) {
14271                    name = null;
14272                    newArgs = EMPTY_STRING_ARRAY;
14273                } else {
14274                    dumpPackage = args[opti];
14275                    opti++;
14276                    newArgs = new String[args.length - opti];
14277                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14278                            args.length - opti);
14279                }
14280                synchronized (this) {
14281                    if (dumpCheckinFormat) {
14282                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14283                                dumpPackage);
14284                    } else {
14285                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14286                    }
14287                }
14288            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14289                String[] newArgs;
14290                String name;
14291                if (opti >= args.length) {
14292                    name = null;
14293                    newArgs = EMPTY_STRING_ARRAY;
14294                } else {
14295                    dumpPackage = args[opti];
14296                    opti++;
14297                    newArgs = new String[args.length - opti];
14298                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14299                            args.length - opti);
14300                }
14301                synchronized (this) {
14302                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14303                }
14304            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14305                String[] newArgs;
14306                String name;
14307                if (opti >= args.length) {
14308                    name = null;
14309                    newArgs = EMPTY_STRING_ARRAY;
14310                } else {
14311                    dumpPackage = args[opti];
14312                    opti++;
14313                    newArgs = new String[args.length - opti];
14314                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14315                            args.length - opti);
14316                }
14317                synchronized (this) {
14318                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14319                }
14320            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14321                synchronized (this) {
14322                    dumpOomLocked(fd, pw, args, opti, true);
14323                }
14324            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14325                synchronized (this) {
14326                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14327                }
14328            } else if ("provider".equals(cmd)) {
14329                String[] newArgs;
14330                String name;
14331                if (opti >= args.length) {
14332                    name = null;
14333                    newArgs = EMPTY_STRING_ARRAY;
14334                } else {
14335                    name = args[opti];
14336                    opti++;
14337                    newArgs = new String[args.length - opti];
14338                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14339                }
14340                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14341                    pw.println("No providers match: " + name);
14342                    pw.println("Use -h for help.");
14343                }
14344            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14345                synchronized (this) {
14346                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14347                }
14348            } else if ("service".equals(cmd)) {
14349                String[] newArgs;
14350                String name;
14351                if (opti >= args.length) {
14352                    name = null;
14353                    newArgs = EMPTY_STRING_ARRAY;
14354                } else {
14355                    name = args[opti];
14356                    opti++;
14357                    newArgs = new String[args.length - opti];
14358                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14359                            args.length - opti);
14360                }
14361                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14362                    pw.println("No services match: " + name);
14363                    pw.println("Use -h for help.");
14364                }
14365            } else if ("package".equals(cmd)) {
14366                String[] newArgs;
14367                if (opti >= args.length) {
14368                    pw.println("package: no package name specified");
14369                    pw.println("Use -h for help.");
14370                } else {
14371                    dumpPackage = args[opti];
14372                    opti++;
14373                    newArgs = new String[args.length - opti];
14374                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14375                            args.length - opti);
14376                    args = newArgs;
14377                    opti = 0;
14378                    more = true;
14379                }
14380            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14381                synchronized (this) {
14382                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14383                }
14384            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14385                if (dumpClient) {
14386                    ActiveServices.ServiceDumper dumper;
14387                    synchronized (this) {
14388                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14389                                dumpPackage);
14390                    }
14391                    dumper.dumpWithClient();
14392                } else {
14393                    synchronized (this) {
14394                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14395                                dumpPackage).dumpLocked();
14396                    }
14397                }
14398            } else if ("locks".equals(cmd)) {
14399                LockGuard.dump(fd, pw, args);
14400            } else {
14401                // Dumping a single activity?
14402                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacks)) {
14403                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14404                    int res = shell.exec(this, null, fd, null, args, null,
14405                            new ResultReceiver(null));
14406                    if (res < 0) {
14407                        pw.println("Bad activity command, or no activities match: " + cmd);
14408                        pw.println("Use -h for help.");
14409                    }
14410                }
14411            }
14412            if (!more) {
14413                Binder.restoreCallingIdentity(origId);
14414                return;
14415            }
14416        }
14417
14418        // No piece of data specified, dump everything.
14419        if (dumpCheckinFormat) {
14420            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14421        } else if (dumpClient) {
14422            ActiveServices.ServiceDumper sdumper;
14423            synchronized (this) {
14424                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14425                pw.println();
14426                if (dumpAll) {
14427                    pw.println("-------------------------------------------------------------------------------");
14428                }
14429                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14430                pw.println();
14431                if (dumpAll) {
14432                    pw.println("-------------------------------------------------------------------------------");
14433                }
14434                if (dumpAll || dumpPackage != null) {
14435                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14436                    pw.println();
14437                    if (dumpAll) {
14438                        pw.println("-------------------------------------------------------------------------------");
14439                    }
14440                }
14441                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14442                pw.println();
14443                if (dumpAll) {
14444                    pw.println("-------------------------------------------------------------------------------");
14445                }
14446                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14447                pw.println();
14448                if (dumpAll) {
14449                    pw.println("-------------------------------------------------------------------------------");
14450                }
14451                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14452                        dumpPackage);
14453            }
14454            sdumper.dumpWithClient();
14455            pw.println();
14456            synchronized (this) {
14457                if (dumpAll) {
14458                    pw.println("-------------------------------------------------------------------------------");
14459                }
14460                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14461                pw.println();
14462                if (dumpAll) {
14463                    pw.println("-------------------------------------------------------------------------------");
14464                }
14465                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14466                if (mAssociations.size() > 0) {
14467                    pw.println();
14468                    if (dumpAll) {
14469                        pw.println("-------------------------------------------------------------------------------");
14470                    }
14471                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14472                }
14473                pw.println();
14474                if (dumpAll) {
14475                    pw.println("-------------------------------------------------------------------------------");
14476                }
14477                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14478            }
14479
14480        } else {
14481            synchronized (this) {
14482                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14483                pw.println();
14484                if (dumpAll) {
14485                    pw.println("-------------------------------------------------------------------------------");
14486                }
14487                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14488                pw.println();
14489                if (dumpAll) {
14490                    pw.println("-------------------------------------------------------------------------------");
14491                }
14492                if (dumpAll || dumpPackage != null) {
14493                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14494                    pw.println();
14495                    if (dumpAll) {
14496                        pw.println("-------------------------------------------------------------------------------");
14497                    }
14498                }
14499                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14500                pw.println();
14501                if (dumpAll) {
14502                    pw.println("-------------------------------------------------------------------------------");
14503                }
14504                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14505                pw.println();
14506                if (dumpAll) {
14507                    pw.println("-------------------------------------------------------------------------------");
14508                }
14509                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14510                        .dumpLocked();
14511                pw.println();
14512                if (dumpAll) {
14513                    pw.println("-------------------------------------------------------------------------------");
14514                }
14515                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14516                pw.println();
14517                if (dumpAll) {
14518                    pw.println("-------------------------------------------------------------------------------");
14519                }
14520                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14521                if (mAssociations.size() > 0) {
14522                    pw.println();
14523                    if (dumpAll) {
14524                        pw.println("-------------------------------------------------------------------------------");
14525                    }
14526                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14527                }
14528                pw.println();
14529                if (dumpAll) {
14530                    pw.println("-------------------------------------------------------------------------------");
14531                }
14532                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14533            }
14534        }
14535        Binder.restoreCallingIdentity(origId);
14536    }
14537
14538    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14539            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14540        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14541
14542        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14543                dumpPackage);
14544        boolean needSep = printedAnything;
14545
14546        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
14547                mStackSupervisor.getResumedActivityLocked(),
14548                dumpPackage, needSep, "  ResumedActivity: ");
14549        if (printed) {
14550            printedAnything = true;
14551            needSep = false;
14552        }
14553
14554        if (dumpPackage == null) {
14555            if (needSep) {
14556                pw.println();
14557            }
14558            needSep = true;
14559            printedAnything = true;
14560            mStackSupervisor.dump(pw, "  ");
14561        }
14562
14563        if (!printedAnything) {
14564            pw.println("  (nothing)");
14565        }
14566    }
14567
14568    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14569            int opti, boolean dumpAll, String dumpPackage) {
14570        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14571
14572        boolean printedAnything = false;
14573
14574        if (mRecentTasks != null && mRecentTasks.size() > 0) {
14575            boolean printedHeader = false;
14576
14577            final int N = mRecentTasks.size();
14578            for (int i=0; i<N; i++) {
14579                TaskRecord tr = mRecentTasks.get(i);
14580                if (dumpPackage != null) {
14581                    if (tr.realActivity == null ||
14582                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
14583                        continue;
14584                    }
14585                }
14586                if (!printedHeader) {
14587                    pw.println("  Recent tasks:");
14588                    printedHeader = true;
14589                    printedAnything = true;
14590                }
14591                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14592                        pw.println(tr);
14593                if (dumpAll) {
14594                    mRecentTasks.get(i).dump(pw, "    ");
14595                }
14596            }
14597        }
14598
14599        if (!printedAnything) {
14600            pw.println("  (nothing)");
14601        }
14602    }
14603
14604    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14605            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14606        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14607
14608        int dumpUid = 0;
14609        if (dumpPackage != null) {
14610            IPackageManager pm = AppGlobals.getPackageManager();
14611            try {
14612                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
14613            } catch (RemoteException e) {
14614            }
14615        }
14616
14617        boolean printedAnything = false;
14618
14619        final long now = SystemClock.uptimeMillis();
14620
14621        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14622            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14623                    = mAssociations.valueAt(i1);
14624            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14625                SparseArray<ArrayMap<String, Association>> sourceUids
14626                        = targetComponents.valueAt(i2);
14627                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14628                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14629                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14630                        Association ass = sourceProcesses.valueAt(i4);
14631                        if (dumpPackage != null) {
14632                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14633                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14634                                continue;
14635                            }
14636                        }
14637                        printedAnything = true;
14638                        pw.print("  ");
14639                        pw.print(ass.mTargetProcess);
14640                        pw.print("/");
14641                        UserHandle.formatUid(pw, ass.mTargetUid);
14642                        pw.print(" <- ");
14643                        pw.print(ass.mSourceProcess);
14644                        pw.print("/");
14645                        UserHandle.formatUid(pw, ass.mSourceUid);
14646                        pw.println();
14647                        pw.print("    via ");
14648                        pw.print(ass.mTargetComponent.flattenToShortString());
14649                        pw.println();
14650                        pw.print("    ");
14651                        long dur = ass.mTime;
14652                        if (ass.mNesting > 0) {
14653                            dur += now - ass.mStartTime;
14654                        }
14655                        TimeUtils.formatDuration(dur, pw);
14656                        pw.print(" (");
14657                        pw.print(ass.mCount);
14658                        pw.print(" times)");
14659                        pw.print("  ");
14660                        for (int i=0; i<ass.mStateTimes.length; i++) {
14661                            long amt = ass.mStateTimes[i];
14662                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14663                                amt += now - ass.mLastStateUptime;
14664                            }
14665                            if (amt != 0) {
14666                                pw.print(" ");
14667                                pw.print(ProcessList.makeProcStateString(
14668                                            i + ActivityManager.MIN_PROCESS_STATE));
14669                                pw.print("=");
14670                                TimeUtils.formatDuration(amt, pw);
14671                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
14672                                    pw.print("*");
14673                                }
14674                            }
14675                        }
14676                        pw.println();
14677                        if (ass.mNesting > 0) {
14678                            pw.print("    Currently active: ");
14679                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
14680                            pw.println();
14681                        }
14682                    }
14683                }
14684            }
14685
14686        }
14687
14688        if (!printedAnything) {
14689            pw.println("  (nothing)");
14690        }
14691    }
14692
14693    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14694            String header, boolean needSep) {
14695        boolean printed = false;
14696        int whichAppId = -1;
14697        if (dumpPackage != null) {
14698            try {
14699                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14700                        dumpPackage, 0);
14701                whichAppId = UserHandle.getAppId(info.uid);
14702            } catch (NameNotFoundException e) {
14703                e.printStackTrace();
14704            }
14705        }
14706        for (int i=0; i<uids.size(); i++) {
14707            UidRecord uidRec = uids.valueAt(i);
14708            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14709                continue;
14710            }
14711            if (!printed) {
14712                printed = true;
14713                if (needSep) {
14714                    pw.println();
14715                }
14716                pw.print("  ");
14717                pw.println(header);
14718                needSep = true;
14719            }
14720            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14721            pw.print(": "); pw.println(uidRec);
14722        }
14723        return printed;
14724    }
14725
14726    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14727            int opti, boolean dumpAll, String dumpPackage) {
14728        boolean needSep = false;
14729        boolean printedAnything = false;
14730        int numPers = 0;
14731
14732        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14733
14734        if (dumpAll) {
14735            final int NP = mProcessNames.getMap().size();
14736            for (int ip=0; ip<NP; ip++) {
14737                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14738                final int NA = procs.size();
14739                for (int ia=0; ia<NA; ia++) {
14740                    ProcessRecord r = procs.valueAt(ia);
14741                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14742                        continue;
14743                    }
14744                    if (!needSep) {
14745                        pw.println("  All known processes:");
14746                        needSep = true;
14747                        printedAnything = true;
14748                    }
14749                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14750                        pw.print(" UID "); pw.print(procs.keyAt(ia));
14751                        pw.print(" "); pw.println(r);
14752                    r.dump(pw, "    ");
14753                    if (r.persistent) {
14754                        numPers++;
14755                    }
14756                }
14757            }
14758        }
14759
14760        if (mIsolatedProcesses.size() > 0) {
14761            boolean printed = false;
14762            for (int i=0; i<mIsolatedProcesses.size(); i++) {
14763                ProcessRecord r = mIsolatedProcesses.valueAt(i);
14764                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14765                    continue;
14766                }
14767                if (!printed) {
14768                    if (needSep) {
14769                        pw.println();
14770                    }
14771                    pw.println("  Isolated process list (sorted by uid):");
14772                    printedAnything = true;
14773                    printed = true;
14774                    needSep = true;
14775                }
14776                pw.println(String.format("%sIsolated #%2d: %s",
14777                        "    ", i, r.toString()));
14778            }
14779        }
14780
14781        if (mActiveUids.size() > 0) {
14782            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14783                printedAnything = needSep = true;
14784            }
14785        }
14786        if (mValidateUids.size() > 0) {
14787            if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14788                printedAnything = needSep = true;
14789            }
14790        }
14791
14792        if (mLruProcesses.size() > 0) {
14793            if (needSep) {
14794                pw.println();
14795            }
14796            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14797                    pw.print(" total, non-act at ");
14798                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14799                    pw.print(", non-svc at ");
14800                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14801                    pw.println("):");
14802            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14803            needSep = true;
14804            printedAnything = true;
14805        }
14806
14807        if (dumpAll || dumpPackage != null) {
14808            synchronized (mPidsSelfLocked) {
14809                boolean printed = false;
14810                for (int i=0; i<mPidsSelfLocked.size(); i++) {
14811                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
14812                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14813                        continue;
14814                    }
14815                    if (!printed) {
14816                        if (needSep) pw.println();
14817                        needSep = true;
14818                        pw.println("  PID mappings:");
14819                        printed = true;
14820                        printedAnything = true;
14821                    }
14822                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14823                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14824                }
14825            }
14826        }
14827
14828        if (mForegroundProcesses.size() > 0) {
14829            synchronized (mPidsSelfLocked) {
14830                boolean printed = false;
14831                for (int i=0; i<mForegroundProcesses.size(); i++) {
14832                    ProcessRecord r = mPidsSelfLocked.get(
14833                            mForegroundProcesses.valueAt(i).pid);
14834                    if (dumpPackage != null && (r == null
14835                            || !r.pkgList.containsKey(dumpPackage))) {
14836                        continue;
14837                    }
14838                    if (!printed) {
14839                        if (needSep) pw.println();
14840                        needSep = true;
14841                        pw.println("  Foreground Processes:");
14842                        printed = true;
14843                        printedAnything = true;
14844                    }
14845                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14846                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14847                }
14848            }
14849        }
14850
14851        if (mPersistentStartingProcesses.size() > 0) {
14852            if (needSep) pw.println();
14853            needSep = true;
14854            printedAnything = true;
14855            pw.println("  Persisent processes that are starting:");
14856            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14857                    "Starting Norm", "Restarting PERS", dumpPackage);
14858        }
14859
14860        if (mRemovedProcesses.size() > 0) {
14861            if (needSep) pw.println();
14862            needSep = true;
14863            printedAnything = true;
14864            pw.println("  Processes that are being removed:");
14865            dumpProcessList(pw, this, mRemovedProcesses, "    ",
14866                    "Removed Norm", "Removed PERS", dumpPackage);
14867        }
14868
14869        if (mProcessesOnHold.size() > 0) {
14870            if (needSep) pw.println();
14871            needSep = true;
14872            printedAnything = true;
14873            pw.println("  Processes that are on old until the system is ready:");
14874            dumpProcessList(pw, this, mProcessesOnHold, "    ",
14875                    "OnHold Norm", "OnHold PERS", dumpPackage);
14876        }
14877
14878        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14879
14880        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14881        if (needSep) {
14882            printedAnything = true;
14883        }
14884
14885        if (dumpPackage == null) {
14886            pw.println();
14887            needSep = false;
14888            mUserController.dump(pw, dumpAll);
14889        }
14890        if (mHomeProcess != null && (dumpPackage == null
14891                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14892            if (needSep) {
14893                pw.println();
14894                needSep = false;
14895            }
14896            pw.println("  mHomeProcess: " + mHomeProcess);
14897        }
14898        if (mPreviousProcess != null && (dumpPackage == null
14899                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14900            if (needSep) {
14901                pw.println();
14902                needSep = false;
14903            }
14904            pw.println("  mPreviousProcess: " + mPreviousProcess);
14905        }
14906        if (dumpAll) {
14907            StringBuilder sb = new StringBuilder(128);
14908            sb.append("  mPreviousProcessVisibleTime: ");
14909            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14910            pw.println(sb);
14911        }
14912        if (mHeavyWeightProcess != null && (dumpPackage == null
14913                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14914            if (needSep) {
14915                pw.println();
14916                needSep = false;
14917            }
14918            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14919        }
14920        if (dumpPackage == null) {
14921            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
14922            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
14923        }
14924        if (dumpAll) {
14925            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14926            if (mCompatModePackages.getPackages().size() > 0) {
14927                boolean printed = false;
14928                for (Map.Entry<String, Integer> entry
14929                        : mCompatModePackages.getPackages().entrySet()) {
14930                    String pkg = entry.getKey();
14931                    int mode = entry.getValue();
14932                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14933                        continue;
14934                    }
14935                    if (!printed) {
14936                        pw.println("  mScreenCompatPackages:");
14937                        printed = true;
14938                    }
14939                    pw.print("    "); pw.print(pkg); pw.print(": ");
14940                            pw.print(mode); pw.println();
14941                }
14942            }
14943            final int NI = mUidObservers.getRegisteredCallbackCount();
14944            boolean printed = false;
14945            for (int i=0; i<NI; i++) {
14946                final UidObserverRegistration reg = (UidObserverRegistration)
14947                        mUidObservers.getRegisteredCallbackCookie(i);
14948                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
14949                    if (!printed) {
14950                        pw.println("  mUidObservers:");
14951                        printed = true;
14952                    }
14953                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
14954                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
14955                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
14956                        pw.print(" IDLE");
14957                    }
14958                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
14959                        pw.print(" ACT" );
14960                    }
14961                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
14962                        pw.print(" GONE");
14963                    }
14964                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
14965                        pw.print(" STATE");
14966                        pw.print(" (cut="); pw.print(reg.cutpoint);
14967                        pw.print(")");
14968                    }
14969                    pw.println();
14970                    if (reg.lastProcStates != null) {
14971                        final int NJ = reg.lastProcStates.size();
14972                        for (int j=0; j<NJ; j++) {
14973                            pw.print("      Last ");
14974                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
14975                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
14976                        }
14977                    }
14978                }
14979            }
14980        }
14981        if (dumpPackage == null) {
14982            pw.println("  mWakefulness="
14983                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
14984            pw.println("  mSleepTokens=" + mSleepTokens);
14985            pw.println("  mSleeping=" + mSleeping);
14986            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14987            if (mRunningVoice != null) {
14988                pw.println("  mRunningVoice=" + mRunningVoice);
14989                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14990            }
14991        }
14992        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14993                || mOrigWaitForDebugger) {
14994            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14995                    || dumpPackage.equals(mOrigDebugApp)) {
14996                if (needSep) {
14997                    pw.println();
14998                    needSep = false;
14999                }
15000                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15001                        + " mDebugTransient=" + mDebugTransient
15002                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15003            }
15004        }
15005        if (mCurAppTimeTracker != null) {
15006            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15007        }
15008        if (mMemWatchProcesses.getMap().size() > 0) {
15009            pw.println("  Mem watch processes:");
15010            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15011                    = mMemWatchProcesses.getMap();
15012            for (int i=0; i<procs.size(); i++) {
15013                final String proc = procs.keyAt(i);
15014                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15015                for (int j=0; j<uids.size(); j++) {
15016                    if (needSep) {
15017                        pw.println();
15018                        needSep = false;
15019                    }
15020                    StringBuilder sb = new StringBuilder();
15021                    sb.append("    ").append(proc).append('/');
15022                    UserHandle.formatUid(sb, uids.keyAt(j));
15023                    Pair<Long, String> val = uids.valueAt(j);
15024                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15025                    if (val.second != null) {
15026                        sb.append(", report to ").append(val.second);
15027                    }
15028                    pw.println(sb.toString());
15029                }
15030            }
15031            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15032            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15033            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15034                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15035        }
15036        if (mTrackAllocationApp != null) {
15037            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15038                if (needSep) {
15039                    pw.println();
15040                    needSep = false;
15041                }
15042                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15043            }
15044        }
15045        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15046                || mProfileFd != null) {
15047            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15048                if (needSep) {
15049                    pw.println();
15050                    needSep = false;
15051                }
15052                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15053                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15054                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15055                        + mAutoStopProfiler);
15056                pw.println("  mProfileType=" + mProfileType);
15057            }
15058        }
15059        if (mNativeDebuggingApp != null) {
15060            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15061                if (needSep) {
15062                    pw.println();
15063                    needSep = false;
15064                }
15065                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15066            }
15067        }
15068        if (dumpPackage == null) {
15069            if (mAlwaysFinishActivities) {
15070                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15071            }
15072            if (mController != null) {
15073                pw.println("  mController=" + mController
15074                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15075            }
15076            if (dumpAll) {
15077                pw.println("  Total persistent processes: " + numPers);
15078                pw.println("  mProcessesReady=" + mProcessesReady
15079                        + " mSystemReady=" + mSystemReady
15080                        + " mBooted=" + mBooted
15081                        + " mFactoryTest=" + mFactoryTest);
15082                pw.println("  mBooting=" + mBooting
15083                        + " mCallFinishBooting=" + mCallFinishBooting
15084                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15085                pw.print("  mLastPowerCheckRealtime=");
15086                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15087                        pw.println("");
15088                pw.print("  mLastPowerCheckUptime=");
15089                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15090                        pw.println("");
15091                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15092                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15093                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15094                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15095                        + " (" + mLruProcesses.size() + " total)"
15096                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15097                        + " mNumServiceProcs=" + mNumServiceProcs
15098                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15099                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15100                        + " mLastMemoryLevel=" + mLastMemoryLevel
15101                        + " mLastNumProcesses=" + mLastNumProcesses);
15102                long now = SystemClock.uptimeMillis();
15103                pw.print("  mLastIdleTime=");
15104                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15105                        pw.print(" mLowRamSinceLastIdle=");
15106                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15107                        pw.println();
15108            }
15109        }
15110
15111        if (!printedAnything) {
15112            pw.println("  (nothing)");
15113        }
15114    }
15115
15116    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15117            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15118        if (mProcessesToGc.size() > 0) {
15119            boolean printed = false;
15120            long now = SystemClock.uptimeMillis();
15121            for (int i=0; i<mProcessesToGc.size(); i++) {
15122                ProcessRecord proc = mProcessesToGc.get(i);
15123                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15124                    continue;
15125                }
15126                if (!printed) {
15127                    if (needSep) pw.println();
15128                    needSep = true;
15129                    pw.println("  Processes that are waiting to GC:");
15130                    printed = true;
15131                }
15132                pw.print("    Process "); pw.println(proc);
15133                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15134                        pw.print(", last gced=");
15135                        pw.print(now-proc.lastRequestedGc);
15136                        pw.print(" ms ago, last lowMem=");
15137                        pw.print(now-proc.lastLowMemory);
15138                        pw.println(" ms ago");
15139
15140            }
15141        }
15142        return needSep;
15143    }
15144
15145    void printOomLevel(PrintWriter pw, String name, int adj) {
15146        pw.print("    ");
15147        if (adj >= 0) {
15148            pw.print(' ');
15149            if (adj < 10) pw.print(' ');
15150        } else {
15151            if (adj > -10) pw.print(' ');
15152        }
15153        pw.print(adj);
15154        pw.print(": ");
15155        pw.print(name);
15156        pw.print(" (");
15157        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15158        pw.println(")");
15159    }
15160
15161    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15162            int opti, boolean dumpAll) {
15163        boolean needSep = false;
15164
15165        if (mLruProcesses.size() > 0) {
15166            if (needSep) pw.println();
15167            needSep = true;
15168            pw.println("  OOM levels:");
15169            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15170            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15171            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15172            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15173            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15174            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15175            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15176            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15177            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15178            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15179            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15180            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15181            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15182            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15183
15184            if (needSep) pw.println();
15185            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15186                    pw.print(" total, non-act at ");
15187                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15188                    pw.print(", non-svc at ");
15189                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15190                    pw.println("):");
15191            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15192            needSep = true;
15193        }
15194
15195        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15196
15197        pw.println();
15198        pw.println("  mHomeProcess: " + mHomeProcess);
15199        pw.println("  mPreviousProcess: " + mPreviousProcess);
15200        if (mHeavyWeightProcess != null) {
15201            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15202        }
15203
15204        return true;
15205    }
15206
15207    /**
15208     * There are three ways to call this:
15209     *  - no provider specified: dump all the providers
15210     *  - a flattened component name that matched an existing provider was specified as the
15211     *    first arg: dump that one provider
15212     *  - the first arg isn't the flattened component name of an existing provider:
15213     *    dump all providers whose component contains the first arg as a substring
15214     */
15215    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15216            int opti, boolean dumpAll) {
15217        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15218    }
15219
15220    static class ItemMatcher {
15221        ArrayList<ComponentName> components;
15222        ArrayList<String> strings;
15223        ArrayList<Integer> objects;
15224        boolean all;
15225
15226        ItemMatcher() {
15227            all = true;
15228        }
15229
15230        void build(String name) {
15231            ComponentName componentName = ComponentName.unflattenFromString(name);
15232            if (componentName != null) {
15233                if (components == null) {
15234                    components = new ArrayList<ComponentName>();
15235                }
15236                components.add(componentName);
15237                all = false;
15238            } else {
15239                int objectId = 0;
15240                // Not a '/' separated full component name; maybe an object ID?
15241                try {
15242                    objectId = Integer.parseInt(name, 16);
15243                    if (objects == null) {
15244                        objects = new ArrayList<Integer>();
15245                    }
15246                    objects.add(objectId);
15247                    all = false;
15248                } catch (RuntimeException e) {
15249                    // Not an integer; just do string match.
15250                    if (strings == null) {
15251                        strings = new ArrayList<String>();
15252                    }
15253                    strings.add(name);
15254                    all = false;
15255                }
15256            }
15257        }
15258
15259        int build(String[] args, int opti) {
15260            for (; opti<args.length; opti++) {
15261                String name = args[opti];
15262                if ("--".equals(name)) {
15263                    return opti+1;
15264                }
15265                build(name);
15266            }
15267            return opti;
15268        }
15269
15270        boolean match(Object object, ComponentName comp) {
15271            if (all) {
15272                return true;
15273            }
15274            if (components != null) {
15275                for (int i=0; i<components.size(); i++) {
15276                    if (components.get(i).equals(comp)) {
15277                        return true;
15278                    }
15279                }
15280            }
15281            if (objects != null) {
15282                for (int i=0; i<objects.size(); i++) {
15283                    if (System.identityHashCode(object) == objects.get(i)) {
15284                        return true;
15285                    }
15286                }
15287            }
15288            if (strings != null) {
15289                String flat = comp.flattenToString();
15290                for (int i=0; i<strings.size(); i++) {
15291                    if (flat.contains(strings.get(i))) {
15292                        return true;
15293                    }
15294                }
15295            }
15296            return false;
15297        }
15298    }
15299
15300    /**
15301     * There are three things that cmd can be:
15302     *  - a flattened component name that matches an existing activity
15303     *  - the cmd arg isn't the flattened component name of an existing activity:
15304     *    dump all activity whose component contains the cmd as a substring
15305     *  - A hex number of the ActivityRecord object instance.
15306     */
15307    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15308            int opti, boolean dumpAll, boolean dumpVisibleStacks) {
15309        ArrayList<ActivityRecord> activities;
15310
15311        synchronized (this) {
15312            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacks);
15313        }
15314
15315        if (activities.size() <= 0) {
15316            return false;
15317        }
15318
15319        String[] newArgs = new String[args.length - opti];
15320        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15321
15322        TaskRecord lastTask = null;
15323        boolean needSep = false;
15324        for (int i=activities.size()-1; i>=0; i--) {
15325            ActivityRecord r = activities.get(i);
15326            if (needSep) {
15327                pw.println();
15328            }
15329            needSep = true;
15330            synchronized (this) {
15331                if (lastTask != r.task) {
15332                    lastTask = r.task;
15333                    pw.print("TASK "); pw.print(lastTask.affinity);
15334                            pw.print(" id="); pw.print(lastTask.taskId);
15335                            pw.print(" userId="); pw.println(lastTask.userId);
15336                    if (dumpAll) {
15337                        lastTask.dump(pw, "  ");
15338                    }
15339                }
15340            }
15341            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15342        }
15343        return true;
15344    }
15345
15346    /**
15347     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15348     * there is a thread associated with the activity.
15349     */
15350    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15351            final ActivityRecord r, String[] args, boolean dumpAll) {
15352        String innerPrefix = prefix + "  ";
15353        synchronized (this) {
15354            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15355                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15356                    pw.print(" pid=");
15357                    if (r.app != null) pw.println(r.app.pid);
15358                    else pw.println("(not running)");
15359            if (dumpAll) {
15360                r.dump(pw, innerPrefix);
15361            }
15362        }
15363        if (r.app != null && r.app.thread != null) {
15364            // flush anything that is already in the PrintWriter since the thread is going
15365            // to write to the file descriptor directly
15366            pw.flush();
15367            try {
15368                TransferPipe tp = new TransferPipe();
15369                try {
15370                    r.app.thread.dumpActivity(tp.getWriteFd(),
15371                            r.appToken, innerPrefix, args);
15372                    tp.go(fd);
15373                } finally {
15374                    tp.kill();
15375                }
15376            } catch (IOException e) {
15377                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15378            } catch (RemoteException e) {
15379                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15380            }
15381        }
15382    }
15383
15384    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15385            int opti, boolean dumpAll, String dumpPackage) {
15386        boolean needSep = false;
15387        boolean onlyHistory = false;
15388        boolean printedAnything = false;
15389
15390        if ("history".equals(dumpPackage)) {
15391            if (opti < args.length && "-s".equals(args[opti])) {
15392                dumpAll = false;
15393            }
15394            onlyHistory = true;
15395            dumpPackage = null;
15396        }
15397
15398        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15399        if (!onlyHistory && dumpAll) {
15400            if (mRegisteredReceivers.size() > 0) {
15401                boolean printed = false;
15402                Iterator it = mRegisteredReceivers.values().iterator();
15403                while (it.hasNext()) {
15404                    ReceiverList r = (ReceiverList)it.next();
15405                    if (dumpPackage != null && (r.app == null ||
15406                            !dumpPackage.equals(r.app.info.packageName))) {
15407                        continue;
15408                    }
15409                    if (!printed) {
15410                        pw.println("  Registered Receivers:");
15411                        needSep = true;
15412                        printed = true;
15413                        printedAnything = true;
15414                    }
15415                    pw.print("  * "); pw.println(r);
15416                    r.dump(pw, "    ");
15417                }
15418            }
15419
15420            if (mReceiverResolver.dump(pw, needSep ?
15421                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15422                    "    ", dumpPackage, false, false)) {
15423                needSep = true;
15424                printedAnything = true;
15425            }
15426        }
15427
15428        for (BroadcastQueue q : mBroadcastQueues) {
15429            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15430            printedAnything |= needSep;
15431        }
15432
15433        needSep = true;
15434
15435        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15436            for (int user=0; user<mStickyBroadcasts.size(); user++) {
15437                if (needSep) {
15438                    pw.println();
15439                }
15440                needSep = true;
15441                printedAnything = true;
15442                pw.print("  Sticky broadcasts for user ");
15443                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15444                StringBuilder sb = new StringBuilder(128);
15445                for (Map.Entry<String, ArrayList<Intent>> ent
15446                        : mStickyBroadcasts.valueAt(user).entrySet()) {
15447                    pw.print("  * Sticky action "); pw.print(ent.getKey());
15448                    if (dumpAll) {
15449                        pw.println(":");
15450                        ArrayList<Intent> intents = ent.getValue();
15451                        final int N = intents.size();
15452                        for (int i=0; i<N; i++) {
15453                            sb.setLength(0);
15454                            sb.append("    Intent: ");
15455                            intents.get(i).toShortString(sb, false, true, false, false);
15456                            pw.println(sb.toString());
15457                            Bundle bundle = intents.get(i).getExtras();
15458                            if (bundle != null) {
15459                                pw.print("      ");
15460                                pw.println(bundle.toString());
15461                            }
15462                        }
15463                    } else {
15464                        pw.println("");
15465                    }
15466                }
15467            }
15468        }
15469
15470        if (!onlyHistory && dumpAll) {
15471            pw.println();
15472            for (BroadcastQueue queue : mBroadcastQueues) {
15473                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15474                        + queue.mBroadcastsScheduled);
15475            }
15476            pw.println("  mHandler:");
15477            mHandler.dump(new PrintWriterPrinter(pw), "    ");
15478            needSep = true;
15479            printedAnything = true;
15480        }
15481
15482        if (!printedAnything) {
15483            pw.println("  (nothing)");
15484        }
15485    }
15486
15487    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15488            int opti, boolean dumpAll, String dumpPackage) {
15489        if (mCurBroadcastStats == null) {
15490            return;
15491        }
15492
15493        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15494        final long now = SystemClock.elapsedRealtime();
15495        if (mLastBroadcastStats != null) {
15496            pw.print("  Last stats (from ");
15497            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15498            pw.print(" to ");
15499            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15500            pw.print(", ");
15501            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15502                    - mLastBroadcastStats.mStartUptime, pw);
15503            pw.println(" uptime):");
15504            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15505                pw.println("    (nothing)");
15506            }
15507            pw.println();
15508        }
15509        pw.print("  Current stats (from ");
15510        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15511        pw.print(" to now, ");
15512        TimeUtils.formatDuration(SystemClock.uptimeMillis()
15513                - mCurBroadcastStats.mStartUptime, pw);
15514        pw.println(" uptime):");
15515        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15516            pw.println("    (nothing)");
15517        }
15518    }
15519
15520    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15521            int opti, boolean fullCheckin, String dumpPackage) {
15522        if (mCurBroadcastStats == null) {
15523            return;
15524        }
15525
15526        if (mLastBroadcastStats != null) {
15527            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15528            if (fullCheckin) {
15529                mLastBroadcastStats = null;
15530                return;
15531            }
15532        }
15533        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15534        if (fullCheckin) {
15535            mCurBroadcastStats = null;
15536        }
15537    }
15538
15539    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15540            int opti, boolean dumpAll, String dumpPackage) {
15541        boolean needSep;
15542        boolean printedAnything = false;
15543
15544        ItemMatcher matcher = new ItemMatcher();
15545        matcher.build(args, opti);
15546
15547        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15548
15549        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15550        printedAnything |= needSep;
15551
15552        if (mLaunchingProviders.size() > 0) {
15553            boolean printed = false;
15554            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15555                ContentProviderRecord r = mLaunchingProviders.get(i);
15556                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15557                    continue;
15558                }
15559                if (!printed) {
15560                    if (needSep) pw.println();
15561                    needSep = true;
15562                    pw.println("  Launching content providers:");
15563                    printed = true;
15564                    printedAnything = true;
15565                }
15566                pw.print("  Launching #"); pw.print(i); pw.print(": ");
15567                        pw.println(r);
15568            }
15569        }
15570
15571        if (!printedAnything) {
15572            pw.println("  (nothing)");
15573        }
15574    }
15575
15576    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15577            int opti, boolean dumpAll, String dumpPackage) {
15578        boolean needSep = false;
15579        boolean printedAnything = false;
15580
15581        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15582
15583        if (mGrantedUriPermissions.size() > 0) {
15584            boolean printed = false;
15585            int dumpUid = -2;
15586            if (dumpPackage != null) {
15587                try {
15588                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15589                            MATCH_ANY_USER, 0);
15590                } catch (NameNotFoundException e) {
15591                    dumpUid = -1;
15592                }
15593            }
15594            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15595                int uid = mGrantedUriPermissions.keyAt(i);
15596                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15597                    continue;
15598                }
15599                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15600                if (!printed) {
15601                    if (needSep) pw.println();
15602                    needSep = true;
15603                    pw.println("  Granted Uri Permissions:");
15604                    printed = true;
15605                    printedAnything = true;
15606                }
15607                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15608                for (UriPermission perm : perms.values()) {
15609                    pw.print("    "); pw.println(perm);
15610                    if (dumpAll) {
15611                        perm.dump(pw, "      ");
15612                    }
15613                }
15614            }
15615        }
15616
15617        if (!printedAnything) {
15618            pw.println("  (nothing)");
15619        }
15620    }
15621
15622    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15623            int opti, boolean dumpAll, String dumpPackage) {
15624        boolean printed = false;
15625
15626        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15627
15628        if (mIntentSenderRecords.size() > 0) {
15629            Iterator<WeakReference<PendingIntentRecord>> it
15630                    = mIntentSenderRecords.values().iterator();
15631            while (it.hasNext()) {
15632                WeakReference<PendingIntentRecord> ref = it.next();
15633                PendingIntentRecord rec = ref != null ? ref.get(): null;
15634                if (dumpPackage != null && (rec == null
15635                        || !dumpPackage.equals(rec.key.packageName))) {
15636                    continue;
15637                }
15638                printed = true;
15639                if (rec != null) {
15640                    pw.print("  * "); pw.println(rec);
15641                    if (dumpAll) {
15642                        rec.dump(pw, "    ");
15643                    }
15644                } else {
15645                    pw.print("  * "); pw.println(ref);
15646                }
15647            }
15648        }
15649
15650        if (!printed) {
15651            pw.println("  (nothing)");
15652        }
15653    }
15654
15655    private static final int dumpProcessList(PrintWriter pw,
15656            ActivityManagerService service, List list,
15657            String prefix, String normalLabel, String persistentLabel,
15658            String dumpPackage) {
15659        int numPers = 0;
15660        final int N = list.size()-1;
15661        for (int i=N; i>=0; i--) {
15662            ProcessRecord r = (ProcessRecord)list.get(i);
15663            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15664                continue;
15665            }
15666            pw.println(String.format("%s%s #%2d: %s",
15667                    prefix, (r.persistent ? persistentLabel : normalLabel),
15668                    i, r.toString()));
15669            if (r.persistent) {
15670                numPers++;
15671            }
15672        }
15673        return numPers;
15674    }
15675
15676    private static final boolean dumpProcessOomList(PrintWriter pw,
15677            ActivityManagerService service, List<ProcessRecord> origList,
15678            String prefix, String normalLabel, String persistentLabel,
15679            boolean inclDetails, String dumpPackage) {
15680
15681        ArrayList<Pair<ProcessRecord, Integer>> list
15682                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15683        for (int i=0; i<origList.size(); i++) {
15684            ProcessRecord r = origList.get(i);
15685            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15686                continue;
15687            }
15688            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15689        }
15690
15691        if (list.size() <= 0) {
15692            return false;
15693        }
15694
15695        Comparator<Pair<ProcessRecord, Integer>> comparator
15696                = new Comparator<Pair<ProcessRecord, Integer>>() {
15697            @Override
15698            public int compare(Pair<ProcessRecord, Integer> object1,
15699                    Pair<ProcessRecord, Integer> object2) {
15700                if (object1.first.setAdj != object2.first.setAdj) {
15701                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15702                }
15703                if (object1.first.setProcState != object2.first.setProcState) {
15704                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15705                }
15706                if (object1.second.intValue() != object2.second.intValue()) {
15707                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15708                }
15709                return 0;
15710            }
15711        };
15712
15713        Collections.sort(list, comparator);
15714
15715        final long curRealtime = SystemClock.elapsedRealtime();
15716        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15717        final long curUptime = SystemClock.uptimeMillis();
15718        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15719
15720        for (int i=list.size()-1; i>=0; i--) {
15721            ProcessRecord r = list.get(i).first;
15722            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15723            char schedGroup;
15724            switch (r.setSchedGroup) {
15725                case ProcessList.SCHED_GROUP_BACKGROUND:
15726                    schedGroup = 'B';
15727                    break;
15728                case ProcessList.SCHED_GROUP_DEFAULT:
15729                    schedGroup = 'F';
15730                    break;
15731                case ProcessList.SCHED_GROUP_TOP_APP:
15732                    schedGroup = 'T';
15733                    break;
15734                default:
15735                    schedGroup = '?';
15736                    break;
15737            }
15738            char foreground;
15739            if (r.foregroundActivities) {
15740                foreground = 'A';
15741            } else if (r.foregroundServices) {
15742                foreground = 'S';
15743            } else {
15744                foreground = ' ';
15745            }
15746            String procState = ProcessList.makeProcStateString(r.curProcState);
15747            pw.print(prefix);
15748            pw.print(r.persistent ? persistentLabel : normalLabel);
15749            pw.print(" #");
15750            int num = (origList.size()-1)-list.get(i).second;
15751            if (num < 10) pw.print(' ');
15752            pw.print(num);
15753            pw.print(": ");
15754            pw.print(oomAdj);
15755            pw.print(' ');
15756            pw.print(schedGroup);
15757            pw.print('/');
15758            pw.print(foreground);
15759            pw.print('/');
15760            pw.print(procState);
15761            pw.print(" trm:");
15762            if (r.trimMemoryLevel < 10) pw.print(' ');
15763            pw.print(r.trimMemoryLevel);
15764            pw.print(' ');
15765            pw.print(r.toShortString());
15766            pw.print(" (");
15767            pw.print(r.adjType);
15768            pw.println(')');
15769            if (r.adjSource != null || r.adjTarget != null) {
15770                pw.print(prefix);
15771                pw.print("    ");
15772                if (r.adjTarget instanceof ComponentName) {
15773                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15774                } else if (r.adjTarget != null) {
15775                    pw.print(r.adjTarget.toString());
15776                } else {
15777                    pw.print("{null}");
15778                }
15779                pw.print("<=");
15780                if (r.adjSource instanceof ProcessRecord) {
15781                    pw.print("Proc{");
15782                    pw.print(((ProcessRecord)r.adjSource).toShortString());
15783                    pw.println("}");
15784                } else if (r.adjSource != null) {
15785                    pw.println(r.adjSource.toString());
15786                } else {
15787                    pw.println("{null}");
15788                }
15789            }
15790            if (inclDetails) {
15791                pw.print(prefix);
15792                pw.print("    ");
15793                pw.print("oom: max="); pw.print(r.maxAdj);
15794                pw.print(" curRaw="); pw.print(r.curRawAdj);
15795                pw.print(" setRaw="); pw.print(r.setRawAdj);
15796                pw.print(" cur="); pw.print(r.curAdj);
15797                pw.print(" set="); pw.println(r.setAdj);
15798                pw.print(prefix);
15799                pw.print("    ");
15800                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15801                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15802                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15803                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15804                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15805                pw.println();
15806                pw.print(prefix);
15807                pw.print("    ");
15808                pw.print("cached="); pw.print(r.cached);
15809                pw.print(" empty="); pw.print(r.empty);
15810                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15811
15812                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15813                    if (r.lastWakeTime != 0) {
15814                        long wtime;
15815                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15816                        synchronized (stats) {
15817                            wtime = stats.getProcessWakeTime(r.info.uid,
15818                                    r.pid, curRealtime);
15819                        }
15820                        long timeUsed = wtime - r.lastWakeTime;
15821                        pw.print(prefix);
15822                        pw.print("    ");
15823                        pw.print("keep awake over ");
15824                        TimeUtils.formatDuration(realtimeSince, pw);
15825                        pw.print(" used ");
15826                        TimeUtils.formatDuration(timeUsed, pw);
15827                        pw.print(" (");
15828                        pw.print((timeUsed*100)/realtimeSince);
15829                        pw.println("%)");
15830                    }
15831                    if (r.lastCpuTime != 0) {
15832                        long timeUsed = r.curCpuTime - r.lastCpuTime;
15833                        pw.print(prefix);
15834                        pw.print("    ");
15835                        pw.print("run cpu over ");
15836                        TimeUtils.formatDuration(uptimeSince, pw);
15837                        pw.print(" used ");
15838                        TimeUtils.formatDuration(timeUsed, pw);
15839                        pw.print(" (");
15840                        pw.print((timeUsed*100)/uptimeSince);
15841                        pw.println("%)");
15842                    }
15843                }
15844            }
15845        }
15846        return true;
15847    }
15848
15849    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15850            String[] args) {
15851        ArrayList<ProcessRecord> procs;
15852        synchronized (this) {
15853            if (args != null && args.length > start
15854                    && args[start].charAt(0) != '-') {
15855                procs = new ArrayList<ProcessRecord>();
15856                int pid = -1;
15857                try {
15858                    pid = Integer.parseInt(args[start]);
15859                } catch (NumberFormatException e) {
15860                }
15861                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15862                    ProcessRecord proc = mLruProcesses.get(i);
15863                    if (proc.pid == pid) {
15864                        procs.add(proc);
15865                    } else if (allPkgs && proc.pkgList != null
15866                            && proc.pkgList.containsKey(args[start])) {
15867                        procs.add(proc);
15868                    } else if (proc.processName.equals(args[start])) {
15869                        procs.add(proc);
15870                    }
15871                }
15872                if (procs.size() <= 0) {
15873                    return null;
15874                }
15875            } else {
15876                procs = new ArrayList<ProcessRecord>(mLruProcesses);
15877            }
15878        }
15879        return procs;
15880    }
15881
15882    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15883            PrintWriter pw, String[] args) {
15884        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15885        if (procs == null) {
15886            pw.println("No process found for: " + args[0]);
15887            return;
15888        }
15889
15890        long uptime = SystemClock.uptimeMillis();
15891        long realtime = SystemClock.elapsedRealtime();
15892        pw.println("Applications Graphics Acceleration Info:");
15893        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15894
15895        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15896            ProcessRecord r = procs.get(i);
15897            if (r.thread != null) {
15898                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15899                pw.flush();
15900                try {
15901                    TransferPipe tp = new TransferPipe();
15902                    try {
15903                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
15904                        tp.go(fd);
15905                    } finally {
15906                        tp.kill();
15907                    }
15908                } catch (IOException e) {
15909                    pw.println("Failure while dumping the app: " + r);
15910                    pw.flush();
15911                } catch (RemoteException e) {
15912                    pw.println("Got a RemoteException while dumping the app " + r);
15913                    pw.flush();
15914                }
15915            }
15916        }
15917    }
15918
15919    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15920        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15921        if (procs == null) {
15922            pw.println("No process found for: " + args[0]);
15923            return;
15924        }
15925
15926        pw.println("Applications Database Info:");
15927
15928        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15929            ProcessRecord r = procs.get(i);
15930            if (r.thread != null) {
15931                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15932                pw.flush();
15933                try {
15934                    TransferPipe tp = new TransferPipe();
15935                    try {
15936                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
15937                        tp.go(fd);
15938                    } finally {
15939                        tp.kill();
15940                    }
15941                } catch (IOException e) {
15942                    pw.println("Failure while dumping the app: " + r);
15943                    pw.flush();
15944                } catch (RemoteException e) {
15945                    pw.println("Got a RemoteException while dumping the app " + r);
15946                    pw.flush();
15947                }
15948            }
15949        }
15950    }
15951
15952    final static class MemItem {
15953        final boolean isProc;
15954        final String label;
15955        final String shortLabel;
15956        final long pss;
15957        final long swapPss;
15958        final int id;
15959        final boolean hasActivities;
15960        ArrayList<MemItem> subitems;
15961
15962        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15963                boolean _hasActivities) {
15964            isProc = true;
15965            label = _label;
15966            shortLabel = _shortLabel;
15967            pss = _pss;
15968            swapPss = _swapPss;
15969            id = _id;
15970            hasActivities = _hasActivities;
15971        }
15972
15973        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15974            isProc = false;
15975            label = _label;
15976            shortLabel = _shortLabel;
15977            pss = _pss;
15978            swapPss = _swapPss;
15979            id = _id;
15980            hasActivities = false;
15981        }
15982    }
15983
15984    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15985            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15986        if (sort && !isCompact) {
15987            Collections.sort(items, new Comparator<MemItem>() {
15988                @Override
15989                public int compare(MemItem lhs, MemItem rhs) {
15990                    if (lhs.pss < rhs.pss) {
15991                        return 1;
15992                    } else if (lhs.pss > rhs.pss) {
15993                        return -1;
15994                    }
15995                    return 0;
15996                }
15997            });
15998        }
15999
16000        for (int i=0; i<items.size(); i++) {
16001            MemItem mi = items.get(i);
16002            if (!isCompact) {
16003                if (dumpSwapPss) {
16004                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16005                            mi.label, stringifyKBSize(mi.swapPss));
16006                } else {
16007                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16008                }
16009            } else if (mi.isProc) {
16010                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16011                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16012                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16013                pw.println(mi.hasActivities ? ",a" : ",e");
16014            } else {
16015                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16016                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16017            }
16018            if (mi.subitems != null) {
16019                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16020                        true, isCompact, dumpSwapPss);
16021            }
16022        }
16023    }
16024
16025    // These are in KB.
16026    static final long[] DUMP_MEM_BUCKETS = new long[] {
16027        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16028        120*1024, 160*1024, 200*1024,
16029        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16030        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16031    };
16032
16033    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16034            boolean stackLike) {
16035        int start = label.lastIndexOf('.');
16036        if (start >= 0) start++;
16037        else start = 0;
16038        int end = label.length();
16039        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16040            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16041                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16042                out.append(bucket);
16043                out.append(stackLike ? "MB." : "MB ");
16044                out.append(label, start, end);
16045                return;
16046            }
16047        }
16048        out.append(memKB/1024);
16049        out.append(stackLike ? "MB." : "MB ");
16050        out.append(label, start, end);
16051    }
16052
16053    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16054            ProcessList.NATIVE_ADJ,
16055            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16056            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16057            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16058            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16059            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16060            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16061    };
16062    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16063            "Native",
16064            "System", "Persistent", "Persistent Service", "Foreground",
16065            "Visible", "Perceptible",
16066            "Heavy Weight", "Backup",
16067            "A Services", "Home",
16068            "Previous", "B Services", "Cached"
16069    };
16070    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16071            "native",
16072            "sys", "pers", "persvc", "fore",
16073            "vis", "percept",
16074            "heavy", "backup",
16075            "servicea", "home",
16076            "prev", "serviceb", "cached"
16077    };
16078
16079    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16080            long realtime, boolean isCheckinRequest, boolean isCompact) {
16081        if (isCompact) {
16082            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16083        }
16084        if (isCheckinRequest || isCompact) {
16085            // short checkin version
16086            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16087        } else {
16088            pw.println("Applications Memory Usage (in Kilobytes):");
16089            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16090        }
16091    }
16092
16093    private static final int KSM_SHARED = 0;
16094    private static final int KSM_SHARING = 1;
16095    private static final int KSM_UNSHARED = 2;
16096    private static final int KSM_VOLATILE = 3;
16097
16098    private final long[] getKsmInfo() {
16099        long[] longOut = new long[4];
16100        final int[] SINGLE_LONG_FORMAT = new int[] {
16101            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16102        };
16103        long[] longTmp = new long[1];
16104        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16105                SINGLE_LONG_FORMAT, null, longTmp, null);
16106        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16107        longTmp[0] = 0;
16108        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16109                SINGLE_LONG_FORMAT, null, longTmp, null);
16110        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16111        longTmp[0] = 0;
16112        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16113                SINGLE_LONG_FORMAT, null, longTmp, null);
16114        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16115        longTmp[0] = 0;
16116        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16117                SINGLE_LONG_FORMAT, null, longTmp, null);
16118        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16119        return longOut;
16120    }
16121
16122    private static String stringifySize(long size, int order) {
16123        Locale locale = Locale.US;
16124        switch (order) {
16125            case 1:
16126                return String.format(locale, "%,13d", size);
16127            case 1024:
16128                return String.format(locale, "%,9dK", size / 1024);
16129            case 1024 * 1024:
16130                return String.format(locale, "%,5dM", size / 1024 / 1024);
16131            case 1024 * 1024 * 1024:
16132                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16133            default:
16134                throw new IllegalArgumentException("Invalid size order");
16135        }
16136    }
16137
16138    private static String stringifyKBSize(long size) {
16139        return stringifySize(size * 1024, 1024);
16140    }
16141
16142    // Update this version number in case you change the 'compact' format
16143    private static final int MEMINFO_COMPACT_VERSION = 1;
16144
16145    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16146            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16147        boolean dumpDetails = false;
16148        boolean dumpFullDetails = false;
16149        boolean dumpDalvik = false;
16150        boolean dumpSummaryOnly = false;
16151        boolean dumpUnreachable = false;
16152        boolean oomOnly = false;
16153        boolean isCompact = false;
16154        boolean localOnly = false;
16155        boolean packages = false;
16156        boolean isCheckinRequest = false;
16157        boolean dumpSwapPss = false;
16158
16159        int opti = 0;
16160        while (opti < args.length) {
16161            String opt = args[opti];
16162            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16163                break;
16164            }
16165            opti++;
16166            if ("-a".equals(opt)) {
16167                dumpDetails = true;
16168                dumpFullDetails = true;
16169                dumpDalvik = true;
16170                dumpSwapPss = true;
16171            } else if ("-d".equals(opt)) {
16172                dumpDalvik = true;
16173            } else if ("-c".equals(opt)) {
16174                isCompact = true;
16175            } else if ("-s".equals(opt)) {
16176                dumpDetails = true;
16177                dumpSummaryOnly = true;
16178            } else if ("-S".equals(opt)) {
16179                dumpSwapPss = true;
16180            } else if ("--unreachable".equals(opt)) {
16181                dumpUnreachable = true;
16182            } else if ("--oom".equals(opt)) {
16183                oomOnly = true;
16184            } else if ("--local".equals(opt)) {
16185                localOnly = true;
16186            } else if ("--package".equals(opt)) {
16187                packages = true;
16188            } else if ("--checkin".equals(opt)) {
16189                isCheckinRequest = true;
16190
16191            } else if ("-h".equals(opt)) {
16192                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16193                pw.println("  -a: include all available information for each process.");
16194                pw.println("  -d: include dalvik details.");
16195                pw.println("  -c: dump in a compact machine-parseable representation.");
16196                pw.println("  -s: dump only summary of application memory usage.");
16197                pw.println("  -S: dump also SwapPss.");
16198                pw.println("  --oom: only show processes organized by oom adj.");
16199                pw.println("  --local: only collect details locally, don't call process.");
16200                pw.println("  --package: interpret process arg as package, dumping all");
16201                pw.println("             processes that have loaded that package.");
16202                pw.println("  --checkin: dump data for a checkin");
16203                pw.println("If [process] is specified it can be the name or ");
16204                pw.println("pid of a specific process to dump.");
16205                return;
16206            } else {
16207                pw.println("Unknown argument: " + opt + "; use -h for help");
16208            }
16209        }
16210
16211        long uptime = SystemClock.uptimeMillis();
16212        long realtime = SystemClock.elapsedRealtime();
16213        final long[] tmpLong = new long[1];
16214
16215        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16216        if (procs == null) {
16217            // No Java processes.  Maybe they want to print a native process.
16218            if (args != null && args.length > opti
16219                    && args[opti].charAt(0) != '-') {
16220                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16221                        = new ArrayList<ProcessCpuTracker.Stats>();
16222                updateCpuStatsNow();
16223                int findPid = -1;
16224                try {
16225                    findPid = Integer.parseInt(args[opti]);
16226                } catch (NumberFormatException e) {
16227                }
16228                synchronized (mProcessCpuTracker) {
16229                    final int N = mProcessCpuTracker.countStats();
16230                    for (int i=0; i<N; i++) {
16231                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16232                        if (st.pid == findPid || (st.baseName != null
16233                                && st.baseName.equals(args[opti]))) {
16234                            nativeProcs.add(st);
16235                        }
16236                    }
16237                }
16238                if (nativeProcs.size() > 0) {
16239                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16240                            isCompact);
16241                    Debug.MemoryInfo mi = null;
16242                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16243                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16244                        final int pid = r.pid;
16245                        if (!isCheckinRequest && dumpDetails) {
16246                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16247                        }
16248                        if (mi == null) {
16249                            mi = new Debug.MemoryInfo();
16250                        }
16251                        if (dumpDetails || (!brief && !oomOnly)) {
16252                            Debug.getMemoryInfo(pid, mi);
16253                        } else {
16254                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16255                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16256                        }
16257                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16258                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16259                        if (isCheckinRequest) {
16260                            pw.println();
16261                        }
16262                    }
16263                    return;
16264                }
16265            }
16266            pw.println("No process found for: " + args[opti]);
16267            return;
16268        }
16269
16270        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16271            dumpDetails = true;
16272        }
16273
16274        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16275
16276        String[] innerArgs = new String[args.length-opti];
16277        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16278
16279        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16280        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16281        long nativePss = 0;
16282        long nativeSwapPss = 0;
16283        long dalvikPss = 0;
16284        long dalvikSwapPss = 0;
16285        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16286                EmptyArray.LONG;
16287        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16288                EmptyArray.LONG;
16289        long otherPss = 0;
16290        long otherSwapPss = 0;
16291        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16292        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16293
16294        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16295        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16296        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16297                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16298
16299        long totalPss = 0;
16300        long totalSwapPss = 0;
16301        long cachedPss = 0;
16302        long cachedSwapPss = 0;
16303        boolean hasSwapPss = false;
16304
16305        Debug.MemoryInfo mi = null;
16306        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16307            final ProcessRecord r = procs.get(i);
16308            final IApplicationThread thread;
16309            final int pid;
16310            final int oomAdj;
16311            final boolean hasActivities;
16312            synchronized (this) {
16313                thread = r.thread;
16314                pid = r.pid;
16315                oomAdj = r.getSetAdjWithServices();
16316                hasActivities = r.activities.size() > 0;
16317            }
16318            if (thread != null) {
16319                if (!isCheckinRequest && dumpDetails) {
16320                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16321                }
16322                if (mi == null) {
16323                    mi = new Debug.MemoryInfo();
16324                }
16325                if (dumpDetails || (!brief && !oomOnly)) {
16326                    Debug.getMemoryInfo(pid, mi);
16327                    hasSwapPss = mi.hasSwappedOutPss;
16328                } else {
16329                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16330                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16331                }
16332                if (dumpDetails) {
16333                    if (localOnly) {
16334                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16335                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16336                        if (isCheckinRequest) {
16337                            pw.println();
16338                        }
16339                    } else {
16340                        pw.flush();
16341                        try {
16342                            TransferPipe tp = new TransferPipe();
16343                            try {
16344                                thread.dumpMemInfo(tp.getWriteFd(),
16345                                        mi, isCheckinRequest, dumpFullDetails,
16346                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16347                                tp.go(fd);
16348                            } finally {
16349                                tp.kill();
16350                            }
16351                        } catch (IOException e) {
16352                            if (!isCheckinRequest) {
16353                                pw.println("Got IoException!");
16354                                pw.flush();
16355                            }
16356                        } catch (RemoteException e) {
16357                            if (!isCheckinRequest) {
16358                                pw.println("Got RemoteException!");
16359                                pw.flush();
16360                            }
16361                        }
16362                    }
16363                }
16364
16365                final long myTotalPss = mi.getTotalPss();
16366                final long myTotalUss = mi.getTotalUss();
16367                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16368
16369                synchronized (this) {
16370                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16371                        // Record this for posterity if the process has been stable.
16372                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16373                    }
16374                }
16375
16376                if (!isCheckinRequest && mi != null) {
16377                    totalPss += myTotalPss;
16378                    totalSwapPss += myTotalSwapPss;
16379                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16380                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16381                            myTotalSwapPss, pid, hasActivities);
16382                    procMems.add(pssItem);
16383                    procMemsMap.put(pid, pssItem);
16384
16385                    nativePss += mi.nativePss;
16386                    nativeSwapPss += mi.nativeSwappedOutPss;
16387                    dalvikPss += mi.dalvikPss;
16388                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16389                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16390                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16391                        dalvikSubitemSwapPss[j] +=
16392                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16393                    }
16394                    otherPss += mi.otherPss;
16395                    otherSwapPss += mi.otherSwappedOutPss;
16396                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16397                        long mem = mi.getOtherPss(j);
16398                        miscPss[j] += mem;
16399                        otherPss -= mem;
16400                        mem = mi.getOtherSwappedOutPss(j);
16401                        miscSwapPss[j] += mem;
16402                        otherSwapPss -= mem;
16403                    }
16404
16405                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16406                        cachedPss += myTotalPss;
16407                        cachedSwapPss += myTotalSwapPss;
16408                    }
16409
16410                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16411                        if (oomIndex == (oomPss.length - 1)
16412                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16413                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16414                            oomPss[oomIndex] += myTotalPss;
16415                            oomSwapPss[oomIndex] += myTotalSwapPss;
16416                            if (oomProcs[oomIndex] == null) {
16417                                oomProcs[oomIndex] = new ArrayList<MemItem>();
16418                            }
16419                            oomProcs[oomIndex].add(pssItem);
16420                            break;
16421                        }
16422                    }
16423                }
16424            }
16425        }
16426
16427        long nativeProcTotalPss = 0;
16428
16429        if (!isCheckinRequest && procs.size() > 1 && !packages) {
16430            // If we are showing aggregations, also look for native processes to
16431            // include so that our aggregations are more accurate.
16432            updateCpuStatsNow();
16433            mi = null;
16434            synchronized (mProcessCpuTracker) {
16435                final int N = mProcessCpuTracker.countStats();
16436                for (int i=0; i<N; i++) {
16437                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16438                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16439                        if (mi == null) {
16440                            mi = new Debug.MemoryInfo();
16441                        }
16442                        if (!brief && !oomOnly) {
16443                            Debug.getMemoryInfo(st.pid, mi);
16444                        } else {
16445                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16446                            mi.nativePrivateDirty = (int)tmpLong[0];
16447                        }
16448
16449                        final long myTotalPss = mi.getTotalPss();
16450                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16451                        totalPss += myTotalPss;
16452                        nativeProcTotalPss += myTotalPss;
16453
16454                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16455                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16456                        procMems.add(pssItem);
16457
16458                        nativePss += mi.nativePss;
16459                        nativeSwapPss += mi.nativeSwappedOutPss;
16460                        dalvikPss += mi.dalvikPss;
16461                        dalvikSwapPss += mi.dalvikSwappedOutPss;
16462                        for (int j=0; j<dalvikSubitemPss.length; j++) {
16463                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16464                            dalvikSubitemSwapPss[j] +=
16465                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16466                        }
16467                        otherPss += mi.otherPss;
16468                        otherSwapPss += mi.otherSwappedOutPss;
16469                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16470                            long mem = mi.getOtherPss(j);
16471                            miscPss[j] += mem;
16472                            otherPss -= mem;
16473                            mem = mi.getOtherSwappedOutPss(j);
16474                            miscSwapPss[j] += mem;
16475                            otherSwapPss -= mem;
16476                        }
16477                        oomPss[0] += myTotalPss;
16478                        oomSwapPss[0] += myTotalSwapPss;
16479                        if (oomProcs[0] == null) {
16480                            oomProcs[0] = new ArrayList<MemItem>();
16481                        }
16482                        oomProcs[0].add(pssItem);
16483                    }
16484                }
16485            }
16486
16487            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16488
16489            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16490            final MemItem dalvikItem =
16491                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16492            if (dalvikSubitemPss.length > 0) {
16493                dalvikItem.subitems = new ArrayList<MemItem>();
16494                for (int j=0; j<dalvikSubitemPss.length; j++) {
16495                    final String name = Debug.MemoryInfo.getOtherLabel(
16496                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
16497                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16498                                    dalvikSubitemSwapPss[j], j));
16499                }
16500            }
16501            catMems.add(dalvikItem);
16502            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16503            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16504                String label = Debug.MemoryInfo.getOtherLabel(j);
16505                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16506            }
16507
16508            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16509            for (int j=0; j<oomPss.length; j++) {
16510                if (oomPss[j] != 0) {
16511                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16512                            : DUMP_MEM_OOM_LABEL[j];
16513                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16514                            DUMP_MEM_OOM_ADJ[j]);
16515                    item.subitems = oomProcs[j];
16516                    oomMems.add(item);
16517                }
16518            }
16519
16520            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16521            if (!brief && !oomOnly && !isCompact) {
16522                pw.println();
16523                pw.println("Total PSS by process:");
16524                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16525                pw.println();
16526            }
16527            if (!isCompact) {
16528                pw.println("Total PSS by OOM adjustment:");
16529            }
16530            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16531            if (!brief && !oomOnly) {
16532                PrintWriter out = categoryPw != null ? categoryPw : pw;
16533                if (!isCompact) {
16534                    out.println();
16535                    out.println("Total PSS by category:");
16536                }
16537                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16538            }
16539            if (!isCompact) {
16540                pw.println();
16541            }
16542            MemInfoReader memInfo = new MemInfoReader();
16543            memInfo.readMemInfo();
16544            if (nativeProcTotalPss > 0) {
16545                synchronized (this) {
16546                    final long cachedKb = memInfo.getCachedSizeKb();
16547                    final long freeKb = memInfo.getFreeSizeKb();
16548                    final long zramKb = memInfo.getZramTotalSizeKb();
16549                    final long kernelKb = memInfo.getKernelUsedSizeKb();
16550                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16551                            kernelKb*1024, nativeProcTotalPss*1024);
16552                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16553                            nativeProcTotalPss);
16554                }
16555            }
16556            if (!brief) {
16557                if (!isCompact) {
16558                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16559                    pw.print(" (status ");
16560                    switch (mLastMemoryLevel) {
16561                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16562                            pw.println("normal)");
16563                            break;
16564                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16565                            pw.println("moderate)");
16566                            break;
16567                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
16568                            pw.println("low)");
16569                            break;
16570                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16571                            pw.println("critical)");
16572                            break;
16573                        default:
16574                            pw.print(mLastMemoryLevel);
16575                            pw.println(")");
16576                            break;
16577                    }
16578                    pw.print(" Free RAM: ");
16579                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16580                            + memInfo.getFreeSizeKb()));
16581                    pw.print(" (");
16582                    pw.print(stringifyKBSize(cachedPss));
16583                    pw.print(" cached pss + ");
16584                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16585                    pw.print(" cached kernel + ");
16586                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16587                    pw.println(" free)");
16588                } else {
16589                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16590                    pw.print(cachedPss + memInfo.getCachedSizeKb()
16591                            + memInfo.getFreeSizeKb()); pw.print(",");
16592                    pw.println(totalPss - cachedPss);
16593                }
16594            }
16595            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16596                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16597                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16598            if (!isCompact) {
16599                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16600                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16601                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16602                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16603                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16604            } else {
16605                pw.print("lostram,"); pw.println(lostRAM);
16606            }
16607            if (!brief) {
16608                if (memInfo.getZramTotalSizeKb() != 0) {
16609                    if (!isCompact) {
16610                        pw.print("     ZRAM: ");
16611                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16612                                pw.print(" physical used for ");
16613                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16614                                        - memInfo.getSwapFreeSizeKb()));
16615                                pw.print(" in swap (");
16616                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16617                                pw.println(" total swap)");
16618                    } else {
16619                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16620                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16621                                pw.println(memInfo.getSwapFreeSizeKb());
16622                    }
16623                }
16624                final long[] ksm = getKsmInfo();
16625                if (!isCompact) {
16626                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16627                            || ksm[KSM_VOLATILE] != 0) {
16628                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16629                                pw.print(" saved from shared ");
16630                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16631                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16632                                pw.print(" unshared; ");
16633                                pw.print(stringifyKBSize(
16634                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
16635                    }
16636                    pw.print("   Tuning: ");
16637                    pw.print(ActivityManager.staticGetMemoryClass());
16638                    pw.print(" (large ");
16639                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16640                    pw.print("), oom ");
16641                    pw.print(stringifySize(
16642                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16643                    pw.print(", restore limit ");
16644                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16645                    if (ActivityManager.isLowRamDeviceStatic()) {
16646                        pw.print(" (low-ram)");
16647                    }
16648                    if (ActivityManager.isHighEndGfx()) {
16649                        pw.print(" (high-end-gfx)");
16650                    }
16651                    pw.println();
16652                } else {
16653                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16654                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16655                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16656                    pw.print("tuning,");
16657                    pw.print(ActivityManager.staticGetMemoryClass());
16658                    pw.print(',');
16659                    pw.print(ActivityManager.staticGetLargeMemoryClass());
16660                    pw.print(',');
16661                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16662                    if (ActivityManager.isLowRamDeviceStatic()) {
16663                        pw.print(",low-ram");
16664                    }
16665                    if (ActivityManager.isHighEndGfx()) {
16666                        pw.print(",high-end-gfx");
16667                    }
16668                    pw.println();
16669                }
16670            }
16671        }
16672    }
16673
16674    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16675            long memtrack, String name) {
16676        sb.append("  ");
16677        sb.append(ProcessList.makeOomAdjString(oomAdj));
16678        sb.append(' ');
16679        sb.append(ProcessList.makeProcStateString(procState));
16680        sb.append(' ');
16681        ProcessList.appendRamKb(sb, pss);
16682        sb.append(": ");
16683        sb.append(name);
16684        if (memtrack > 0) {
16685            sb.append(" (");
16686            sb.append(stringifyKBSize(memtrack));
16687            sb.append(" memtrack)");
16688        }
16689    }
16690
16691    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16692        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16693        sb.append(" (pid ");
16694        sb.append(mi.pid);
16695        sb.append(") ");
16696        sb.append(mi.adjType);
16697        sb.append('\n');
16698        if (mi.adjReason != null) {
16699            sb.append("                      ");
16700            sb.append(mi.adjReason);
16701            sb.append('\n');
16702        }
16703    }
16704
16705    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16706        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16707        for (int i=0, N=memInfos.size(); i<N; i++) {
16708            ProcessMemInfo mi = memInfos.get(i);
16709            infoMap.put(mi.pid, mi);
16710        }
16711        updateCpuStatsNow();
16712        long[] memtrackTmp = new long[1];
16713        final List<ProcessCpuTracker.Stats> stats;
16714        // Get a list of Stats that have vsize > 0
16715        synchronized (mProcessCpuTracker) {
16716            stats = mProcessCpuTracker.getStats((st) -> {
16717                return st.vsize > 0;
16718            });
16719        }
16720        final int statsCount = stats.size();
16721        for (int i = 0; i < statsCount; i++) {
16722            ProcessCpuTracker.Stats st = stats.get(i);
16723            long pss = Debug.getPss(st.pid, null, memtrackTmp);
16724            if (pss > 0) {
16725                if (infoMap.indexOfKey(st.pid) < 0) {
16726                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16727                            ProcessList.NATIVE_ADJ, -1, "native", null);
16728                    mi.pss = pss;
16729                    mi.memtrack = memtrackTmp[0];
16730                    memInfos.add(mi);
16731                }
16732            }
16733        }
16734
16735        long totalPss = 0;
16736        long totalMemtrack = 0;
16737        for (int i=0, N=memInfos.size(); i<N; i++) {
16738            ProcessMemInfo mi = memInfos.get(i);
16739            if (mi.pss == 0) {
16740                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16741                mi.memtrack = memtrackTmp[0];
16742            }
16743            totalPss += mi.pss;
16744            totalMemtrack += mi.memtrack;
16745        }
16746        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16747            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16748                if (lhs.oomAdj != rhs.oomAdj) {
16749                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16750                }
16751                if (lhs.pss != rhs.pss) {
16752                    return lhs.pss < rhs.pss ? 1 : -1;
16753                }
16754                return 0;
16755            }
16756        });
16757
16758        StringBuilder tag = new StringBuilder(128);
16759        StringBuilder stack = new StringBuilder(128);
16760        tag.append("Low on memory -- ");
16761        appendMemBucket(tag, totalPss, "total", false);
16762        appendMemBucket(stack, totalPss, "total", true);
16763
16764        StringBuilder fullNativeBuilder = new StringBuilder(1024);
16765        StringBuilder shortNativeBuilder = new StringBuilder(1024);
16766        StringBuilder fullJavaBuilder = new StringBuilder(1024);
16767
16768        boolean firstLine = true;
16769        int lastOomAdj = Integer.MIN_VALUE;
16770        long extraNativeRam = 0;
16771        long extraNativeMemtrack = 0;
16772        long cachedPss = 0;
16773        for (int i=0, N=memInfos.size(); i<N; i++) {
16774            ProcessMemInfo mi = memInfos.get(i);
16775
16776            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16777                cachedPss += mi.pss;
16778            }
16779
16780            if (mi.oomAdj != ProcessList.NATIVE_ADJ
16781                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
16782                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
16783                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16784                if (lastOomAdj != mi.oomAdj) {
16785                    lastOomAdj = mi.oomAdj;
16786                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16787                        tag.append(" / ");
16788                    }
16789                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16790                        if (firstLine) {
16791                            stack.append(":");
16792                            firstLine = false;
16793                        }
16794                        stack.append("\n\t at ");
16795                    } else {
16796                        stack.append("$");
16797                    }
16798                } else {
16799                    tag.append(" ");
16800                    stack.append("$");
16801                }
16802                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16803                    appendMemBucket(tag, mi.pss, mi.name, false);
16804                }
16805                appendMemBucket(stack, mi.pss, mi.name, true);
16806                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16807                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16808                    stack.append("(");
16809                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16810                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16811                            stack.append(DUMP_MEM_OOM_LABEL[k]);
16812                            stack.append(":");
16813                            stack.append(DUMP_MEM_OOM_ADJ[k]);
16814                        }
16815                    }
16816                    stack.append(")");
16817                }
16818            }
16819
16820            appendMemInfo(fullNativeBuilder, mi);
16821            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16822                // The short form only has native processes that are >= 512K.
16823                if (mi.pss >= 512) {
16824                    appendMemInfo(shortNativeBuilder, mi);
16825                } else {
16826                    extraNativeRam += mi.pss;
16827                    extraNativeMemtrack += mi.memtrack;
16828                }
16829            } else {
16830                // Short form has all other details, but if we have collected RAM
16831                // from smaller native processes let's dump a summary of that.
16832                if (extraNativeRam > 0) {
16833                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16834                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16835                    shortNativeBuilder.append('\n');
16836                    extraNativeRam = 0;
16837                }
16838                appendMemInfo(fullJavaBuilder, mi);
16839            }
16840        }
16841
16842        fullJavaBuilder.append("           ");
16843        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16844        fullJavaBuilder.append(": TOTAL");
16845        if (totalMemtrack > 0) {
16846            fullJavaBuilder.append(" (");
16847            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16848            fullJavaBuilder.append(" memtrack)");
16849        } else {
16850        }
16851        fullJavaBuilder.append("\n");
16852
16853        MemInfoReader memInfo = new MemInfoReader();
16854        memInfo.readMemInfo();
16855        final long[] infos = memInfo.getRawInfo();
16856
16857        StringBuilder memInfoBuilder = new StringBuilder(1024);
16858        Debug.getMemInfo(infos);
16859        memInfoBuilder.append("  MemInfo: ");
16860        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16861        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16862        memInfoBuilder.append(stringifyKBSize(
16863                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16864        memInfoBuilder.append(stringifyKBSize(
16865                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16866        memInfoBuilder.append(stringifyKBSize(
16867                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16868        memInfoBuilder.append("           ");
16869        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16870        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16871        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16872        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16873        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16874            memInfoBuilder.append("  ZRAM: ");
16875            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16876            memInfoBuilder.append(" RAM, ");
16877            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16878            memInfoBuilder.append(" swap total, ");
16879            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16880            memInfoBuilder.append(" swap free\n");
16881        }
16882        final long[] ksm = getKsmInfo();
16883        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16884                || ksm[KSM_VOLATILE] != 0) {
16885            memInfoBuilder.append("  KSM: ");
16886            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16887            memInfoBuilder.append(" saved from shared ");
16888            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16889            memInfoBuilder.append("\n       ");
16890            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16891            memInfoBuilder.append(" unshared; ");
16892            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16893            memInfoBuilder.append(" volatile\n");
16894        }
16895        memInfoBuilder.append("  Free RAM: ");
16896        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16897                + memInfo.getFreeSizeKb()));
16898        memInfoBuilder.append("\n");
16899        memInfoBuilder.append("  Used RAM: ");
16900        memInfoBuilder.append(stringifyKBSize(
16901                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16902        memInfoBuilder.append("\n");
16903        memInfoBuilder.append("  Lost RAM: ");
16904        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16905                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16906                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16907        memInfoBuilder.append("\n");
16908        Slog.i(TAG, "Low on memory:");
16909        Slog.i(TAG, shortNativeBuilder.toString());
16910        Slog.i(TAG, fullJavaBuilder.toString());
16911        Slog.i(TAG, memInfoBuilder.toString());
16912
16913        StringBuilder dropBuilder = new StringBuilder(1024);
16914        /*
16915        StringWriter oomSw = new StringWriter();
16916        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16917        StringWriter catSw = new StringWriter();
16918        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16919        String[] emptyArgs = new String[] { };
16920        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16921        oomPw.flush();
16922        String oomString = oomSw.toString();
16923        */
16924        dropBuilder.append("Low on memory:");
16925        dropBuilder.append(stack);
16926        dropBuilder.append('\n');
16927        dropBuilder.append(fullNativeBuilder);
16928        dropBuilder.append(fullJavaBuilder);
16929        dropBuilder.append('\n');
16930        dropBuilder.append(memInfoBuilder);
16931        dropBuilder.append('\n');
16932        /*
16933        dropBuilder.append(oomString);
16934        dropBuilder.append('\n');
16935        */
16936        StringWriter catSw = new StringWriter();
16937        synchronized (ActivityManagerService.this) {
16938            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16939            String[] emptyArgs = new String[] { };
16940            catPw.println();
16941            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16942            catPw.println();
16943            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16944                    false, null).dumpLocked();
16945            catPw.println();
16946            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16947            catPw.flush();
16948        }
16949        dropBuilder.append(catSw.toString());
16950        addErrorToDropBox("lowmem", null, "system_server", null,
16951                null, tag.toString(), dropBuilder.toString(), null, null);
16952        //Slog.i(TAG, "Sent to dropbox:");
16953        //Slog.i(TAG, dropBuilder.toString());
16954        synchronized (ActivityManagerService.this) {
16955            long now = SystemClock.uptimeMillis();
16956            if (mLastMemUsageReportTime < now) {
16957                mLastMemUsageReportTime = now;
16958            }
16959        }
16960    }
16961
16962    /**
16963     * Searches array of arguments for the specified string
16964     * @param args array of argument strings
16965     * @param value value to search for
16966     * @return true if the value is contained in the array
16967     */
16968    private static boolean scanArgs(String[] args, String value) {
16969        if (args != null) {
16970            for (String arg : args) {
16971                if (value.equals(arg)) {
16972                    return true;
16973                }
16974            }
16975        }
16976        return false;
16977    }
16978
16979    private final boolean removeDyingProviderLocked(ProcessRecord proc,
16980            ContentProviderRecord cpr, boolean always) {
16981        final boolean inLaunching = mLaunchingProviders.contains(cpr);
16982
16983        if (!inLaunching || always) {
16984            synchronized (cpr) {
16985                cpr.launchingApp = null;
16986                cpr.notifyAll();
16987            }
16988            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16989            String names[] = cpr.info.authority.split(";");
16990            for (int j = 0; j < names.length; j++) {
16991                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16992            }
16993        }
16994
16995        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16996            ContentProviderConnection conn = cpr.connections.get(i);
16997            if (conn.waiting) {
16998                // If this connection is waiting for the provider, then we don't
16999                // need to mess with its process unless we are always removing
17000                // or for some reason the provider is not currently launching.
17001                if (inLaunching && !always) {
17002                    continue;
17003                }
17004            }
17005            ProcessRecord capp = conn.client;
17006            conn.dead = true;
17007            if (conn.stableCount > 0) {
17008                if (!capp.persistent && capp.thread != null
17009                        && capp.pid != 0
17010                        && capp.pid != MY_PID) {
17011                    capp.kill("depends on provider "
17012                            + cpr.name.flattenToShortString()
17013                            + " in dying proc " + (proc != null ? proc.processName : "??")
17014                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17015                }
17016            } else if (capp.thread != null && conn.provider.provider != null) {
17017                try {
17018                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17019                } catch (RemoteException e) {
17020                }
17021                // In the protocol here, we don't expect the client to correctly
17022                // clean up this connection, we'll just remove it.
17023                cpr.connections.remove(i);
17024                if (conn.client.conProviders.remove(conn)) {
17025                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17026                }
17027            }
17028        }
17029
17030        if (inLaunching && always) {
17031            mLaunchingProviders.remove(cpr);
17032        }
17033        return inLaunching;
17034    }
17035
17036    /**
17037     * Main code for cleaning up a process when it has gone away.  This is
17038     * called both as a result of the process dying, or directly when stopping
17039     * a process when running in single process mode.
17040     *
17041     * @return Returns true if the given process has been restarted, so the
17042     * app that was passed in must remain on the process lists.
17043     */
17044    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17045            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17046        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
17047        if (index >= 0) {
17048            removeLruProcessLocked(app);
17049            ProcessList.remove(app.pid);
17050        }
17051
17052        mProcessesToGc.remove(app);
17053        mPendingPssProcesses.remove(app);
17054
17055        // Dismiss any open dialogs.
17056        if (app.crashDialog != null && !app.forceCrashReport) {
17057            app.crashDialog.dismiss();
17058            app.crashDialog = null;
17059        }
17060        if (app.anrDialog != null) {
17061            app.anrDialog.dismiss();
17062            app.anrDialog = null;
17063        }
17064        if (app.waitDialog != null) {
17065            app.waitDialog.dismiss();
17066            app.waitDialog = null;
17067        }
17068
17069        app.crashing = false;
17070        app.notResponding = false;
17071
17072        app.resetPackageList(mProcessStats);
17073        app.unlinkDeathRecipient();
17074        app.makeInactive(mProcessStats);
17075        app.waitingToKill = null;
17076        app.forcingToForeground = null;
17077        updateProcessForegroundLocked(app, false, false);
17078        app.foregroundActivities = false;
17079        app.hasShownUi = false;
17080        app.treatLikeActivity = false;
17081        app.hasAboveClient = false;
17082        app.hasClientActivities = false;
17083
17084        mServices.killServicesLocked(app, allowRestart);
17085
17086        boolean restart = false;
17087
17088        // Remove published content providers.
17089        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17090            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17091            final boolean always = app.bad || !allowRestart;
17092            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17093            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17094                // We left the provider in the launching list, need to
17095                // restart it.
17096                restart = true;
17097            }
17098
17099            cpr.provider = null;
17100            cpr.proc = null;
17101        }
17102        app.pubProviders.clear();
17103
17104        // Take care of any launching providers waiting for this process.
17105        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17106            restart = true;
17107        }
17108
17109        // Unregister from connected content providers.
17110        if (!app.conProviders.isEmpty()) {
17111            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17112                ContentProviderConnection conn = app.conProviders.get(i);
17113                conn.provider.connections.remove(conn);
17114                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17115                        conn.provider.name);
17116            }
17117            app.conProviders.clear();
17118        }
17119
17120        // At this point there may be remaining entries in mLaunchingProviders
17121        // where we were the only one waiting, so they are no longer of use.
17122        // Look for these and clean up if found.
17123        // XXX Commented out for now.  Trying to figure out a way to reproduce
17124        // the actual situation to identify what is actually going on.
17125        if (false) {
17126            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17127                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17128                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17129                    synchronized (cpr) {
17130                        cpr.launchingApp = null;
17131                        cpr.notifyAll();
17132                    }
17133                }
17134            }
17135        }
17136
17137        skipCurrentReceiverLocked(app);
17138
17139        // Unregister any receivers.
17140        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17141            removeReceiverLocked(app.receivers.valueAt(i));
17142        }
17143        app.receivers.clear();
17144
17145        // If the app is undergoing backup, tell the backup manager about it
17146        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17147            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17148                    + mBackupTarget.appInfo + " died during backup");
17149            mHandler.post(new Runnable() {
17150                @Override
17151                public void run(){
17152                    try {
17153                        IBackupManager bm = IBackupManager.Stub.asInterface(
17154                                ServiceManager.getService(Context.BACKUP_SERVICE));
17155                        bm.agentDisconnected(app.info.packageName);
17156                    } catch (RemoteException e) {
17157                        // can't happen; backup manager is local
17158                    }
17159                }
17160            });
17161        }
17162
17163        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17164            ProcessChangeItem item = mPendingProcessChanges.get(i);
17165            if (item.pid == app.pid) {
17166                mPendingProcessChanges.remove(i);
17167                mAvailProcessChanges.add(item);
17168            }
17169        }
17170        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17171                null).sendToTarget();
17172
17173        // If the caller is restarting this app, then leave it in its
17174        // current lists and let the caller take care of it.
17175        if (restarting) {
17176            return false;
17177        }
17178
17179        if (!app.persistent || app.isolated) {
17180            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17181                    "Removing non-persistent process during cleanup: " + app);
17182            if (!replacingPid) {
17183                removeProcessNameLocked(app.processName, app.uid, app);
17184            }
17185            if (mHeavyWeightProcess == app) {
17186                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17187                        mHeavyWeightProcess.userId, 0));
17188                mHeavyWeightProcess = null;
17189            }
17190        } else if (!app.removed) {
17191            // This app is persistent, so we need to keep its record around.
17192            // If it is not already on the pending app list, add it there
17193            // and start a new process for it.
17194            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17195                mPersistentStartingProcesses.add(app);
17196                restart = true;
17197            }
17198        }
17199        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17200                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17201        mProcessesOnHold.remove(app);
17202
17203        if (app == mHomeProcess) {
17204            mHomeProcess = null;
17205        }
17206        if (app == mPreviousProcess) {
17207            mPreviousProcess = null;
17208        }
17209
17210        if (restart && !app.isolated) {
17211            // We have components that still need to be running in the
17212            // process, so re-launch it.
17213            if (index < 0) {
17214                ProcessList.remove(app.pid);
17215            }
17216            addProcessNameLocked(app);
17217            startProcessLocked(app, "restart", app.processName);
17218            return true;
17219        } else if (app.pid > 0 && app.pid != MY_PID) {
17220            // Goodbye!
17221            boolean removed;
17222            synchronized (mPidsSelfLocked) {
17223                mPidsSelfLocked.remove(app.pid);
17224                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17225            }
17226            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17227            if (app.isolated) {
17228                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17229            }
17230            app.setPid(0);
17231        }
17232        return false;
17233    }
17234
17235    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17236        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17237            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17238            if (cpr.launchingApp == app) {
17239                return true;
17240            }
17241        }
17242        return false;
17243    }
17244
17245    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17246        // Look through the content providers we are waiting to have launched,
17247        // and if any run in this process then either schedule a restart of
17248        // the process or kill the client waiting for it if this process has
17249        // gone bad.
17250        boolean restart = false;
17251        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17252            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17253            if (cpr.launchingApp == app) {
17254                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17255                    restart = true;
17256                } else {
17257                    removeDyingProviderLocked(app, cpr, true);
17258                }
17259            }
17260        }
17261        return restart;
17262    }
17263
17264    // =========================================================
17265    // SERVICES
17266    // =========================================================
17267
17268    @Override
17269    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17270            int flags) {
17271        enforceNotIsolatedCaller("getServices");
17272        synchronized (this) {
17273            return mServices.getRunningServiceInfoLocked(maxNum, flags);
17274        }
17275    }
17276
17277    @Override
17278    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17279        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17280        synchronized (this) {
17281            return mServices.getRunningServiceControlPanelLocked(name);
17282        }
17283    }
17284
17285    @Override
17286    public ComponentName startService(IApplicationThread caller, Intent service,
17287            String resolvedType, String callingPackage, int userId)
17288            throws TransactionTooLargeException {
17289        enforceNotIsolatedCaller("startService");
17290        // Refuse possible leaked file descriptors
17291        if (service != null && service.hasFileDescriptors() == true) {
17292            throw new IllegalArgumentException("File descriptors passed in Intent");
17293        }
17294
17295        if (callingPackage == null) {
17296            throw new IllegalArgumentException("callingPackage cannot be null");
17297        }
17298
17299        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17300                "startService: " + service + " type=" + resolvedType);
17301        synchronized(this) {
17302            final int callingPid = Binder.getCallingPid();
17303            final int callingUid = Binder.getCallingUid();
17304            final long origId = Binder.clearCallingIdentity();
17305            ComponentName res = mServices.startServiceLocked(caller, service,
17306                    resolvedType, callingPid, callingUid, callingPackage, userId);
17307            Binder.restoreCallingIdentity(origId);
17308            return res;
17309        }
17310    }
17311
17312    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17313            String callingPackage, int userId)
17314            throws TransactionTooLargeException {
17315        synchronized(this) {
17316            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17317                    "startServiceInPackage: " + service + " type=" + resolvedType);
17318            final long origId = Binder.clearCallingIdentity();
17319            ComponentName res = mServices.startServiceLocked(null, service,
17320                    resolvedType, -1, uid, callingPackage, userId);
17321            Binder.restoreCallingIdentity(origId);
17322            return res;
17323        }
17324    }
17325
17326    @Override
17327    public int stopService(IApplicationThread caller, Intent service,
17328            String resolvedType, int userId) {
17329        enforceNotIsolatedCaller("stopService");
17330        // Refuse possible leaked file descriptors
17331        if (service != null && service.hasFileDescriptors() == true) {
17332            throw new IllegalArgumentException("File descriptors passed in Intent");
17333        }
17334
17335        synchronized(this) {
17336            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17337        }
17338    }
17339
17340    @Override
17341    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17342        enforceNotIsolatedCaller("peekService");
17343        // Refuse possible leaked file descriptors
17344        if (service != null && service.hasFileDescriptors() == true) {
17345            throw new IllegalArgumentException("File descriptors passed in Intent");
17346        }
17347
17348        if (callingPackage == null) {
17349            throw new IllegalArgumentException("callingPackage cannot be null");
17350        }
17351
17352        synchronized(this) {
17353            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17354        }
17355    }
17356
17357    @Override
17358    public boolean stopServiceToken(ComponentName className, IBinder token,
17359            int startId) {
17360        synchronized(this) {
17361            return mServices.stopServiceTokenLocked(className, token, startId);
17362        }
17363    }
17364
17365    @Override
17366    public void setServiceForeground(ComponentName className, IBinder token,
17367            int id, Notification notification, int flags) {
17368        synchronized(this) {
17369            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17370        }
17371    }
17372
17373    @Override
17374    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17375            boolean requireFull, String name, String callerPackage) {
17376        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17377                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17378    }
17379
17380    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17381            String className, int flags) {
17382        boolean result = false;
17383        // For apps that don't have pre-defined UIDs, check for permission
17384        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17385            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17386                if (ActivityManager.checkUidPermission(
17387                        INTERACT_ACROSS_USERS,
17388                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17389                    ComponentName comp = new ComponentName(aInfo.packageName, className);
17390                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
17391                            + " requests FLAG_SINGLE_USER, but app does not hold "
17392                            + INTERACT_ACROSS_USERS;
17393                    Slog.w(TAG, msg);
17394                    throw new SecurityException(msg);
17395                }
17396                // Permission passed
17397                result = true;
17398            }
17399        } else if ("system".equals(componentProcessName)) {
17400            result = true;
17401        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17402            // Phone app and persistent apps are allowed to export singleuser providers.
17403            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17404                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17405        }
17406        if (DEBUG_MU) Slog.v(TAG_MU,
17407                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17408                + Integer.toHexString(flags) + ") = " + result);
17409        return result;
17410    }
17411
17412    /**
17413     * Checks to see if the caller is in the same app as the singleton
17414     * component, or the component is in a special app. It allows special apps
17415     * to export singleton components but prevents exporting singleton
17416     * components for regular apps.
17417     */
17418    boolean isValidSingletonCall(int callingUid, int componentUid) {
17419        int componentAppId = UserHandle.getAppId(componentUid);
17420        return UserHandle.isSameApp(callingUid, componentUid)
17421                || componentAppId == Process.SYSTEM_UID
17422                || componentAppId == Process.PHONE_UID
17423                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17424                        == PackageManager.PERMISSION_GRANTED;
17425    }
17426
17427    public int bindService(IApplicationThread caller, IBinder token, Intent service,
17428            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17429            int userId) throws TransactionTooLargeException {
17430        enforceNotIsolatedCaller("bindService");
17431
17432        // Refuse possible leaked file descriptors
17433        if (service != null && service.hasFileDescriptors() == true) {
17434            throw new IllegalArgumentException("File descriptors passed in Intent");
17435        }
17436
17437        if (callingPackage == null) {
17438            throw new IllegalArgumentException("callingPackage cannot be null");
17439        }
17440
17441        synchronized(this) {
17442            return mServices.bindServiceLocked(caller, token, service,
17443                    resolvedType, connection, flags, callingPackage, userId);
17444        }
17445    }
17446
17447    public boolean unbindService(IServiceConnection connection) {
17448        synchronized (this) {
17449            return mServices.unbindServiceLocked(connection);
17450        }
17451    }
17452
17453    public void publishService(IBinder token, Intent intent, IBinder service) {
17454        // Refuse possible leaked file descriptors
17455        if (intent != null && intent.hasFileDescriptors() == true) {
17456            throw new IllegalArgumentException("File descriptors passed in Intent");
17457        }
17458
17459        synchronized(this) {
17460            if (!(token instanceof ServiceRecord)) {
17461                throw new IllegalArgumentException("Invalid service token");
17462            }
17463            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17464        }
17465    }
17466
17467    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17468        // Refuse possible leaked file descriptors
17469        if (intent != null && intent.hasFileDescriptors() == true) {
17470            throw new IllegalArgumentException("File descriptors passed in Intent");
17471        }
17472
17473        synchronized(this) {
17474            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17475        }
17476    }
17477
17478    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17479        synchronized(this) {
17480            if (!(token instanceof ServiceRecord)) {
17481                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17482                throw new IllegalArgumentException("Invalid service token");
17483            }
17484            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17485        }
17486    }
17487
17488    // =========================================================
17489    // BACKUP AND RESTORE
17490    // =========================================================
17491
17492    // Cause the target app to be launched if necessary and its backup agent
17493    // instantiated.  The backup agent will invoke backupAgentCreated() on the
17494    // activity manager to announce its creation.
17495    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17496        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17497        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17498
17499        IPackageManager pm = AppGlobals.getPackageManager();
17500        ApplicationInfo app = null;
17501        try {
17502            app = pm.getApplicationInfo(packageName, 0, userId);
17503        } catch (RemoteException e) {
17504            // can't happen; package manager is process-local
17505        }
17506        if (app == null) {
17507            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17508            return false;
17509        }
17510
17511        synchronized(this) {
17512            // !!! TODO: currently no check here that we're already bound
17513            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17514            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17515            synchronized (stats) {
17516                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17517            }
17518
17519            // Backup agent is now in use, its package can't be stopped.
17520            try {
17521                AppGlobals.getPackageManager().setPackageStoppedState(
17522                        app.packageName, false, UserHandle.getUserId(app.uid));
17523            } catch (RemoteException e) {
17524            } catch (IllegalArgumentException e) {
17525                Slog.w(TAG, "Failed trying to unstop package "
17526                        + app.packageName + ": " + e);
17527            }
17528
17529            BackupRecord r = new BackupRecord(ss, app, backupMode);
17530            ComponentName hostingName =
17531                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
17532                            ? new ComponentName(app.packageName, app.backupAgentName)
17533                            : new ComponentName("android", "FullBackupAgent");
17534            // startProcessLocked() returns existing proc's record if it's already running
17535            ProcessRecord proc = startProcessLocked(app.processName, app,
17536                    false, 0, "backup", hostingName, false, false, false);
17537            if (proc == null) {
17538                Slog.e(TAG, "Unable to start backup agent process " + r);
17539                return false;
17540            }
17541
17542            // If the app is a regular app (uid >= 10000) and not the system server or phone
17543            // process, etc, then mark it as being in full backup so that certain calls to the
17544            // process can be blocked. This is not reset to false anywhere because we kill the
17545            // process after the full backup is done and the ProcessRecord will vaporize anyway.
17546            if (UserHandle.isApp(app.uid) &&
17547                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
17548                proc.inFullBackup = true;
17549            }
17550            r.app = proc;
17551            mBackupTarget = r;
17552            mBackupAppName = app.packageName;
17553
17554            // Try not to kill the process during backup
17555            updateOomAdjLocked(proc);
17556
17557            // If the process is already attached, schedule the creation of the backup agent now.
17558            // If it is not yet live, this will be done when it attaches to the framework.
17559            if (proc.thread != null) {
17560                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17561                try {
17562                    proc.thread.scheduleCreateBackupAgent(app,
17563                            compatibilityInfoForPackageLocked(app), backupMode);
17564                } catch (RemoteException e) {
17565                    // Will time out on the backup manager side
17566                }
17567            } else {
17568                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17569            }
17570            // Invariants: at this point, the target app process exists and the application
17571            // is either already running or in the process of coming up.  mBackupTarget and
17572            // mBackupAppName describe the app, so that when it binds back to the AM we
17573            // know that it's scheduled for a backup-agent operation.
17574        }
17575
17576        return true;
17577    }
17578
17579    @Override
17580    public void clearPendingBackup() {
17581        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17582        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17583
17584        synchronized (this) {
17585            mBackupTarget = null;
17586            mBackupAppName = null;
17587        }
17588    }
17589
17590    // A backup agent has just come up
17591    public void backupAgentCreated(String agentPackageName, IBinder agent) {
17592        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17593                + " = " + agent);
17594
17595        synchronized(this) {
17596            if (!agentPackageName.equals(mBackupAppName)) {
17597                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17598                return;
17599            }
17600        }
17601
17602        long oldIdent = Binder.clearCallingIdentity();
17603        try {
17604            IBackupManager bm = IBackupManager.Stub.asInterface(
17605                    ServiceManager.getService(Context.BACKUP_SERVICE));
17606            bm.agentConnected(agentPackageName, agent);
17607        } catch (RemoteException e) {
17608            // can't happen; the backup manager service is local
17609        } catch (Exception e) {
17610            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17611            e.printStackTrace();
17612        } finally {
17613            Binder.restoreCallingIdentity(oldIdent);
17614        }
17615    }
17616
17617    // done with this agent
17618    public void unbindBackupAgent(ApplicationInfo appInfo) {
17619        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17620        if (appInfo == null) {
17621            Slog.w(TAG, "unbind backup agent for null app");
17622            return;
17623        }
17624
17625        synchronized(this) {
17626            try {
17627                if (mBackupAppName == null) {
17628                    Slog.w(TAG, "Unbinding backup agent with no active backup");
17629                    return;
17630                }
17631
17632                if (!mBackupAppName.equals(appInfo.packageName)) {
17633                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17634                    return;
17635                }
17636
17637                // Not backing this app up any more; reset its OOM adjustment
17638                final ProcessRecord proc = mBackupTarget.app;
17639                updateOomAdjLocked(proc);
17640
17641                // If the app crashed during backup, 'thread' will be null here
17642                if (proc.thread != null) {
17643                    try {
17644                        proc.thread.scheduleDestroyBackupAgent(appInfo,
17645                                compatibilityInfoForPackageLocked(appInfo));
17646                    } catch (Exception e) {
17647                        Slog.e(TAG, "Exception when unbinding backup agent:");
17648                        e.printStackTrace();
17649                    }
17650                }
17651            } finally {
17652                mBackupTarget = null;
17653                mBackupAppName = null;
17654            }
17655        }
17656    }
17657    // =========================================================
17658    // BROADCASTS
17659    // =========================================================
17660
17661    boolean isPendingBroadcastProcessLocked(int pid) {
17662        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17663                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17664    }
17665
17666    void skipPendingBroadcastLocked(int pid) {
17667            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17668            for (BroadcastQueue queue : mBroadcastQueues) {
17669                queue.skipPendingBroadcastLocked(pid);
17670            }
17671    }
17672
17673    // The app just attached; send any pending broadcasts that it should receive
17674    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17675        boolean didSomething = false;
17676        for (BroadcastQueue queue : mBroadcastQueues) {
17677            didSomething |= queue.sendPendingBroadcastsLocked(app);
17678        }
17679        return didSomething;
17680    }
17681
17682    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17683            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17684        enforceNotIsolatedCaller("registerReceiver");
17685        ArrayList<Intent> stickyIntents = null;
17686        ProcessRecord callerApp = null;
17687        int callingUid;
17688        int callingPid;
17689        synchronized(this) {
17690            if (caller != null) {
17691                callerApp = getRecordForAppLocked(caller);
17692                if (callerApp == null) {
17693                    throw new SecurityException(
17694                            "Unable to find app for caller " + caller
17695                            + " (pid=" + Binder.getCallingPid()
17696                            + ") when registering receiver " + receiver);
17697                }
17698                if (callerApp.info.uid != Process.SYSTEM_UID &&
17699                        !callerApp.pkgList.containsKey(callerPackage) &&
17700                        !"android".equals(callerPackage)) {
17701                    throw new SecurityException("Given caller package " + callerPackage
17702                            + " is not running in process " + callerApp);
17703                }
17704                callingUid = callerApp.info.uid;
17705                callingPid = callerApp.pid;
17706            } else {
17707                callerPackage = null;
17708                callingUid = Binder.getCallingUid();
17709                callingPid = Binder.getCallingPid();
17710            }
17711
17712            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17713                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17714
17715            Iterator<String> actions = filter.actionsIterator();
17716            if (actions == null) {
17717                ArrayList<String> noAction = new ArrayList<String>(1);
17718                noAction.add(null);
17719                actions = noAction.iterator();
17720            }
17721
17722            // Collect stickies of users
17723            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17724            while (actions.hasNext()) {
17725                String action = actions.next();
17726                for (int id : userIds) {
17727                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17728                    if (stickies != null) {
17729                        ArrayList<Intent> intents = stickies.get(action);
17730                        if (intents != null) {
17731                            if (stickyIntents == null) {
17732                                stickyIntents = new ArrayList<Intent>();
17733                            }
17734                            stickyIntents.addAll(intents);
17735                        }
17736                    }
17737                }
17738            }
17739        }
17740
17741        ArrayList<Intent> allSticky = null;
17742        if (stickyIntents != null) {
17743            final ContentResolver resolver = mContext.getContentResolver();
17744            // Look for any matching sticky broadcasts...
17745            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17746                Intent intent = stickyIntents.get(i);
17747                // If intent has scheme "content", it will need to acccess
17748                // provider that needs to lock mProviderMap in ActivityThread
17749                // and also it may need to wait application response, so we
17750                // cannot lock ActivityManagerService here.
17751                if (filter.match(resolver, intent, true, TAG) >= 0) {
17752                    if (allSticky == null) {
17753                        allSticky = new ArrayList<Intent>();
17754                    }
17755                    allSticky.add(intent);
17756                }
17757            }
17758        }
17759
17760        // The first sticky in the list is returned directly back to the client.
17761        Intent sticky = allSticky != null ? allSticky.get(0) : null;
17762        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17763        if (receiver == null) {
17764            return sticky;
17765        }
17766
17767        synchronized (this) {
17768            if (callerApp != null && (callerApp.thread == null
17769                    || callerApp.thread.asBinder() != caller.asBinder())) {
17770                // Original caller already died
17771                return null;
17772            }
17773            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17774            if (rl == null) {
17775                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17776                        userId, receiver);
17777                if (rl.app != null) {
17778                    rl.app.receivers.add(rl);
17779                } else {
17780                    try {
17781                        receiver.asBinder().linkToDeath(rl, 0);
17782                    } catch (RemoteException e) {
17783                        return sticky;
17784                    }
17785                    rl.linkedToDeath = true;
17786                }
17787                mRegisteredReceivers.put(receiver.asBinder(), rl);
17788            } else if (rl.uid != callingUid) {
17789                throw new IllegalArgumentException(
17790                        "Receiver requested to register for uid " + callingUid
17791                        + " was previously registered for uid " + rl.uid);
17792            } else if (rl.pid != callingPid) {
17793                throw new IllegalArgumentException(
17794                        "Receiver requested to register for pid " + callingPid
17795                        + " was previously registered for pid " + rl.pid);
17796            } else if (rl.userId != userId) {
17797                throw new IllegalArgumentException(
17798                        "Receiver requested to register for user " + userId
17799                        + " was previously registered for user " + rl.userId);
17800            }
17801            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17802                    permission, callingUid, userId);
17803            rl.add(bf);
17804            if (!bf.debugCheck()) {
17805                Slog.w(TAG, "==> For Dynamic broadcast");
17806            }
17807            mReceiverResolver.addFilter(bf);
17808
17809            // Enqueue broadcasts for all existing stickies that match
17810            // this filter.
17811            if (allSticky != null) {
17812                ArrayList receivers = new ArrayList();
17813                receivers.add(bf);
17814
17815                final int stickyCount = allSticky.size();
17816                for (int i = 0; i < stickyCount; i++) {
17817                    Intent intent = allSticky.get(i);
17818                    BroadcastQueue queue = broadcastQueueForIntent(intent);
17819                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17820                            null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17821                            null, 0, null, null, false, true, true, -1);
17822                    queue.enqueueParallelBroadcastLocked(r);
17823                    queue.scheduleBroadcastsLocked();
17824                }
17825            }
17826
17827            return sticky;
17828        }
17829    }
17830
17831    public void unregisterReceiver(IIntentReceiver receiver) {
17832        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17833
17834        final long origId = Binder.clearCallingIdentity();
17835        try {
17836            boolean doTrim = false;
17837
17838            synchronized(this) {
17839                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17840                if (rl != null) {
17841                    final BroadcastRecord r = rl.curBroadcast;
17842                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17843                        final boolean doNext = r.queue.finishReceiverLocked(
17844                                r, r.resultCode, r.resultData, r.resultExtras,
17845                                r.resultAbort, false);
17846                        if (doNext) {
17847                            doTrim = true;
17848                            r.queue.processNextBroadcast(false);
17849                        }
17850                    }
17851
17852                    if (rl.app != null) {
17853                        rl.app.receivers.remove(rl);
17854                    }
17855                    removeReceiverLocked(rl);
17856                    if (rl.linkedToDeath) {
17857                        rl.linkedToDeath = false;
17858                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
17859                    }
17860                }
17861            }
17862
17863            // If we actually concluded any broadcasts, we might now be able
17864            // to trim the recipients' apps from our working set
17865            if (doTrim) {
17866                trimApplications();
17867                return;
17868            }
17869
17870        } finally {
17871            Binder.restoreCallingIdentity(origId);
17872        }
17873    }
17874
17875    void removeReceiverLocked(ReceiverList rl) {
17876        mRegisteredReceivers.remove(rl.receiver.asBinder());
17877        for (int i = rl.size() - 1; i >= 0; i--) {
17878            mReceiverResolver.removeFilter(rl.get(i));
17879        }
17880    }
17881
17882    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17883        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17884            ProcessRecord r = mLruProcesses.get(i);
17885            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17886                try {
17887                    r.thread.dispatchPackageBroadcast(cmd, packages);
17888                } catch (RemoteException ex) {
17889                }
17890            }
17891        }
17892    }
17893
17894    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17895            int callingUid, int[] users) {
17896        // TODO: come back and remove this assumption to triage all broadcasts
17897        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17898
17899        List<ResolveInfo> receivers = null;
17900        try {
17901            HashSet<ComponentName> singleUserReceivers = null;
17902            boolean scannedFirstReceivers = false;
17903            for (int user : users) {
17904                // Skip users that have Shell restrictions, with exception of always permitted
17905                // Shell broadcasts
17906                if (callingUid == Process.SHELL_UID
17907                        && mUserController.hasUserRestriction(
17908                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17909                        && !isPermittedShellBroadcast(intent)) {
17910                    continue;
17911                }
17912                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17913                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17914                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17915                    // If this is not the system user, we need to check for
17916                    // any receivers that should be filtered out.
17917                    for (int i=0; i<newReceivers.size(); i++) {
17918                        ResolveInfo ri = newReceivers.get(i);
17919                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17920                            newReceivers.remove(i);
17921                            i--;
17922                        }
17923                    }
17924                }
17925                if (newReceivers != null && newReceivers.size() == 0) {
17926                    newReceivers = null;
17927                }
17928                if (receivers == null) {
17929                    receivers = newReceivers;
17930                } else if (newReceivers != null) {
17931                    // We need to concatenate the additional receivers
17932                    // found with what we have do far.  This would be easy,
17933                    // but we also need to de-dup any receivers that are
17934                    // singleUser.
17935                    if (!scannedFirstReceivers) {
17936                        // Collect any single user receivers we had already retrieved.
17937                        scannedFirstReceivers = true;
17938                        for (int i=0; i<receivers.size(); i++) {
17939                            ResolveInfo ri = receivers.get(i);
17940                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17941                                ComponentName cn = new ComponentName(
17942                                        ri.activityInfo.packageName, ri.activityInfo.name);
17943                                if (singleUserReceivers == null) {
17944                                    singleUserReceivers = new HashSet<ComponentName>();
17945                                }
17946                                singleUserReceivers.add(cn);
17947                            }
17948                        }
17949                    }
17950                    // Add the new results to the existing results, tracking
17951                    // and de-dupping single user receivers.
17952                    for (int i=0; i<newReceivers.size(); i++) {
17953                        ResolveInfo ri = newReceivers.get(i);
17954                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17955                            ComponentName cn = new ComponentName(
17956                                    ri.activityInfo.packageName, ri.activityInfo.name);
17957                            if (singleUserReceivers == null) {
17958                                singleUserReceivers = new HashSet<ComponentName>();
17959                            }
17960                            if (!singleUserReceivers.contains(cn)) {
17961                                singleUserReceivers.add(cn);
17962                                receivers.add(ri);
17963                            }
17964                        } else {
17965                            receivers.add(ri);
17966                        }
17967                    }
17968                }
17969            }
17970        } catch (RemoteException ex) {
17971            // pm is in same process, this will never happen.
17972        }
17973        return receivers;
17974    }
17975
17976    private boolean isPermittedShellBroadcast(Intent intent) {
17977        // remote bugreport should always be allowed to be taken
17978        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17979    }
17980
17981    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17982            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17983        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
17984            // Don't yell about broadcasts sent via shell
17985            return;
17986        }
17987
17988        final String action = intent.getAction();
17989        if (isProtectedBroadcast
17990                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17991                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17992                || Intent.ACTION_MEDIA_BUTTON.equals(action)
17993                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17994                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17995                || Intent.ACTION_MASTER_CLEAR.equals(action)
17996                || Intent.ACTION_FACTORY_RESET.equals(action)
17997                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17998                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17999                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18000                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18001                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
18002            // Broadcast is either protected, or it's a public action that
18003            // we've relaxed, so it's fine for system internals to send.
18004            return;
18005        }
18006
18007        // This broadcast may be a problem...  but there are often system components that
18008        // want to send an internal broadcast to themselves, which is annoying to have to
18009        // explicitly list each action as a protected broadcast, so we will check for that
18010        // one safe case and allow it: an explicit broadcast, only being received by something
18011        // that has protected itself.
18012        if (receivers != null && receivers.size() > 0
18013                && (intent.getPackage() != null || intent.getComponent() != null)) {
18014            boolean allProtected = true;
18015            for (int i = receivers.size()-1; i >= 0; i--) {
18016                Object target = receivers.get(i);
18017                if (target instanceof ResolveInfo) {
18018                    ResolveInfo ri = (ResolveInfo)target;
18019                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18020                        allProtected = false;
18021                        break;
18022                    }
18023                } else {
18024                    BroadcastFilter bf = (BroadcastFilter)target;
18025                    if (bf.requiredPermission == null) {
18026                        allProtected = false;
18027                        break;
18028                    }
18029                }
18030            }
18031            if (allProtected) {
18032                // All safe!
18033                return;
18034            }
18035        }
18036
18037        // The vast majority of broadcasts sent from system internals
18038        // should be protected to avoid security holes, so yell loudly
18039        // to ensure we examine these cases.
18040        if (callerApp != null) {
18041            Log.wtf(TAG, "Sending non-protected broadcast " + action
18042                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
18043                    new Throwable());
18044        } else {
18045            Log.wtf(TAG, "Sending non-protected broadcast " + action
18046                            + " from system uid " + UserHandle.formatUid(callingUid)
18047                            + " pkg " + callerPackage,
18048                    new Throwable());
18049        }
18050    }
18051
18052    final int broadcastIntentLocked(ProcessRecord callerApp,
18053            String callerPackage, Intent intent, String resolvedType,
18054            IIntentReceiver resultTo, int resultCode, String resultData,
18055            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
18056            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
18057        intent = new Intent(intent);
18058
18059        // By default broadcasts do not go to stopped apps.
18060        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
18061
18062        // If we have not finished booting, don't allow this to launch new processes.
18063        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
18064            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18065        }
18066
18067        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
18068                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
18069                + " ordered=" + ordered + " userid=" + userId);
18070        if ((resultTo != null) && !ordered) {
18071            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
18072        }
18073
18074        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18075                ALLOW_NON_FULL, "broadcast", callerPackage);
18076
18077        // Make sure that the user who is receiving this broadcast is running.
18078        // If not, we will just skip it. Make an exception for shutdown broadcasts
18079        // and upgrade steps.
18080
18081        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
18082            if ((callingUid != Process.SYSTEM_UID
18083                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
18084                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
18085                Slog.w(TAG, "Skipping broadcast of " + intent
18086                        + ": user " + userId + " is stopped");
18087                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
18088            }
18089        }
18090
18091        BroadcastOptions brOptions = null;
18092        if (bOptions != null) {
18093            brOptions = new BroadcastOptions(bOptions);
18094            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
18095                // See if the caller is allowed to do this.  Note we are checking against
18096                // the actual real caller (not whoever provided the operation as say a
18097                // PendingIntent), because that who is actually supplied the arguments.
18098                if (checkComponentPermission(
18099                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
18100                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
18101                        != PackageManager.PERMISSION_GRANTED) {
18102                    String msg = "Permission Denial: " + intent.getAction()
18103                            + " broadcast from " + callerPackage + " (pid=" + callingPid
18104                            + ", uid=" + callingUid + ")"
18105                            + " requires "
18106                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
18107                    Slog.w(TAG, msg);
18108                    throw new SecurityException(msg);
18109                }
18110            }
18111        }
18112
18113        // Verify that protected broadcasts are only being sent by system code,
18114        // and that system code is only sending protected broadcasts.
18115        final String action = intent.getAction();
18116        final boolean isProtectedBroadcast;
18117        try {
18118            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18119        } catch (RemoteException e) {
18120            Slog.w(TAG, "Remote exception", e);
18121            return ActivityManager.BROADCAST_SUCCESS;
18122        }
18123
18124        final boolean isCallerSystem;
18125        switch (UserHandle.getAppId(callingUid)) {
18126            case Process.ROOT_UID:
18127            case Process.SYSTEM_UID:
18128            case Process.PHONE_UID:
18129            case Process.BLUETOOTH_UID:
18130            case Process.NFC_UID:
18131                isCallerSystem = true;
18132                break;
18133            default:
18134                isCallerSystem = (callerApp != null) && callerApp.persistent;
18135                break;
18136        }
18137
18138        // First line security check before anything else: stop non-system apps from
18139        // sending protected broadcasts.
18140        if (!isCallerSystem) {
18141            if (isProtectedBroadcast) {
18142                String msg = "Permission Denial: not allowed to send broadcast "
18143                        + action + " from pid="
18144                        + callingPid + ", uid=" + callingUid;
18145                Slog.w(TAG, msg);
18146                throw new SecurityException(msg);
18147
18148            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18149                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18150                // Special case for compatibility: we don't want apps to send this,
18151                // but historically it has not been protected and apps may be using it
18152                // to poke their own app widget.  So, instead of making it protected,
18153                // just limit it to the caller.
18154                if (callerPackage == null) {
18155                    String msg = "Permission Denial: not allowed to send broadcast "
18156                            + action + " from unknown caller.";
18157                    Slog.w(TAG, msg);
18158                    throw new SecurityException(msg);
18159                } else if (intent.getComponent() != null) {
18160                    // They are good enough to send to an explicit component...  verify
18161                    // it is being sent to the calling app.
18162                    if (!intent.getComponent().getPackageName().equals(
18163                            callerPackage)) {
18164                        String msg = "Permission Denial: not allowed to send broadcast "
18165                                + action + " to "
18166                                + intent.getComponent().getPackageName() + " from "
18167                                + callerPackage;
18168                        Slog.w(TAG, msg);
18169                        throw new SecurityException(msg);
18170                    }
18171                } else {
18172                    // Limit broadcast to their own package.
18173                    intent.setPackage(callerPackage);
18174                }
18175            }
18176        }
18177
18178        if (action != null) {
18179            switch (action) {
18180                case Intent.ACTION_UID_REMOVED:
18181                case Intent.ACTION_PACKAGE_REMOVED:
18182                case Intent.ACTION_PACKAGE_CHANGED:
18183                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18184                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18185                case Intent.ACTION_PACKAGES_SUSPENDED:
18186                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18187                    // Handle special intents: if this broadcast is from the package
18188                    // manager about a package being removed, we need to remove all of
18189                    // its activities from the history stack.
18190                    if (checkComponentPermission(
18191                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18192                            callingPid, callingUid, -1, true)
18193                            != PackageManager.PERMISSION_GRANTED) {
18194                        String msg = "Permission Denial: " + intent.getAction()
18195                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18196                                + ", uid=" + callingUid + ")"
18197                                + " requires "
18198                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18199                        Slog.w(TAG, msg);
18200                        throw new SecurityException(msg);
18201                    }
18202                    switch (action) {
18203                        case Intent.ACTION_UID_REMOVED:
18204                            final Bundle intentExtras = intent.getExtras();
18205                            final int uid = intentExtras != null
18206                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18207                            if (uid >= 0) {
18208                                mBatteryStatsService.removeUid(uid);
18209                                mAppOpsService.uidRemoved(uid);
18210                            }
18211                            break;
18212                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18213                            // If resources are unavailable just force stop all those packages
18214                            // and flush the attribute cache as well.
18215                            String list[] =
18216                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18217                            if (list != null && list.length > 0) {
18218                                for (int i = 0; i < list.length; i++) {
18219                                    forceStopPackageLocked(list[i], -1, false, true, true,
18220                                            false, false, userId, "storage unmount");
18221                                }
18222                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18223                                sendPackageBroadcastLocked(
18224                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
18225                                        list, userId);
18226                            }
18227                            break;
18228                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18229                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18230                            break;
18231                        case Intent.ACTION_PACKAGE_REMOVED:
18232                        case Intent.ACTION_PACKAGE_CHANGED:
18233                            Uri data = intent.getData();
18234                            String ssp;
18235                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18236                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18237                                final boolean replacing =
18238                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18239                                final boolean killProcess =
18240                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18241                                final boolean fullUninstall = removed && !replacing;
18242                                if (removed) {
18243                                    if (killProcess) {
18244                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18245                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18246                                                false, true, true, false, fullUninstall, userId,
18247                                                removed ? "pkg removed" : "pkg changed");
18248                                    }
18249                                    final int cmd = killProcess
18250                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18251                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
18252                                    sendPackageBroadcastLocked(cmd,
18253                                            new String[] {ssp}, userId);
18254                                    if (fullUninstall) {
18255                                        mAppOpsService.packageRemoved(
18256                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18257
18258                                        // Remove all permissions granted from/to this package
18259                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18260
18261                                        removeTasksByPackageNameLocked(ssp, userId);
18262
18263                                        // Hide the "unsupported display" dialog if necessary.
18264                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18265                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18266                                            mUnsupportedDisplaySizeDialog.dismiss();
18267                                            mUnsupportedDisplaySizeDialog = null;
18268                                        }
18269                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18270                                        mBatteryStatsService.notePackageUninstalled(ssp);
18271                                    }
18272                                } else {
18273                                    if (killProcess) {
18274                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18275                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18276                                                userId, ProcessList.INVALID_ADJ,
18277                                                false, true, true, false, "change " + ssp);
18278                                    }
18279                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18280                                            intent.getStringArrayExtra(
18281                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18282                                }
18283                            }
18284                            break;
18285                        case Intent.ACTION_PACKAGES_SUSPENDED:
18286                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18287                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18288                                    intent.getAction());
18289                            final String[] packageNames = intent.getStringArrayExtra(
18290                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18291                            final int userHandle = intent.getIntExtra(
18292                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18293
18294                            synchronized(ActivityManagerService.this) {
18295                                mRecentTasks.onPackagesSuspendedChanged(
18296                                        packageNames, suspended, userHandle);
18297                            }
18298                            break;
18299                    }
18300                    break;
18301                case Intent.ACTION_PACKAGE_REPLACED:
18302                {
18303                    final Uri data = intent.getData();
18304                    final String ssp;
18305                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18306                        final ApplicationInfo aInfo =
18307                                getPackageManagerInternalLocked().getApplicationInfo(
18308                                        ssp,
18309                                        userId);
18310                        if (aInfo == null) {
18311                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18312                                    + " ssp=" + ssp + " data=" + data);
18313                            return ActivityManager.BROADCAST_SUCCESS;
18314                        }
18315                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18316                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
18317                                new String[] {ssp}, userId);
18318                    }
18319                    break;
18320                }
18321                case Intent.ACTION_PACKAGE_ADDED:
18322                {
18323                    // Special case for adding a package: by default turn on compatibility mode.
18324                    Uri data = intent.getData();
18325                    String ssp;
18326                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18327                        final boolean replacing =
18328                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18329                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18330
18331                        try {
18332                            ApplicationInfo ai = AppGlobals.getPackageManager().
18333                                    getApplicationInfo(ssp, 0, 0);
18334                            mBatteryStatsService.notePackageInstalled(ssp,
18335                                    ai != null ? ai.versionCode : 0);
18336                        } catch (RemoteException e) {
18337                        }
18338                    }
18339                    break;
18340                }
18341                case Intent.ACTION_PACKAGE_DATA_CLEARED:
18342                {
18343                    Uri data = intent.getData();
18344                    String ssp;
18345                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18346                        // Hide the "unsupported display" dialog if necessary.
18347                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18348                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18349                            mUnsupportedDisplaySizeDialog.dismiss();
18350                            mUnsupportedDisplaySizeDialog = null;
18351                        }
18352                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
18353                    }
18354                    break;
18355                }
18356                case Intent.ACTION_TIMEZONE_CHANGED:
18357                    // If this is the time zone changed action, queue up a message that will reset
18358                    // the timezone of all currently running processes. This message will get
18359                    // queued up before the broadcast happens.
18360                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18361                    break;
18362                case Intent.ACTION_TIME_CHANGED:
18363                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
18364                    // the tri-state value it may contain and "unknown".
18365                    // For convenience we re-use the Intent extra values.
18366                    final int NO_EXTRA_VALUE_FOUND = -1;
18367                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
18368                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
18369                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
18370                    // Only send a message if the time preference is available.
18371                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
18372                        Message updateTimePreferenceMsg =
18373                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
18374                                        timeFormatPreferenceMsgValue, 0);
18375                        mHandler.sendMessage(updateTimePreferenceMsg);
18376                    }
18377                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18378                    synchronized (stats) {
18379                        stats.noteCurrentTimeChangedLocked();
18380                    }
18381                    break;
18382                case Intent.ACTION_CLEAR_DNS_CACHE:
18383                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18384                    break;
18385                case Proxy.PROXY_CHANGE_ACTION:
18386                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18387                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18388                    break;
18389                case android.hardware.Camera.ACTION_NEW_PICTURE:
18390                case android.hardware.Camera.ACTION_NEW_VIDEO:
18391                    // These broadcasts are no longer allowed by the system, since they can
18392                    // cause significant thrashing at a crictical point (using the camera).
18393                    // Apps should use JobScehduler to monitor for media provider changes.
18394                    Slog.w(TAG, action + " no longer allowed; dropping from "
18395                            + UserHandle.formatUid(callingUid));
18396                    if (resultTo != null) {
18397                        final BroadcastQueue queue = broadcastQueueForIntent(intent);
18398                        try {
18399                            queue.performReceiveLocked(callerApp, resultTo, intent,
18400                                    Activity.RESULT_CANCELED, null, null,
18401                                    false, false, userId);
18402                        } catch (RemoteException e) {
18403                            Slog.w(TAG, "Failure ["
18404                                    + queue.mQueueName + "] sending broadcast result of "
18405                                    + intent, e);
18406
18407                        }
18408                    }
18409                    // Lie; we don't want to crash the app.
18410                    return ActivityManager.BROADCAST_SUCCESS;
18411                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
18412                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
18413                    break;
18414            }
18415        }
18416
18417        // Add to the sticky list if requested.
18418        if (sticky) {
18419            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18420                    callingPid, callingUid)
18421                    != PackageManager.PERMISSION_GRANTED) {
18422                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18423                        + callingPid + ", uid=" + callingUid
18424                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18425                Slog.w(TAG, msg);
18426                throw new SecurityException(msg);
18427            }
18428            if (requiredPermissions != null && requiredPermissions.length > 0) {
18429                Slog.w(TAG, "Can't broadcast sticky intent " + intent
18430                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
18431                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18432            }
18433            if (intent.getComponent() != null) {
18434                throw new SecurityException(
18435                        "Sticky broadcasts can't target a specific component");
18436            }
18437            // We use userId directly here, since the "all" target is maintained
18438            // as a separate set of sticky broadcasts.
18439            if (userId != UserHandle.USER_ALL) {
18440                // But first, if this is not a broadcast to all users, then
18441                // make sure it doesn't conflict with an existing broadcast to
18442                // all users.
18443                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18444                        UserHandle.USER_ALL);
18445                if (stickies != null) {
18446                    ArrayList<Intent> list = stickies.get(intent.getAction());
18447                    if (list != null) {
18448                        int N = list.size();
18449                        int i;
18450                        for (i=0; i<N; i++) {
18451                            if (intent.filterEquals(list.get(i))) {
18452                                throw new IllegalArgumentException(
18453                                        "Sticky broadcast " + intent + " for user "
18454                                        + userId + " conflicts with existing global broadcast");
18455                            }
18456                        }
18457                    }
18458                }
18459            }
18460            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18461            if (stickies == null) {
18462                stickies = new ArrayMap<>();
18463                mStickyBroadcasts.put(userId, stickies);
18464            }
18465            ArrayList<Intent> list = stickies.get(intent.getAction());
18466            if (list == null) {
18467                list = new ArrayList<>();
18468                stickies.put(intent.getAction(), list);
18469            }
18470            final int stickiesCount = list.size();
18471            int i;
18472            for (i = 0; i < stickiesCount; i++) {
18473                if (intent.filterEquals(list.get(i))) {
18474                    // This sticky already exists, replace it.
18475                    list.set(i, new Intent(intent));
18476                    break;
18477                }
18478            }
18479            if (i >= stickiesCount) {
18480                list.add(new Intent(intent));
18481            }
18482        }
18483
18484        int[] users;
18485        if (userId == UserHandle.USER_ALL) {
18486            // Caller wants broadcast to go to all started users.
18487            users = mUserController.getStartedUserArrayLocked();
18488        } else {
18489            // Caller wants broadcast to go to one specific user.
18490            users = new int[] {userId};
18491        }
18492
18493        // Figure out who all will receive this broadcast.
18494        List receivers = null;
18495        List<BroadcastFilter> registeredReceivers = null;
18496        // Need to resolve the intent to interested receivers...
18497        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18498                 == 0) {
18499            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18500        }
18501        if (intent.getComponent() == null) {
18502            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18503                // Query one target user at a time, excluding shell-restricted users
18504                for (int i = 0; i < users.length; i++) {
18505                    if (mUserController.hasUserRestriction(
18506                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18507                        continue;
18508                    }
18509                    List<BroadcastFilter> registeredReceiversForUser =
18510                            mReceiverResolver.queryIntent(intent,
18511                                    resolvedType, false, false /*visibleToEphemeral*/,
18512                                    false /*isEphemeral*/, users[i]);
18513                    if (registeredReceivers == null) {
18514                        registeredReceivers = registeredReceiversForUser;
18515                    } else if (registeredReceiversForUser != null) {
18516                        registeredReceivers.addAll(registeredReceiversForUser);
18517                    }
18518                }
18519            } else {
18520                registeredReceivers = mReceiverResolver.queryIntent(intent,
18521                        resolvedType, false, false /*visibleToEphemeral*/,
18522                        false /*isEphemeral*/, userId);
18523            }
18524        }
18525
18526        final boolean replacePending =
18527                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18528
18529        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18530                + " replacePending=" + replacePending);
18531
18532        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18533        if (!ordered && NR > 0) {
18534            // If we are not serializing this broadcast, then send the
18535            // registered receivers separately so they don't wait for the
18536            // components to be launched.
18537            if (isCallerSystem) {
18538                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18539                        isProtectedBroadcast, registeredReceivers);
18540            }
18541            final BroadcastQueue queue = broadcastQueueForIntent(intent);
18542            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18543                    callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18544                    appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18545                    resultExtras, ordered, sticky, false, userId);
18546            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18547            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18548            if (!replaced) {
18549                queue.enqueueParallelBroadcastLocked(r);
18550                queue.scheduleBroadcastsLocked();
18551            }
18552            registeredReceivers = null;
18553            NR = 0;
18554        }
18555
18556        // Merge into one list.
18557        int ir = 0;
18558        if (receivers != null) {
18559            // A special case for PACKAGE_ADDED: do not allow the package
18560            // being added to see this broadcast.  This prevents them from
18561            // using this as a back door to get run as soon as they are
18562            // installed.  Maybe in the future we want to have a special install
18563            // broadcast or such for apps, but we'd like to deliberately make
18564            // this decision.
18565            String skipPackages[] = null;
18566            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18567                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18568                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18569                Uri data = intent.getData();
18570                if (data != null) {
18571                    String pkgName = data.getSchemeSpecificPart();
18572                    if (pkgName != null) {
18573                        skipPackages = new String[] { pkgName };
18574                    }
18575                }
18576            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18577                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18578            }
18579            if (skipPackages != null && (skipPackages.length > 0)) {
18580                for (String skipPackage : skipPackages) {
18581                    if (skipPackage != null) {
18582                        int NT = receivers.size();
18583                        for (int it=0; it<NT; it++) {
18584                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
18585                            if (curt.activityInfo.packageName.equals(skipPackage)) {
18586                                receivers.remove(it);
18587                                it--;
18588                                NT--;
18589                            }
18590                        }
18591                    }
18592                }
18593            }
18594
18595            int NT = receivers != null ? receivers.size() : 0;
18596            int it = 0;
18597            ResolveInfo curt = null;
18598            BroadcastFilter curr = null;
18599            while (it < NT && ir < NR) {
18600                if (curt == null) {
18601                    curt = (ResolveInfo)receivers.get(it);
18602                }
18603                if (curr == null) {
18604                    curr = registeredReceivers.get(ir);
18605                }
18606                if (curr.getPriority() >= curt.priority) {
18607                    // Insert this broadcast record into the final list.
18608                    receivers.add(it, curr);
18609                    ir++;
18610                    curr = null;
18611                    it++;
18612                    NT++;
18613                } else {
18614                    // Skip to the next ResolveInfo in the final list.
18615                    it++;
18616                    curt = null;
18617                }
18618            }
18619        }
18620        while (ir < NR) {
18621            if (receivers == null) {
18622                receivers = new ArrayList();
18623            }
18624            receivers.add(registeredReceivers.get(ir));
18625            ir++;
18626        }
18627
18628        if (isCallerSystem) {
18629            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18630                    isProtectedBroadcast, receivers);
18631        }
18632
18633        if ((receivers != null && receivers.size() > 0)
18634                || resultTo != null) {
18635            BroadcastQueue queue = broadcastQueueForIntent(intent);
18636            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18637                    callerPackage, callingPid, callingUid, resolvedType,
18638                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18639                    resultData, resultExtras, ordered, sticky, false, userId);
18640
18641            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18642                    + ": prev had " + queue.mOrderedBroadcasts.size());
18643            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18644                    "Enqueueing broadcast " + r.intent.getAction());
18645
18646            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18647            if (!replaced) {
18648                queue.enqueueOrderedBroadcastLocked(r);
18649                queue.scheduleBroadcastsLocked();
18650            }
18651        } else {
18652            // There was nobody interested in the broadcast, but we still want to record
18653            // that it happened.
18654            if (intent.getComponent() == null && intent.getPackage() == null
18655                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18656                // This was an implicit broadcast... let's record it for posterity.
18657                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18658            }
18659        }
18660
18661        return ActivityManager.BROADCAST_SUCCESS;
18662    }
18663
18664    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18665            int skipCount, long dispatchTime) {
18666        final long now = SystemClock.elapsedRealtime();
18667        if (mCurBroadcastStats == null ||
18668                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18669            mLastBroadcastStats = mCurBroadcastStats;
18670            if (mLastBroadcastStats != null) {
18671                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18672                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18673            }
18674            mCurBroadcastStats = new BroadcastStats();
18675        }
18676        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18677    }
18678
18679    final Intent verifyBroadcastLocked(Intent intent) {
18680        // Refuse possible leaked file descriptors
18681        if (intent != null && intent.hasFileDescriptors() == true) {
18682            throw new IllegalArgumentException("File descriptors passed in Intent");
18683        }
18684
18685        int flags = intent.getFlags();
18686
18687        if (!mProcessesReady) {
18688            // if the caller really truly claims to know what they're doing, go
18689            // ahead and allow the broadcast without launching any receivers
18690            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18691                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18692            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18693                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18694                        + " before boot completion");
18695                throw new IllegalStateException("Cannot broadcast before boot completed");
18696            }
18697        }
18698
18699        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18700            throw new IllegalArgumentException(
18701                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18702        }
18703
18704        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18705            switch (Binder.getCallingUid()) {
18706                case Process.ROOT_UID:
18707                case Process.SHELL_UID:
18708                    break;
18709                default:
18710                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
18711                            + Binder.getCallingUid());
18712                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
18713                    break;
18714            }
18715        }
18716
18717        return intent;
18718    }
18719
18720    public final int broadcastIntent(IApplicationThread caller,
18721            Intent intent, String resolvedType, IIntentReceiver resultTo,
18722            int resultCode, String resultData, Bundle resultExtras,
18723            String[] requiredPermissions, int appOp, Bundle bOptions,
18724            boolean serialized, boolean sticky, int userId) {
18725        enforceNotIsolatedCaller("broadcastIntent");
18726        synchronized(this) {
18727            intent = verifyBroadcastLocked(intent);
18728
18729            final ProcessRecord callerApp = getRecordForAppLocked(caller);
18730            final int callingPid = Binder.getCallingPid();
18731            final int callingUid = Binder.getCallingUid();
18732            final long origId = Binder.clearCallingIdentity();
18733            int res = broadcastIntentLocked(callerApp,
18734                    callerApp != null ? callerApp.info.packageName : null,
18735                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18736                    requiredPermissions, appOp, bOptions, serialized, sticky,
18737                    callingPid, callingUid, userId);
18738            Binder.restoreCallingIdentity(origId);
18739            return res;
18740        }
18741    }
18742
18743
18744    int broadcastIntentInPackage(String packageName, int uid,
18745            Intent intent, String resolvedType, IIntentReceiver resultTo,
18746            int resultCode, String resultData, Bundle resultExtras,
18747            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18748            int userId) {
18749        synchronized(this) {
18750            intent = verifyBroadcastLocked(intent);
18751
18752            final long origId = Binder.clearCallingIdentity();
18753            String[] requiredPermissions = requiredPermission == null ? null
18754                    : new String[] {requiredPermission};
18755            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18756                    resultTo, resultCode, resultData, resultExtras,
18757                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18758                    sticky, -1, uid, userId);
18759            Binder.restoreCallingIdentity(origId);
18760            return res;
18761        }
18762    }
18763
18764    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18765        // Refuse possible leaked file descriptors
18766        if (intent != null && intent.hasFileDescriptors() == true) {
18767            throw new IllegalArgumentException("File descriptors passed in Intent");
18768        }
18769
18770        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18771                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18772
18773        synchronized(this) {
18774            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18775                    != PackageManager.PERMISSION_GRANTED) {
18776                String msg = "Permission Denial: unbroadcastIntent() from pid="
18777                        + Binder.getCallingPid()
18778                        + ", uid=" + Binder.getCallingUid()
18779                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18780                Slog.w(TAG, msg);
18781                throw new SecurityException(msg);
18782            }
18783            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18784            if (stickies != null) {
18785                ArrayList<Intent> list = stickies.get(intent.getAction());
18786                if (list != null) {
18787                    int N = list.size();
18788                    int i;
18789                    for (i=0; i<N; i++) {
18790                        if (intent.filterEquals(list.get(i))) {
18791                            list.remove(i);
18792                            break;
18793                        }
18794                    }
18795                    if (list.size() <= 0) {
18796                        stickies.remove(intent.getAction());
18797                    }
18798                }
18799                if (stickies.size() <= 0) {
18800                    mStickyBroadcasts.remove(userId);
18801                }
18802            }
18803        }
18804    }
18805
18806    void backgroundServicesFinishedLocked(int userId) {
18807        for (BroadcastQueue queue : mBroadcastQueues) {
18808            queue.backgroundServicesFinishedLocked(userId);
18809        }
18810    }
18811
18812    public void finishReceiver(IBinder who, int resultCode, String resultData,
18813            Bundle resultExtras, boolean resultAbort, int flags) {
18814        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18815
18816        // Refuse possible leaked file descriptors
18817        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18818            throw new IllegalArgumentException("File descriptors passed in Bundle");
18819        }
18820
18821        final long origId = Binder.clearCallingIdentity();
18822        try {
18823            boolean doNext = false;
18824            BroadcastRecord r;
18825
18826            synchronized(this) {
18827                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18828                        ? mFgBroadcastQueue : mBgBroadcastQueue;
18829                r = queue.getMatchingOrderedReceiver(who);
18830                if (r != null) {
18831                    doNext = r.queue.finishReceiverLocked(r, resultCode,
18832                        resultData, resultExtras, resultAbort, true);
18833                }
18834            }
18835
18836            if (doNext) {
18837                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
18838                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
18839                      String.format("ProcessBroadcast from %s (%s) %s", r.callerPackage,
18840                        r.callerApp == null ? "caller unknown" : r.callerApp.toShortString(),
18841                        r.intent == null ? "" : r.intent.toString()));
18842                }
18843                r.queue.processNextBroadcast(false);
18844                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
18845            }
18846            trimApplications();
18847        } finally {
18848            Binder.restoreCallingIdentity(origId);
18849        }
18850    }
18851
18852    // =========================================================
18853    // INSTRUMENTATION
18854    // =========================================================
18855
18856    public boolean startInstrumentation(ComponentName className,
18857            String profileFile, int flags, Bundle arguments,
18858            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18859            int userId, String abiOverride) {
18860        enforceNotIsolatedCaller("startInstrumentation");
18861        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18862                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18863        // Refuse possible leaked file descriptors
18864        if (arguments != null && arguments.hasFileDescriptors()) {
18865            throw new IllegalArgumentException("File descriptors passed in Bundle");
18866        }
18867
18868        synchronized(this) {
18869            InstrumentationInfo ii = null;
18870            ApplicationInfo ai = null;
18871            try {
18872                ii = mContext.getPackageManager().getInstrumentationInfo(
18873                    className, STOCK_PM_FLAGS);
18874                ai = AppGlobals.getPackageManager().getApplicationInfo(
18875                        ii.targetPackage, STOCK_PM_FLAGS, userId);
18876            } catch (PackageManager.NameNotFoundException e) {
18877            } catch (RemoteException e) {
18878            }
18879            if (ii == null) {
18880                reportStartInstrumentationFailureLocked(watcher, className,
18881                        "Unable to find instrumentation info for: " + className);
18882                return false;
18883            }
18884            if (ai == null) {
18885                reportStartInstrumentationFailureLocked(watcher, className,
18886                        "Unable to find instrumentation target package: " + ii.targetPackage);
18887                return false;
18888            }
18889            if (!ai.hasCode()) {
18890                reportStartInstrumentationFailureLocked(watcher, className,
18891                        "Instrumentation target has no code: " + ii.targetPackage);
18892                return false;
18893            }
18894
18895            int match = mContext.getPackageManager().checkSignatures(
18896                    ii.targetPackage, ii.packageName);
18897            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18898                String msg = "Permission Denial: starting instrumentation "
18899                        + className + " from pid="
18900                        + Binder.getCallingPid()
18901                        + ", uid=" + Binder.getCallingPid()
18902                        + " not allowed because package " + ii.packageName
18903                        + " does not have a signature matching the target "
18904                        + ii.targetPackage;
18905                reportStartInstrumentationFailureLocked(watcher, className, msg);
18906                throw new SecurityException(msg);
18907            }
18908
18909            final long origId = Binder.clearCallingIdentity();
18910            // Instrumentation can kill and relaunch even persistent processes
18911            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18912                    "start instr");
18913            ProcessRecord app = addAppLocked(ai, false, abiOverride);
18914            app.instrumentationClass = className;
18915            app.instrumentationInfo = ai;
18916            app.instrumentationProfileFile = profileFile;
18917            app.instrumentationArguments = arguments;
18918            app.instrumentationWatcher = watcher;
18919            app.instrumentationUiAutomationConnection = uiAutomationConnection;
18920            app.instrumentationResultClass = className;
18921            Binder.restoreCallingIdentity(origId);
18922        }
18923
18924        return true;
18925    }
18926
18927    /**
18928     * Report errors that occur while attempting to start Instrumentation.  Always writes the
18929     * error to the logs, but if somebody is watching, send the report there too.  This enables
18930     * the "am" command to report errors with more information.
18931     *
18932     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18933     * @param cn The component name of the instrumentation.
18934     * @param report The error report.
18935     */
18936    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18937            ComponentName cn, String report) {
18938        Slog.w(TAG, report);
18939        if (watcher != null) {
18940            Bundle results = new Bundle();
18941            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18942            results.putString("Error", report);
18943            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18944        }
18945    }
18946
18947    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18948        if (app.instrumentationWatcher != null) {
18949            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18950                    app.instrumentationClass, resultCode, results);
18951        }
18952
18953        // Can't call out of the system process with a lock held, so post a message.
18954        if (app.instrumentationUiAutomationConnection != null) {
18955            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18956                    app.instrumentationUiAutomationConnection).sendToTarget();
18957        }
18958
18959        app.instrumentationWatcher = null;
18960        app.instrumentationUiAutomationConnection = null;
18961        app.instrumentationClass = null;
18962        app.instrumentationInfo = null;
18963        app.instrumentationProfileFile = null;
18964        app.instrumentationArguments = null;
18965
18966        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18967                "finished inst");
18968    }
18969
18970    public void finishInstrumentation(IApplicationThread target,
18971            int resultCode, Bundle results) {
18972        int userId = UserHandle.getCallingUserId();
18973        // Refuse possible leaked file descriptors
18974        if (results != null && results.hasFileDescriptors()) {
18975            throw new IllegalArgumentException("File descriptors passed in Intent");
18976        }
18977
18978        synchronized(this) {
18979            ProcessRecord app = getRecordForAppLocked(target);
18980            if (app == null) {
18981                Slog.w(TAG, "finishInstrumentation: no app for " + target);
18982                return;
18983            }
18984            final long origId = Binder.clearCallingIdentity();
18985            finishInstrumentationLocked(app, resultCode, results);
18986            Binder.restoreCallingIdentity(origId);
18987        }
18988    }
18989
18990    // =========================================================
18991    // CONFIGURATION
18992    // =========================================================
18993
18994    public ConfigurationInfo getDeviceConfigurationInfo() {
18995        ConfigurationInfo config = new ConfigurationInfo();
18996        synchronized (this) {
18997            final Configuration globalConfig = getGlobalConfiguration();
18998            config.reqTouchScreen = globalConfig.touchscreen;
18999            config.reqKeyboardType = globalConfig.keyboard;
19000            config.reqNavigation = globalConfig.navigation;
19001            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
19002                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
19003                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
19004            }
19005            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
19006                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
19007                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
19008            }
19009            config.reqGlEsVersion = GL_ES_VERSION;
19010        }
19011        return config;
19012    }
19013
19014    ActivityStack getFocusedStack() {
19015        return mStackSupervisor.getFocusedStack();
19016    }
19017
19018    @Override
19019    public int getFocusedStackId() throws RemoteException {
19020        ActivityStack focusedStack = getFocusedStack();
19021        if (focusedStack != null) {
19022            return focusedStack.getStackId();
19023        }
19024        return -1;
19025    }
19026
19027    public Configuration getConfiguration() {
19028        Configuration ci;
19029        synchronized(this) {
19030            ci = new Configuration(getGlobalConfiguration());
19031            ci.userSetLocale = false;
19032        }
19033        return ci;
19034    }
19035
19036    @Override
19037    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
19038        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
19039        synchronized (this) {
19040            mSuppressResizeConfigChanges = suppress;
19041        }
19042    }
19043
19044    @Override
19045    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
19046        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
19047        if (StackId.isHomeOrRecentsStack(fromStackId)) {
19048            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
19049        }
19050        synchronized (this) {
19051            final long origId = Binder.clearCallingIdentity();
19052            try {
19053                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
19054            } finally {
19055                Binder.restoreCallingIdentity(origId);
19056            }
19057        }
19058    }
19059
19060    @Override
19061    public void updatePersistentConfiguration(Configuration values) {
19062        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
19063        enforceWriteSettingsPermission("updatePersistentConfiguration()");
19064        if (values == null) {
19065            throw new NullPointerException("Configuration must not be null");
19066        }
19067
19068        int userId = UserHandle.getCallingUserId();
19069
19070        synchronized(this) {
19071            updatePersistentConfigurationLocked(values, userId);
19072        }
19073    }
19074
19075    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
19076        final long origId = Binder.clearCallingIdentity();
19077        try {
19078            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
19079        } finally {
19080            Binder.restoreCallingIdentity(origId);
19081        }
19082    }
19083
19084    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
19085        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
19086                FONT_SCALE, 1.0f, userId);
19087
19088        synchronized (this) {
19089            if (getGlobalConfiguration().fontScale == scaleFactor) {
19090                return;
19091            }
19092
19093            final Configuration configuration
19094                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19095            configuration.fontScale = scaleFactor;
19096            updatePersistentConfigurationLocked(configuration, userId);
19097        }
19098    }
19099
19100    private void enforceWriteSettingsPermission(String func) {
19101        int uid = Binder.getCallingUid();
19102        if (uid == Process.ROOT_UID) {
19103            return;
19104        }
19105
19106        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
19107                Settings.getPackageNameForUid(mContext, uid), false)) {
19108            return;
19109        }
19110
19111        String msg = "Permission Denial: " + func + " from pid="
19112                + Binder.getCallingPid()
19113                + ", uid=" + uid
19114                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
19115        Slog.w(TAG, msg);
19116        throw new SecurityException(msg);
19117    }
19118
19119    @Override
19120    public boolean updateConfiguration(Configuration values) {
19121        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
19122
19123        synchronized(this) {
19124            if (values == null && mWindowManager != null) {
19125                // sentinel: fetch the current configuration from the window manager
19126                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19127            }
19128
19129            if (mWindowManager != null) {
19130                // Update OOM levels based on display size.
19131                mProcessList.applyDisplaySize(mWindowManager);
19132            }
19133
19134            final long origId = Binder.clearCallingIdentity();
19135            try {
19136                if (values != null) {
19137                    Settings.System.clearConfiguration(values);
19138                }
19139                updateConfigurationLocked(values, null, false, false /* persistent */,
19140                        UserHandle.USER_NULL, false /* deferResume */,
19141                        mTmpUpdateConfigurationResult);
19142                return mTmpUpdateConfigurationResult.changes != 0;
19143            } finally {
19144                Binder.restoreCallingIdentity(origId);
19145            }
19146        }
19147    }
19148
19149    void updateUserConfigurationLocked() {
19150        final Configuration configuration = new Configuration(getGlobalConfiguration());
19151        final int currentUserId = mUserController.getCurrentUserIdLocked();
19152        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
19153                currentUserId, Settings.System.canWrite(mContext));
19154        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
19155                false /* persistent */, currentUserId, false /* deferResume */);
19156    }
19157
19158    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19159            boolean initLocale) {
19160        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19161    }
19162
19163    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19164            boolean initLocale, boolean deferResume) {
19165        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19166        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19167                UserHandle.USER_NULL, deferResume);
19168    }
19169
19170    // To cache the list of supported system locales
19171    private String[] mSupportedSystemLocales = null;
19172
19173    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19174            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19175        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
19176                deferResume, null /* result */);
19177    }
19178
19179    /**
19180     * Do either or both things: (1) change the current configuration, and (2)
19181     * make sure the given activity is running with the (now) current
19182     * configuration.  Returns true if the activity has been left running, or
19183     * false if <var>starting</var> is being destroyed to match the new
19184     * configuration.
19185     *
19186     * @param userId is only used when persistent parameter is set to true to persist configuration
19187     *               for that particular user
19188     */
19189    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19190            boolean initLocale, boolean persistent, int userId, boolean deferResume,
19191            UpdateConfigurationResult result) {
19192        int changes = 0;
19193        boolean kept = true;
19194
19195        if (mWindowManager != null) {
19196            mWindowManager.deferSurfaceLayout();
19197        }
19198        try {
19199            if (values != null) {
19200                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
19201                        deferResume);
19202            }
19203
19204            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19205        } finally {
19206            if (mWindowManager != null) {
19207                mWindowManager.continueSurfaceLayout();
19208            }
19209        }
19210
19211        if (result != null) {
19212            result.changes = changes;
19213            result.activityRelaunched = !kept;
19214        }
19215        return kept;
19216    }
19217
19218    /** Update default (global) configuration and notify listeners about changes. */
19219    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
19220            boolean persistent, int userId, boolean deferResume) {
19221        mTempConfig.setTo(getGlobalConfiguration());
19222        final int changes = mTempConfig.updateFrom(values);
19223        if (changes == 0) {
19224            return 0;
19225        }
19226
19227        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19228                "Updating global configuration to: " + values);
19229
19230        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19231
19232        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19233            final LocaleList locales = values.getLocales();
19234            int bestLocaleIndex = 0;
19235            if (locales.size() > 1) {
19236                if (mSupportedSystemLocales == null) {
19237                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
19238                }
19239                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
19240            }
19241            SystemProperties.set("persist.sys.locale",
19242                    locales.get(bestLocaleIndex).toLanguageTag());
19243            LocaleList.setDefault(locales, bestLocaleIndex);
19244            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19245                    locales.get(bestLocaleIndex)));
19246        }
19247
19248        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
19249        mTempConfig.seq = mConfigurationSeq;
19250
19251        // Update stored global config and notify everyone about the change.
19252        mStackSupervisor.onConfigurationChanged(mTempConfig);
19253
19254        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
19255        // TODO(multi-display): Update UsageEvents#Event to include displayId.
19256        mUsageStatsService.reportConfigurationChange(mTempConfig,
19257                mUserController.getCurrentUserIdLocked());
19258
19259        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
19260        mShowDialogs = shouldShowDialogs(mTempConfig, mInVrMode);
19261
19262        AttributeCache ac = AttributeCache.instance();
19263        if (ac != null) {
19264            ac.updateConfiguration(mTempConfig);
19265        }
19266
19267        // Make sure all resources in our process are updated right now, so that anyone who is going
19268        // to retrieve resource values after we return will be sure to get the new ones. This is
19269        // especially important during boot, where the first config change needs to guarantee all
19270        // resources have that config before following boot code is executed.
19271        mSystemThread.applyConfigurationToResources(mTempConfig);
19272
19273        // We need another copy of global config because we're scheduling some calls instead of
19274        // running them in place. We need to be sure that object we send will be handled unchanged.
19275        final Configuration configCopy = new Configuration(mTempConfig);
19276        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19277            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19278            msg.obj = configCopy;
19279            msg.arg1 = userId;
19280            mHandler.sendMessage(msg);
19281        }
19282
19283        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19284            ProcessRecord app = mLruProcesses.get(i);
19285            try {
19286                if (app.thread != null) {
19287                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19288                            + app.processName + " new config " + configCopy);
19289                    app.thread.scheduleConfigurationChanged(configCopy);
19290                }
19291            } catch (Exception e) {
19292            }
19293        }
19294
19295        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19296        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
19297                | Intent.FLAG_RECEIVER_FOREGROUND);
19298        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19299                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19300                UserHandle.USER_ALL);
19301        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
19302            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19303            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19304            if (initLocale || !mProcessesReady) {
19305                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19306            }
19307            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
19308                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19309                    UserHandle.USER_ALL);
19310        }
19311
19312        // Override configuration of the default display duplicates global config, so we need to
19313        // update it also. This will also notify WindowManager about changes.
19314        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
19315                DEFAULT_DISPLAY);
19316
19317        return changes;
19318    }
19319
19320    @Override
19321    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
19322        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
19323
19324        synchronized (this) {
19325            // Check if display is initialized in AM.
19326            if (!mStackSupervisor.isDisplayAdded(displayId)) {
19327                // Call might come when display is not yet added or has already been removed.
19328                if (DEBUG_CONFIGURATION) {
19329                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
19330                            + displayId);
19331                }
19332                return false;
19333            }
19334
19335            if (values == null && mWindowManager != null) {
19336                // sentinel: fetch the current configuration from the window manager
19337                values = mWindowManager.computeNewConfiguration(displayId);
19338            }
19339
19340            if (mWindowManager != null) {
19341                // Update OOM levels based on display size.
19342                mProcessList.applyDisplaySize(mWindowManager);
19343            }
19344
19345            final long origId = Binder.clearCallingIdentity();
19346            try {
19347                if (values != null) {
19348                    Settings.System.clearConfiguration(values);
19349                }
19350                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
19351                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
19352                return mTmpUpdateConfigurationResult.changes != 0;
19353            } finally {
19354                Binder.restoreCallingIdentity(origId);
19355            }
19356        }
19357    }
19358
19359    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
19360            boolean deferResume, int displayId) {
19361        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
19362                displayId, null /* result */);
19363    }
19364
19365    /**
19366     * Updates override configuration specific for the selected display. If no config is provided,
19367     * new one will be computed in WM based on current display info.
19368     */
19369    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
19370            ActivityRecord starting, boolean deferResume, int displayId,
19371            UpdateConfigurationResult result) {
19372        int changes = 0;
19373        boolean kept = true;
19374
19375        if (mWindowManager != null) {
19376            mWindowManager.deferSurfaceLayout();
19377        }
19378        try {
19379            if (values != null) {
19380                if (displayId == DEFAULT_DISPLAY) {
19381                    // Override configuration of the default display duplicates global config, so
19382                    // we're calling global config update instead for default display. It will also
19383                    // apply the correct override config.
19384                    changes = updateGlobalConfiguration(values, false /* initLocale */,
19385                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
19386                } else {
19387                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
19388                }
19389            }
19390
19391            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19392        } finally {
19393            if (mWindowManager != null) {
19394                mWindowManager.continueSurfaceLayout();
19395            }
19396        }
19397
19398        if (result != null) {
19399            result.changes = changes;
19400            result.activityRelaunched = !kept;
19401        }
19402        return kept;
19403    }
19404
19405    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
19406            int displayId) {
19407        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
19408        final int changes = mTempConfig.updateFrom(values);
19409        if (changes == 0) {
19410            return 0;
19411        }
19412
19413        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
19414                + " for displayId=" + displayId);
19415        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
19416
19417        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19418        if (isDensityChange) {
19419            // Reset the unsupported display size dialog.
19420            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19421
19422            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19423        }
19424
19425        // Update the configuration with WM first and check if any of the stacks need to be resized
19426        // due to the configuration change. If so, resize the stacks now and do any relaunches if
19427        // necessary. This way we don't need to relaunch again afterwards in
19428        // ensureActivityConfigurationLocked().
19429        if (mWindowManager != null) {
19430            final int[] resizedStacks =
19431                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
19432            if (resizedStacks != null) {
19433                for (int stackId : resizedStacks) {
19434                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
19435                }
19436            }
19437        }
19438
19439        return changes;
19440    }
19441
19442    /** Applies latest configuration and/or visibility updates if needed. */
19443    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
19444        boolean kept = true;
19445        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19446        // mainStack is null during startup.
19447        if (mainStack != null) {
19448            if (changes != 0 && starting == null) {
19449                // If the configuration changed, and the caller is not already
19450                // in the process of starting an activity, then find the top
19451                // activity to check if its configuration needs to change.
19452                starting = mainStack.topRunningActivityLocked();
19453            }
19454
19455            if (starting != null) {
19456                kept = starting.ensureActivityConfigurationLocked(changes,
19457                        false /* preserveWindow */);
19458                // And we need to make sure at this point that all other activities
19459                // are made visible with the correct configuration.
19460                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19461                        !PRESERVE_WINDOWS);
19462            }
19463        }
19464
19465        return kept;
19466    }
19467
19468    /** Helper method that requests bounds from WM and applies them to stack. */
19469    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
19470        final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19471        mStackSupervisor.resizeStackLocked(
19472                stackId, newBounds, null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
19473                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
19474    }
19475
19476    /**
19477     * Decide based on the configuration whether we should show the ANR,
19478     * crash, etc dialogs.  The idea is that if there is no affordance to
19479     * press the on-screen buttons, or the user experience would be more
19480     * greatly impacted than the crash itself, we shouldn't show the dialog.
19481     *
19482     * A thought: SystemUI might also want to get told about this, the Power
19483     * dialog / global actions also might want different behaviors.
19484     */
19485    private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19486        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19487                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19488                                   && config.navigation == Configuration.NAVIGATION_NONAV);
19489        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19490        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19491                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19492        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19493    }
19494
19495    @Override
19496    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19497        synchronized (this) {
19498            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19499            if (srec != null) {
19500                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
19501            }
19502        }
19503        return false;
19504    }
19505
19506    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19507            Intent resultData) {
19508
19509        synchronized (this) {
19510            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19511            if (r != null) {
19512                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
19513            }
19514            return false;
19515        }
19516    }
19517
19518    public int getLaunchedFromUid(IBinder activityToken) {
19519        ActivityRecord srec;
19520        synchronized (this) {
19521            srec = ActivityRecord.forTokenLocked(activityToken);
19522        }
19523        if (srec == null) {
19524            return -1;
19525        }
19526        return srec.launchedFromUid;
19527    }
19528
19529    public String getLaunchedFromPackage(IBinder activityToken) {
19530        ActivityRecord srec;
19531        synchronized (this) {
19532            srec = ActivityRecord.forTokenLocked(activityToken);
19533        }
19534        if (srec == null) {
19535            return null;
19536        }
19537        return srec.launchedFromPackage;
19538    }
19539
19540    // =========================================================
19541    // LIFETIME MANAGEMENT
19542    // =========================================================
19543
19544    // Returns whether the app is receiving broadcast.
19545    // If receiving, fetch all broadcast queues which the app is
19546    // the current [or imminent] receiver on.
19547    private boolean isReceivingBroadcastLocked(ProcessRecord app,
19548            ArraySet<BroadcastQueue> receivingQueues) {
19549        if (!app.curReceivers.isEmpty()) {
19550            for (BroadcastRecord r : app.curReceivers) {
19551                receivingQueues.add(r.queue);
19552            }
19553            return true;
19554        }
19555
19556        // It's not the current receiver, but it might be starting up to become one
19557        for (BroadcastQueue queue : mBroadcastQueues) {
19558            final BroadcastRecord r = queue.mPendingBroadcast;
19559            if (r != null && r.curApp == app) {
19560                // found it; report which queue it's in
19561                receivingQueues.add(queue);
19562            }
19563        }
19564
19565        return !receivingQueues.isEmpty();
19566    }
19567
19568    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19569            int targetUid, ComponentName targetComponent, String targetProcess) {
19570        if (!mTrackingAssociations) {
19571            return null;
19572        }
19573        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19574                = mAssociations.get(targetUid);
19575        if (components == null) {
19576            components = new ArrayMap<>();
19577            mAssociations.put(targetUid, components);
19578        }
19579        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19580        if (sourceUids == null) {
19581            sourceUids = new SparseArray<>();
19582            components.put(targetComponent, sourceUids);
19583        }
19584        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19585        if (sourceProcesses == null) {
19586            sourceProcesses = new ArrayMap<>();
19587            sourceUids.put(sourceUid, sourceProcesses);
19588        }
19589        Association ass = sourceProcesses.get(sourceProcess);
19590        if (ass == null) {
19591            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19592                    targetProcess);
19593            sourceProcesses.put(sourceProcess, ass);
19594        }
19595        ass.mCount++;
19596        ass.mNesting++;
19597        if (ass.mNesting == 1) {
19598            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19599            ass.mLastState = sourceState;
19600        }
19601        return ass;
19602    }
19603
19604    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19605            ComponentName targetComponent) {
19606        if (!mTrackingAssociations) {
19607            return;
19608        }
19609        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19610                = mAssociations.get(targetUid);
19611        if (components == null) {
19612            return;
19613        }
19614        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19615        if (sourceUids == null) {
19616            return;
19617        }
19618        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19619        if (sourceProcesses == null) {
19620            return;
19621        }
19622        Association ass = sourceProcesses.get(sourceProcess);
19623        if (ass == null || ass.mNesting <= 0) {
19624            return;
19625        }
19626        ass.mNesting--;
19627        if (ass.mNesting == 0) {
19628            long uptime = SystemClock.uptimeMillis();
19629            ass.mTime += uptime - ass.mStartTime;
19630            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19631                    += uptime - ass.mLastStateUptime;
19632            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19633        }
19634    }
19635
19636    private void noteUidProcessState(final int uid, final int state) {
19637        mBatteryStatsService.noteUidProcessState(uid, state);
19638        if (mTrackingAssociations) {
19639            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19640                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19641                        = mAssociations.valueAt(i1);
19642                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19643                    SparseArray<ArrayMap<String, Association>> sourceUids
19644                            = targetComponents.valueAt(i2);
19645                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19646                    if (sourceProcesses != null) {
19647                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19648                            Association ass = sourceProcesses.valueAt(i4);
19649                            if (ass.mNesting >= 1) {
19650                                // currently associated
19651                                long uptime = SystemClock.uptimeMillis();
19652                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19653                                        += uptime - ass.mLastStateUptime;
19654                                ass.mLastState = state;
19655                                ass.mLastStateUptime = uptime;
19656                            }
19657                        }
19658                    }
19659                }
19660            }
19661        }
19662    }
19663
19664    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19665            boolean doingAll, long now) {
19666        if (mAdjSeq == app.adjSeq) {
19667            // This adjustment has already been computed.
19668            return app.curRawAdj;
19669        }
19670
19671        if (app.thread == null) {
19672            app.adjSeq = mAdjSeq;
19673            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19674            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19675            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19676        }
19677
19678        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19679        app.adjSource = null;
19680        app.adjTarget = null;
19681        app.empty = false;
19682        app.cached = false;
19683
19684        final int activitiesSize = app.activities.size();
19685
19686        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19687            // The max adjustment doesn't allow this app to be anything
19688            // below foreground, so it is not worth doing work for it.
19689            app.adjType = "fixed";
19690            app.adjSeq = mAdjSeq;
19691            app.curRawAdj = app.maxAdj;
19692            app.foregroundActivities = false;
19693            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19694            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19695            // System processes can do UI, and when they do we want to have
19696            // them trim their memory after the user leaves the UI.  To
19697            // facilitate this, here we need to determine whether or not it
19698            // is currently showing UI.
19699            app.systemNoUi = true;
19700            if (app == TOP_APP) {
19701                app.systemNoUi = false;
19702                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19703                app.adjType = "pers-top-activity";
19704            } else if (app.hasTopUi) {
19705                app.systemNoUi = false;
19706                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19707                app.adjType = "pers-top-ui";
19708            } else if (activitiesSize > 0) {
19709                for (int j = 0; j < activitiesSize; j++) {
19710                    final ActivityRecord r = app.activities.get(j);
19711                    if (r.visible) {
19712                        app.systemNoUi = false;
19713                    }
19714                }
19715            }
19716            if (!app.systemNoUi) {
19717                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19718            }
19719            return (app.curAdj=app.maxAdj);
19720        }
19721
19722        app.systemNoUi = false;
19723
19724        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19725
19726        // Determine the importance of the process, starting with most
19727        // important to least, and assign an appropriate OOM adjustment.
19728        int adj;
19729        int schedGroup;
19730        int procState;
19731        boolean foregroundActivities = false;
19732        mTmpBroadcastQueue.clear();
19733        if (app == TOP_APP) {
19734            // The last app on the list is the foreground app.
19735            adj = ProcessList.FOREGROUND_APP_ADJ;
19736            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19737            app.adjType = "top-activity";
19738            foregroundActivities = true;
19739            procState = PROCESS_STATE_CUR_TOP;
19740        } else if (app.instrumentationClass != null) {
19741            // Don't want to kill running instrumentation.
19742            adj = ProcessList.FOREGROUND_APP_ADJ;
19743            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19744            app.adjType = "instrumentation";
19745            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19746        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
19747            // An app that is currently receiving a broadcast also
19748            // counts as being in the foreground for OOM killer purposes.
19749            // It's placed in a sched group based on the nature of the
19750            // broadcast as reflected by which queue it's active in.
19751            adj = ProcessList.FOREGROUND_APP_ADJ;
19752            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
19753                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19754            app.adjType = "broadcast";
19755            procState = ActivityManager.PROCESS_STATE_RECEIVER;
19756        } else if (app.executingServices.size() > 0) {
19757            // An app that is currently executing a service callback also
19758            // counts as being in the foreground.
19759            adj = ProcessList.FOREGROUND_APP_ADJ;
19760            schedGroup = app.execServicesFg ?
19761                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19762            app.adjType = "exec-service";
19763            procState = ActivityManager.PROCESS_STATE_SERVICE;
19764            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19765        } else {
19766            // As far as we know the process is empty.  We may change our mind later.
19767            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19768            // At this point we don't actually know the adjustment.  Use the cached adj
19769            // value that the caller wants us to.
19770            adj = cachedAdj;
19771            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19772            app.cached = true;
19773            app.empty = true;
19774            app.adjType = "cch-empty";
19775        }
19776
19777        // Examine all activities if not already foreground.
19778        if (!foregroundActivities && activitiesSize > 0) {
19779            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19780            for (int j = 0; j < activitiesSize; j++) {
19781                final ActivityRecord r = app.activities.get(j);
19782                if (r.app != app) {
19783                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19784                            + " instead of expected " + app);
19785                    if (r.app == null || (r.app.uid == app.uid)) {
19786                        // Only fix things up when they look sane
19787                        r.app = app;
19788                    } else {
19789                        continue;
19790                    }
19791                }
19792                if (r.visible) {
19793                    // App has a visible activity; only upgrade adjustment.
19794                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
19795                        adj = ProcessList.VISIBLE_APP_ADJ;
19796                        app.adjType = "visible";
19797                    }
19798                    if (procState > PROCESS_STATE_CUR_TOP) {
19799                        procState = PROCESS_STATE_CUR_TOP;
19800                    }
19801                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19802                    app.cached = false;
19803                    app.empty = false;
19804                    foregroundActivities = true;
19805                    if (r.task != null && minLayer > 0) {
19806                        final int layer = r.task.mLayerRank;
19807                        if (layer >= 0 && minLayer > layer) {
19808                            minLayer = layer;
19809                        }
19810                    }
19811                    break;
19812                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19813                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19814                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19815                        app.adjType = "pausing";
19816                    }
19817                    if (procState > PROCESS_STATE_CUR_TOP) {
19818                        procState = PROCESS_STATE_CUR_TOP;
19819                    }
19820                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19821                    app.cached = false;
19822                    app.empty = false;
19823                    foregroundActivities = true;
19824                } else if (r.state == ActivityState.STOPPING) {
19825                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19826                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19827                        app.adjType = "stopping";
19828                    }
19829                    // For the process state, we will at this point consider the
19830                    // process to be cached.  It will be cached either as an activity
19831                    // or empty depending on whether the activity is finishing.  We do
19832                    // this so that we can treat the process as cached for purposes of
19833                    // memory trimming (determing current memory level, trim command to
19834                    // send to process) since there can be an arbitrary number of stopping
19835                    // processes and they should soon all go into the cached state.
19836                    if (!r.finishing) {
19837                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19838                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19839                        }
19840                    }
19841                    app.cached = false;
19842                    app.empty = false;
19843                    foregroundActivities = true;
19844                } else {
19845                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19846                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19847                        app.adjType = "cch-act";
19848                    }
19849                }
19850            }
19851            if (adj == ProcessList.VISIBLE_APP_ADJ) {
19852                adj += minLayer;
19853            }
19854        }
19855
19856        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19857                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19858            if (app.foregroundServices) {
19859                // The user is aware of this app, so make it visible.
19860                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19861                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19862                app.cached = false;
19863                app.adjType = "fg-service";
19864                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19865            } else if (app.forcingToForeground != null) {
19866                // The user is aware of this app, so make it visible.
19867                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19868                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19869                app.cached = false;
19870                app.adjType = "force-fg";
19871                app.adjSource = app.forcingToForeground;
19872                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19873            }
19874        }
19875
19876        if (app == mHeavyWeightProcess) {
19877            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19878                // We don't want to kill the current heavy-weight process.
19879                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19880                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19881                app.cached = false;
19882                app.adjType = "heavy";
19883            }
19884            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19885                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19886            }
19887        }
19888
19889        if (app == mHomeProcess) {
19890            if (adj > ProcessList.HOME_APP_ADJ) {
19891                // This process is hosting what we currently consider to be the
19892                // home app, so we don't want to let it go into the background.
19893                adj = ProcessList.HOME_APP_ADJ;
19894                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19895                app.cached = false;
19896                app.adjType = "home";
19897            }
19898            if (procState > ActivityManager.PROCESS_STATE_HOME) {
19899                procState = ActivityManager.PROCESS_STATE_HOME;
19900            }
19901        }
19902
19903        if (app == mPreviousProcess && app.activities.size() > 0) {
19904            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19905                // This was the previous process that showed UI to the user.
19906                // We want to try to keep it around more aggressively, to give
19907                // a good experience around switching between two apps.
19908                adj = ProcessList.PREVIOUS_APP_ADJ;
19909                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19910                app.cached = false;
19911                app.adjType = "previous";
19912            }
19913            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19914                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19915            }
19916        }
19917
19918        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19919                + " reason=" + app.adjType);
19920
19921        // By default, we use the computed adjustment.  It may be changed if
19922        // there are applications dependent on our services or providers, but
19923        // this gives us a baseline and makes sure we don't get into an
19924        // infinite recursion.
19925        app.adjSeq = mAdjSeq;
19926        app.curRawAdj = adj;
19927        app.hasStartedServices = false;
19928
19929        if (mBackupTarget != null && app == mBackupTarget.app) {
19930            // If possible we want to avoid killing apps while they're being backed up
19931            if (adj > ProcessList.BACKUP_APP_ADJ) {
19932                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19933                adj = ProcessList.BACKUP_APP_ADJ;
19934                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19935                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19936                }
19937                app.adjType = "backup";
19938                app.cached = false;
19939            }
19940            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19941                procState = ActivityManager.PROCESS_STATE_BACKUP;
19942            }
19943        }
19944
19945        boolean mayBeTop = false;
19946
19947        for (int is = app.services.size()-1;
19948                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19949                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19950                        || procState > ActivityManager.PROCESS_STATE_TOP);
19951                is--) {
19952            ServiceRecord s = app.services.valueAt(is);
19953            if (s.startRequested) {
19954                app.hasStartedServices = true;
19955                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19956                    procState = ActivityManager.PROCESS_STATE_SERVICE;
19957                }
19958                if (app.hasShownUi && app != mHomeProcess) {
19959                    // If this process has shown some UI, let it immediately
19960                    // go to the LRU list because it may be pretty heavy with
19961                    // UI stuff.  We'll tag it with a label just to help
19962                    // debug and understand what is going on.
19963                    if (adj > ProcessList.SERVICE_ADJ) {
19964                        app.adjType = "cch-started-ui-services";
19965                    }
19966                } else {
19967                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19968                        // This service has seen some activity within
19969                        // recent memory, so we will keep its process ahead
19970                        // of the background processes.
19971                        if (adj > ProcessList.SERVICE_ADJ) {
19972                            adj = ProcessList.SERVICE_ADJ;
19973                            app.adjType = "started-services";
19974                            app.cached = false;
19975                        }
19976                    }
19977                    // If we have let the service slide into the background
19978                    // state, still have some text describing what it is doing
19979                    // even though the service no longer has an impact.
19980                    if (adj > ProcessList.SERVICE_ADJ) {
19981                        app.adjType = "cch-started-services";
19982                    }
19983                }
19984            }
19985
19986            for (int conni = s.connections.size()-1;
19987                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19988                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19989                            || procState > ActivityManager.PROCESS_STATE_TOP);
19990                    conni--) {
19991                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19992                for (int i = 0;
19993                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19994                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19995                                || procState > ActivityManager.PROCESS_STATE_TOP);
19996                        i++) {
19997                    // XXX should compute this based on the max of
19998                    // all connected clients.
19999                    ConnectionRecord cr = clist.get(i);
20000                    if (cr.binding.client == app) {
20001                        // Binding to ourself is not interesting.
20002                        continue;
20003                    }
20004
20005                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
20006                        ProcessRecord client = cr.binding.client;
20007                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
20008                                TOP_APP, doingAll, now);
20009                        int clientProcState = client.curProcState;
20010                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20011                            // If the other app is cached for any reason, for purposes here
20012                            // we are going to consider it empty.  The specific cached state
20013                            // doesn't propagate except under certain conditions.
20014                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20015                        }
20016                        String adjType = null;
20017                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
20018                            // Not doing bind OOM management, so treat
20019                            // this guy more like a started service.
20020                            if (app.hasShownUi && app != mHomeProcess) {
20021                                // If this process has shown some UI, let it immediately
20022                                // go to the LRU list because it may be pretty heavy with
20023                                // UI stuff.  We'll tag it with a label just to help
20024                                // debug and understand what is going on.
20025                                if (adj > clientAdj) {
20026                                    adjType = "cch-bound-ui-services";
20027                                }
20028                                app.cached = false;
20029                                clientAdj = adj;
20030                                clientProcState = procState;
20031                            } else {
20032                                if (now >= (s.lastActivity
20033                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20034                                    // This service has not seen activity within
20035                                    // recent memory, so allow it to drop to the
20036                                    // LRU list if there is no other reason to keep
20037                                    // it around.  We'll also tag it with a label just
20038                                    // to help debug and undertand what is going on.
20039                                    if (adj > clientAdj) {
20040                                        adjType = "cch-bound-services";
20041                                    }
20042                                    clientAdj = adj;
20043                                }
20044                            }
20045                        }
20046                        if (adj > clientAdj) {
20047                            // If this process has recently shown UI, and
20048                            // the process that is binding to it is less
20049                            // important than being visible, then we don't
20050                            // care about the binding as much as we care
20051                            // about letting this process get into the LRU
20052                            // list to be killed and restarted if needed for
20053                            // memory.
20054                            if (app.hasShownUi && app != mHomeProcess
20055                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20056                                adjType = "cch-bound-ui-services";
20057                            } else {
20058                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
20059                                        |Context.BIND_IMPORTANT)) != 0) {
20060                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
20061                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
20062                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
20063                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
20064                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20065                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20066                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
20067                                    adj = clientAdj;
20068                                } else {
20069                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20070                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
20071                                    }
20072                                }
20073                                if (!client.cached) {
20074                                    app.cached = false;
20075                                }
20076                                adjType = "service";
20077                            }
20078                        }
20079                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20080                            // This will treat important bound services identically to
20081                            // the top app, which may behave differently than generic
20082                            // foreground work.
20083                            if (client.curSchedGroup > schedGroup) {
20084                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20085                                    schedGroup = client.curSchedGroup;
20086                                } else {
20087                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20088                                }
20089                            }
20090                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20091                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20092                                    // Special handling of clients who are in the top state.
20093                                    // We *may* want to consider this process to be in the
20094                                    // top state as well, but only if there is not another
20095                                    // reason for it to be running.  Being on the top is a
20096                                    // special state, meaning you are specifically running
20097                                    // for the current top app.  If the process is already
20098                                    // running in the background for some other reason, it
20099                                    // is more important to continue considering it to be
20100                                    // in the background state.
20101                                    mayBeTop = true;
20102                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20103                                } else {
20104                                    // Special handling for above-top states (persistent
20105                                    // processes).  These should not bring the current process
20106                                    // into the top state, since they are not on top.  Instead
20107                                    // give them the best state after that.
20108                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
20109                                        clientProcState =
20110                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20111                                    } else if (mWakefulness
20112                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
20113                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
20114                                                    != 0) {
20115                                        clientProcState =
20116                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20117                                    } else {
20118                                        clientProcState =
20119                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20120                                    }
20121                                }
20122                            }
20123                        } else {
20124                            if (clientProcState <
20125                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20126                                clientProcState =
20127                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20128                            }
20129                        }
20130                        if (procState > clientProcState) {
20131                            procState = clientProcState;
20132                        }
20133                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20134                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
20135                            app.pendingUiClean = true;
20136                        }
20137                        if (adjType != null) {
20138                            app.adjType = adjType;
20139                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20140                                    .REASON_SERVICE_IN_USE;
20141                            app.adjSource = cr.binding.client;
20142                            app.adjSourceProcState = clientProcState;
20143                            app.adjTarget = s.name;
20144                        }
20145                    }
20146                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
20147                        app.treatLikeActivity = true;
20148                    }
20149                    final ActivityRecord a = cr.activity;
20150                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
20151                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
20152                            (a.visible || a.state == ActivityState.RESUMED ||
20153                             a.state == ActivityState.PAUSING)) {
20154                            adj = ProcessList.FOREGROUND_APP_ADJ;
20155                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20156                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20157                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
20158                                } else {
20159                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20160                                }
20161                            }
20162                            app.cached = false;
20163                            app.adjType = "service";
20164                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20165                                    .REASON_SERVICE_IN_USE;
20166                            app.adjSource = a;
20167                            app.adjSourceProcState = procState;
20168                            app.adjTarget = s.name;
20169                        }
20170                    }
20171                }
20172            }
20173        }
20174
20175        for (int provi = app.pubProviders.size()-1;
20176                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20177                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20178                        || procState > ActivityManager.PROCESS_STATE_TOP);
20179                provi--) {
20180            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
20181            for (int i = cpr.connections.size()-1;
20182                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20183                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20184                            || procState > ActivityManager.PROCESS_STATE_TOP);
20185                    i--) {
20186                ContentProviderConnection conn = cpr.connections.get(i);
20187                ProcessRecord client = conn.client;
20188                if (client == app) {
20189                    // Being our own client is not interesting.
20190                    continue;
20191                }
20192                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
20193                int clientProcState = client.curProcState;
20194                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20195                    // If the other app is cached for any reason, for purposes here
20196                    // we are going to consider it empty.
20197                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20198                }
20199                if (adj > clientAdj) {
20200                    if (app.hasShownUi && app != mHomeProcess
20201                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20202                        app.adjType = "cch-ui-provider";
20203                    } else {
20204                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
20205                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
20206                        app.adjType = "provider";
20207                    }
20208                    app.cached &= client.cached;
20209                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20210                            .REASON_PROVIDER_IN_USE;
20211                    app.adjSource = client;
20212                    app.adjSourceProcState = clientProcState;
20213                    app.adjTarget = cpr.name;
20214                }
20215                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20216                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20217                        // Special handling of clients who are in the top state.
20218                        // We *may* want to consider this process to be in the
20219                        // top state as well, but only if there is not another
20220                        // reason for it to be running.  Being on the top is a
20221                        // special state, meaning you are specifically running
20222                        // for the current top app.  If the process is already
20223                        // running in the background for some other reason, it
20224                        // is more important to continue considering it to be
20225                        // in the background state.
20226                        mayBeTop = true;
20227                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20228                    } else {
20229                        // Special handling for above-top states (persistent
20230                        // processes).  These should not bring the current process
20231                        // into the top state, since they are not on top.  Instead
20232                        // give them the best state after that.
20233                        clientProcState =
20234                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20235                    }
20236                }
20237                if (procState > clientProcState) {
20238                    procState = clientProcState;
20239                }
20240                if (client.curSchedGroup > schedGroup) {
20241                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20242                }
20243            }
20244            // If the provider has external (non-framework) process
20245            // dependencies, ensure that its adjustment is at least
20246            // FOREGROUND_APP_ADJ.
20247            if (cpr.hasExternalProcessHandles()) {
20248                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
20249                    adj = ProcessList.FOREGROUND_APP_ADJ;
20250                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20251                    app.cached = false;
20252                    app.adjType = "provider";
20253                    app.adjTarget = cpr.name;
20254                }
20255                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20256                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20257                }
20258            }
20259        }
20260
20261        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
20262            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20263                adj = ProcessList.PREVIOUS_APP_ADJ;
20264                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20265                app.cached = false;
20266                app.adjType = "provider";
20267            }
20268            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20269                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20270            }
20271        }
20272
20273        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
20274            // A client of one of our services or providers is in the top state.  We
20275            // *may* want to be in the top state, but not if we are already running in
20276            // the background for some other reason.  For the decision here, we are going
20277            // to pick out a few specific states that we want to remain in when a client
20278            // is top (states that tend to be longer-term) and otherwise allow it to go
20279            // to the top state.
20280            switch (procState) {
20281                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
20282                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
20283                case ActivityManager.PROCESS_STATE_SERVICE:
20284                    // These all are longer-term states, so pull them up to the top
20285                    // of the background states, but not all the way to the top state.
20286                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20287                    break;
20288                default:
20289                    // Otherwise, top is a better choice, so take it.
20290                    procState = ActivityManager.PROCESS_STATE_TOP;
20291                    break;
20292            }
20293        }
20294
20295        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
20296            if (app.hasClientActivities) {
20297                // This is a cached process, but with client activities.  Mark it so.
20298                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
20299                app.adjType = "cch-client-act";
20300            } else if (app.treatLikeActivity) {
20301                // This is a cached process, but somebody wants us to treat it like it has
20302                // an activity, okay!
20303                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20304                app.adjType = "cch-as-act";
20305            }
20306        }
20307
20308        if (adj == ProcessList.SERVICE_ADJ) {
20309            if (doingAll) {
20310                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20311                mNewNumServiceProcs++;
20312                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20313                if (!app.serviceb) {
20314                    // This service isn't far enough down on the LRU list to
20315                    // normally be a B service, but if we are low on RAM and it
20316                    // is large we want to force it down since we would prefer to
20317                    // keep launcher over it.
20318                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20319                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20320                        app.serviceHighRam = true;
20321                        app.serviceb = true;
20322                        //Slog.i(TAG, "ADJ " + app + " high ram!");
20323                    } else {
20324                        mNewNumAServiceProcs++;
20325                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
20326                    }
20327                } else {
20328                    app.serviceHighRam = false;
20329                }
20330            }
20331            if (app.serviceb) {
20332                adj = ProcessList.SERVICE_B_ADJ;
20333            }
20334        }
20335
20336        app.curRawAdj = adj;
20337
20338        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20339        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20340        if (adj > app.maxAdj) {
20341            adj = app.maxAdj;
20342            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20343                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20344            }
20345        }
20346
20347        // Do final modification to adj.  Everything we do between here and applying
20348        // the final setAdj must be done in this function, because we will also use
20349        // it when computing the final cached adj later.  Note that we don't need to
20350        // worry about this for max adj above, since max adj will always be used to
20351        // keep it out of the cached vaues.
20352        app.curAdj = app.modifyRawOomAdj(adj);
20353        app.curSchedGroup = schedGroup;
20354        app.curProcState = procState;
20355        app.foregroundActivities = foregroundActivities;
20356
20357        return app.curRawAdj;
20358    }
20359
20360    /**
20361     * Record new PSS sample for a process.
20362     */
20363    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20364            long now) {
20365        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20366                swapPss * 1024);
20367        proc.lastPssTime = now;
20368        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20369        if (DEBUG_PSS) Slog.d(TAG_PSS,
20370                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20371                + " state=" + ProcessList.makeProcStateString(procState));
20372        if (proc.initialIdlePss == 0) {
20373            proc.initialIdlePss = pss;
20374        }
20375        proc.lastPss = pss;
20376        proc.lastSwapPss = swapPss;
20377        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20378            proc.lastCachedPss = pss;
20379            proc.lastCachedSwapPss = swapPss;
20380        }
20381
20382        final SparseArray<Pair<Long, String>> watchUids
20383                = mMemWatchProcesses.getMap().get(proc.processName);
20384        Long check = null;
20385        if (watchUids != null) {
20386            Pair<Long, String> val = watchUids.get(proc.uid);
20387            if (val == null) {
20388                val = watchUids.get(0);
20389            }
20390            if (val != null) {
20391                check = val.first;
20392            }
20393        }
20394        if (check != null) {
20395            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20396                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20397                if (!isDebuggable) {
20398                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20399                        isDebuggable = true;
20400                    }
20401                }
20402                if (isDebuggable) {
20403                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20404                    final ProcessRecord myProc = proc;
20405                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
20406                    mMemWatchDumpProcName = proc.processName;
20407                    mMemWatchDumpFile = heapdumpFile.toString();
20408                    mMemWatchDumpPid = proc.pid;
20409                    mMemWatchDumpUid = proc.uid;
20410                    BackgroundThread.getHandler().post(new Runnable() {
20411                        @Override
20412                        public void run() {
20413                            revokeUriPermission(ActivityThread.currentActivityThread()
20414                                            .getApplicationThread(),
20415                                    DumpHeapActivity.JAVA_URI,
20416                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
20417                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20418                                    UserHandle.myUserId());
20419                            ParcelFileDescriptor fd = null;
20420                            try {
20421                                heapdumpFile.delete();
20422                                fd = ParcelFileDescriptor.open(heapdumpFile,
20423                                        ParcelFileDescriptor.MODE_CREATE |
20424                                                ParcelFileDescriptor.MODE_TRUNCATE |
20425                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
20426                                                ParcelFileDescriptor.MODE_APPEND);
20427                                IApplicationThread thread = myProc.thread;
20428                                if (thread != null) {
20429                                    try {
20430                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
20431                                                "Requesting dump heap from "
20432                                                + myProc + " to " + heapdumpFile);
20433                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
20434                                    } catch (RemoteException e) {
20435                                    }
20436                                }
20437                            } catch (FileNotFoundException e) {
20438                                e.printStackTrace();
20439                            } finally {
20440                                if (fd != null) {
20441                                    try {
20442                                        fd.close();
20443                                    } catch (IOException e) {
20444                                    }
20445                                }
20446                            }
20447                        }
20448                    });
20449                } else {
20450                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20451                            + ", but debugging not enabled");
20452                }
20453            }
20454        }
20455    }
20456
20457    /**
20458     * Schedule PSS collection of a process.
20459     */
20460    void requestPssLocked(ProcessRecord proc, int procState) {
20461        if (mPendingPssProcesses.contains(proc)) {
20462            return;
20463        }
20464        if (mPendingPssProcesses.size() == 0) {
20465            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20466        }
20467        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20468        proc.pssProcState = procState;
20469        mPendingPssProcesses.add(proc);
20470    }
20471
20472    /**
20473     * Schedule PSS collection of all processes.
20474     */
20475    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20476        if (!always) {
20477            if (now < (mLastFullPssTime +
20478                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20479                return;
20480            }
20481        }
20482        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20483        mLastFullPssTime = now;
20484        mFullPssPending = true;
20485        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20486        mPendingPssProcesses.clear();
20487        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20488            ProcessRecord app = mLruProcesses.get(i);
20489            if (app.thread == null
20490                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20491                continue;
20492            }
20493            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20494                app.pssProcState = app.setProcState;
20495                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20496                        mTestPssMode, isSleepingLocked(), now);
20497                mPendingPssProcesses.add(app);
20498            }
20499        }
20500        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20501    }
20502
20503    public void setTestPssMode(boolean enabled) {
20504        synchronized (this) {
20505            mTestPssMode = enabled;
20506            if (enabled) {
20507                // Whenever we enable the mode, we want to take a snapshot all of current
20508                // process mem use.
20509                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20510            }
20511        }
20512    }
20513
20514    /**
20515     * Ask a given process to GC right now.
20516     */
20517    final void performAppGcLocked(ProcessRecord app) {
20518        try {
20519            app.lastRequestedGc = SystemClock.uptimeMillis();
20520            if (app.thread != null) {
20521                if (app.reportLowMemory) {
20522                    app.reportLowMemory = false;
20523                    app.thread.scheduleLowMemory();
20524                } else {
20525                    app.thread.processInBackground();
20526                }
20527            }
20528        } catch (Exception e) {
20529            // whatever.
20530        }
20531    }
20532
20533    /**
20534     * Returns true if things are idle enough to perform GCs.
20535     */
20536    private final boolean canGcNowLocked() {
20537        boolean processingBroadcasts = false;
20538        for (BroadcastQueue q : mBroadcastQueues) {
20539            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20540                processingBroadcasts = true;
20541            }
20542        }
20543        return !processingBroadcasts
20544                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20545    }
20546
20547    /**
20548     * Perform GCs on all processes that are waiting for it, but only
20549     * if things are idle.
20550     */
20551    final void performAppGcsLocked() {
20552        final int N = mProcessesToGc.size();
20553        if (N <= 0) {
20554            return;
20555        }
20556        if (canGcNowLocked()) {
20557            while (mProcessesToGc.size() > 0) {
20558                ProcessRecord proc = mProcessesToGc.remove(0);
20559                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20560                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20561                            <= SystemClock.uptimeMillis()) {
20562                        // To avoid spamming the system, we will GC processes one
20563                        // at a time, waiting a few seconds between each.
20564                        performAppGcLocked(proc);
20565                        scheduleAppGcsLocked();
20566                        return;
20567                    } else {
20568                        // It hasn't been long enough since we last GCed this
20569                        // process...  put it in the list to wait for its time.
20570                        addProcessToGcListLocked(proc);
20571                        break;
20572                    }
20573                }
20574            }
20575
20576            scheduleAppGcsLocked();
20577        }
20578    }
20579
20580    /**
20581     * If all looks good, perform GCs on all processes waiting for them.
20582     */
20583    final void performAppGcsIfAppropriateLocked() {
20584        if (canGcNowLocked()) {
20585            performAppGcsLocked();
20586            return;
20587        }
20588        // Still not idle, wait some more.
20589        scheduleAppGcsLocked();
20590    }
20591
20592    /**
20593     * Schedule the execution of all pending app GCs.
20594     */
20595    final void scheduleAppGcsLocked() {
20596        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20597
20598        if (mProcessesToGc.size() > 0) {
20599            // Schedule a GC for the time to the next process.
20600            ProcessRecord proc = mProcessesToGc.get(0);
20601            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20602
20603            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20604            long now = SystemClock.uptimeMillis();
20605            if (when < (now+GC_TIMEOUT)) {
20606                when = now + GC_TIMEOUT;
20607            }
20608            mHandler.sendMessageAtTime(msg, when);
20609        }
20610    }
20611
20612    /**
20613     * Add a process to the array of processes waiting to be GCed.  Keeps the
20614     * list in sorted order by the last GC time.  The process can't already be
20615     * on the list.
20616     */
20617    final void addProcessToGcListLocked(ProcessRecord proc) {
20618        boolean added = false;
20619        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20620            if (mProcessesToGc.get(i).lastRequestedGc <
20621                    proc.lastRequestedGc) {
20622                added = true;
20623                mProcessesToGc.add(i+1, proc);
20624                break;
20625            }
20626        }
20627        if (!added) {
20628            mProcessesToGc.add(0, proc);
20629        }
20630    }
20631
20632    /**
20633     * Set up to ask a process to GC itself.  This will either do it
20634     * immediately, or put it on the list of processes to gc the next
20635     * time things are idle.
20636     */
20637    final void scheduleAppGcLocked(ProcessRecord app) {
20638        long now = SystemClock.uptimeMillis();
20639        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20640            return;
20641        }
20642        if (!mProcessesToGc.contains(app)) {
20643            addProcessToGcListLocked(app);
20644            scheduleAppGcsLocked();
20645        }
20646    }
20647
20648    final void checkExcessivePowerUsageLocked(boolean doKills) {
20649        updateCpuStatsNow();
20650
20651        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20652        boolean doWakeKills = doKills;
20653        boolean doCpuKills = doKills;
20654        if (mLastPowerCheckRealtime == 0) {
20655            doWakeKills = false;
20656        }
20657        if (mLastPowerCheckUptime == 0) {
20658            doCpuKills = false;
20659        }
20660        if (stats.isScreenOn()) {
20661            doWakeKills = false;
20662        }
20663        final long curRealtime = SystemClock.elapsedRealtime();
20664        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20665        final long curUptime = SystemClock.uptimeMillis();
20666        final long uptimeSince = curUptime - mLastPowerCheckUptime;
20667        mLastPowerCheckRealtime = curRealtime;
20668        mLastPowerCheckUptime = curUptime;
20669        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20670            doWakeKills = false;
20671        }
20672        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20673            doCpuKills = false;
20674        }
20675        int i = mLruProcesses.size();
20676        while (i > 0) {
20677            i--;
20678            ProcessRecord app = mLruProcesses.get(i);
20679            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20680                long wtime;
20681                synchronized (stats) {
20682                    wtime = stats.getProcessWakeTime(app.info.uid,
20683                            app.pid, curRealtime);
20684                }
20685                long wtimeUsed = wtime - app.lastWakeTime;
20686                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20687                if (DEBUG_POWER) {
20688                    StringBuilder sb = new StringBuilder(128);
20689                    sb.append("Wake for ");
20690                    app.toShortString(sb);
20691                    sb.append(": over ");
20692                    TimeUtils.formatDuration(realtimeSince, sb);
20693                    sb.append(" used ");
20694                    TimeUtils.formatDuration(wtimeUsed, sb);
20695                    sb.append(" (");
20696                    sb.append((wtimeUsed*100)/realtimeSince);
20697                    sb.append("%)");
20698                    Slog.i(TAG_POWER, sb.toString());
20699                    sb.setLength(0);
20700                    sb.append("CPU for ");
20701                    app.toShortString(sb);
20702                    sb.append(": over ");
20703                    TimeUtils.formatDuration(uptimeSince, sb);
20704                    sb.append(" used ");
20705                    TimeUtils.formatDuration(cputimeUsed, sb);
20706                    sb.append(" (");
20707                    sb.append((cputimeUsed*100)/uptimeSince);
20708                    sb.append("%)");
20709                    Slog.i(TAG_POWER, sb.toString());
20710                }
20711                // If a process has held a wake lock for more
20712                // than 50% of the time during this period,
20713                // that sounds bad.  Kill!
20714                if (doWakeKills && realtimeSince > 0
20715                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
20716                    synchronized (stats) {
20717                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20718                                realtimeSince, wtimeUsed);
20719                    }
20720                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20721                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20722                } else if (doCpuKills && uptimeSince > 0
20723                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
20724                    synchronized (stats) {
20725                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20726                                uptimeSince, cputimeUsed);
20727                    }
20728                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20729                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20730                } else {
20731                    app.lastWakeTime = wtime;
20732                    app.lastCpuTime = app.curCpuTime;
20733                }
20734            }
20735        }
20736    }
20737
20738    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20739            long nowElapsed) {
20740        boolean success = true;
20741
20742        if (app.curRawAdj != app.setRawAdj) {
20743            app.setRawAdj = app.curRawAdj;
20744        }
20745
20746        int changes = 0;
20747
20748        if (app.curAdj != app.setAdj) {
20749            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20750            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20751                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20752                    + app.adjType);
20753            app.setAdj = app.curAdj;
20754            app.verifiedAdj = ProcessList.INVALID_ADJ;
20755        }
20756
20757        if (app.setSchedGroup != app.curSchedGroup) {
20758            int oldSchedGroup = app.setSchedGroup;
20759            app.setSchedGroup = app.curSchedGroup;
20760            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20761                    "Setting sched group of " + app.processName
20762                    + " to " + app.curSchedGroup);
20763            if (app.waitingToKill != null && app.curReceivers.isEmpty()
20764                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20765                app.kill(app.waitingToKill, true);
20766                success = false;
20767            } else {
20768                int processGroup;
20769                switch (app.curSchedGroup) {
20770                    case ProcessList.SCHED_GROUP_BACKGROUND:
20771                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20772                        break;
20773                    case ProcessList.SCHED_GROUP_TOP_APP:
20774                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20775                        processGroup = Process.THREAD_GROUP_TOP_APP;
20776                        break;
20777                    default:
20778                        processGroup = Process.THREAD_GROUP_DEFAULT;
20779                        break;
20780                }
20781                long oldId = Binder.clearCallingIdentity();
20782                try {
20783                    Process.setProcessGroup(app.pid, processGroup);
20784                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20785                        // do nothing if we already switched to RT
20786                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20787                            // Switch VR thread for app to SCHED_FIFO
20788                            if (mInVrMode && app.vrThreadTid != 0) {
20789                                try {
20790                                    Process.setThreadScheduler(app.vrThreadTid,
20791                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20792                                } catch (IllegalArgumentException e) {
20793                                    // thread died, ignore
20794                                }
20795                            }
20796                            if (mUseFifoUiScheduling) {
20797                                // Switch UI pipeline for app to SCHED_FIFO
20798                                app.savedPriority = Process.getThreadPriority(app.pid);
20799                                try {
20800                                    Process.setThreadScheduler(app.pid,
20801                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20802                                } catch (IllegalArgumentException e) {
20803                                    // thread died, ignore
20804                                }
20805                                if (app.renderThreadTid != 0) {
20806                                    try {
20807                                        Process.setThreadScheduler(app.renderThreadTid,
20808                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20809                                    } catch (IllegalArgumentException e) {
20810                                        // thread died, ignore
20811                                    }
20812                                    if (DEBUG_OOM_ADJ) {
20813                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
20814                                            app.renderThreadTid + ") to FIFO");
20815                                    }
20816                                } else {
20817                                    if (DEBUG_OOM_ADJ) {
20818                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
20819                                    }
20820                                }
20821                            } else {
20822                                // Boost priority for top app UI and render threads
20823                                Process.setThreadPriority(app.pid, -10);
20824                                if (app.renderThreadTid != 0) {
20825                                    try {
20826                                        Process.setThreadPriority(app.renderThreadTid, -10);
20827                                    } catch (IllegalArgumentException e) {
20828                                        // thread died, ignore
20829                                    }
20830                                }
20831                            }
20832                        }
20833                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20834                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20835                        // Reset VR thread to SCHED_OTHER
20836                        // Safe to do even if we're not in VR mode
20837                        if (app.vrThreadTid != 0) {
20838                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20839                        }
20840                        if (mUseFifoUiScheduling) {
20841                            // Reset UI pipeline to SCHED_OTHER
20842                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20843                            Process.setThreadPriority(app.pid, app.savedPriority);
20844                            if (app.renderThreadTid != 0) {
20845                                Process.setThreadScheduler(app.renderThreadTid,
20846                                    Process.SCHED_OTHER, 0);
20847                                Process.setThreadPriority(app.renderThreadTid, -4);
20848                            }
20849                        } else {
20850                            // Reset priority for top app UI and render threads
20851                            Process.setThreadPriority(app.pid, 0);
20852                            if (app.renderThreadTid != 0) {
20853                                Process.setThreadPriority(app.renderThreadTid, 0);
20854                            }
20855                        }
20856                    }
20857                } catch (Exception e) {
20858                    Slog.w(TAG, "Failed setting process group of " + app.pid
20859                            + " to " + app.curSchedGroup);
20860                    e.printStackTrace();
20861                } finally {
20862                    Binder.restoreCallingIdentity(oldId);
20863                }
20864            }
20865        }
20866        if (app.repForegroundActivities != app.foregroundActivities) {
20867            app.repForegroundActivities = app.foregroundActivities;
20868            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20869        }
20870        if (app.repProcState != app.curProcState) {
20871            app.repProcState = app.curProcState;
20872            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20873            if (app.thread != null) {
20874                try {
20875                    if (false) {
20876                        //RuntimeException h = new RuntimeException("here");
20877                        Slog.i(TAG, "Sending new process state " + app.repProcState
20878                                + " to " + app /*, h*/);
20879                    }
20880                    app.thread.setProcessState(app.repProcState);
20881                } catch (RemoteException e) {
20882                }
20883            }
20884        }
20885        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20886                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20887            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20888                // Experimental code to more aggressively collect pss while
20889                // running test...  the problem is that this tends to collect
20890                // the data right when a process is transitioning between process
20891                // states, which well tend to give noisy data.
20892                long start = SystemClock.uptimeMillis();
20893                long pss = Debug.getPss(app.pid, mTmpLong, null);
20894                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20895                mPendingPssProcesses.remove(app);
20896                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20897                        + " to " + app.curProcState + ": "
20898                        + (SystemClock.uptimeMillis()-start) + "ms");
20899            }
20900            app.lastStateTime = now;
20901            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20902                    mTestPssMode, isSleepingLocked(), now);
20903            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20904                    + ProcessList.makeProcStateString(app.setProcState) + " to "
20905                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20906                    + (app.nextPssTime-now) + ": " + app);
20907        } else {
20908            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20909                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20910                    mTestPssMode)))) {
20911                requestPssLocked(app, app.setProcState);
20912                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20913                        mTestPssMode, isSleepingLocked(), now);
20914            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20915                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20916        }
20917        if (app.setProcState != app.curProcState) {
20918            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20919                    "Proc state change of " + app.processName
20920                            + " to " + app.curProcState);
20921            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20922            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20923            if (setImportant && !curImportant) {
20924                // This app is no longer something we consider important enough to allow to
20925                // use arbitrary amounts of battery power.  Note
20926                // its current wake lock time to later know to kill it if
20927                // it is not behaving well.
20928                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20929                synchronized (stats) {
20930                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20931                            app.pid, nowElapsed);
20932                }
20933                app.lastCpuTime = app.curCpuTime;
20934
20935            }
20936            // Inform UsageStats of important process state change
20937            // Must be called before updating setProcState
20938            maybeUpdateUsageStatsLocked(app, nowElapsed);
20939
20940            app.setProcState = app.curProcState;
20941            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20942                app.notCachedSinceIdle = false;
20943            }
20944            if (!doingAll) {
20945                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20946            } else {
20947                app.procStateChanged = true;
20948            }
20949        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20950                > USAGE_STATS_INTERACTION_INTERVAL) {
20951            // For apps that sit around for a long time in the interactive state, we need
20952            // to report this at least once a day so they don't go idle.
20953            maybeUpdateUsageStatsLocked(app, nowElapsed);
20954        }
20955
20956        if (changes != 0) {
20957            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20958                    "Changes in " + app + ": " + changes);
20959            int i = mPendingProcessChanges.size()-1;
20960            ProcessChangeItem item = null;
20961            while (i >= 0) {
20962                item = mPendingProcessChanges.get(i);
20963                if (item.pid == app.pid) {
20964                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20965                            "Re-using existing item: " + item);
20966                    break;
20967                }
20968                i--;
20969            }
20970            if (i < 0) {
20971                // No existing item in pending changes; need a new one.
20972                final int NA = mAvailProcessChanges.size();
20973                if (NA > 0) {
20974                    item = mAvailProcessChanges.remove(NA-1);
20975                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20976                            "Retrieving available item: " + item);
20977                } else {
20978                    item = new ProcessChangeItem();
20979                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20980                            "Allocating new item: " + item);
20981                }
20982                item.changes = 0;
20983                item.pid = app.pid;
20984                item.uid = app.info.uid;
20985                if (mPendingProcessChanges.size() == 0) {
20986                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20987                            "*** Enqueueing dispatch processes changed!");
20988                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20989                }
20990                mPendingProcessChanges.add(item);
20991            }
20992            item.changes |= changes;
20993            item.processState = app.repProcState;
20994            item.foregroundActivities = app.repForegroundActivities;
20995            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20996                    "Item " + Integer.toHexString(System.identityHashCode(item))
20997                    + " " + app.toShortString() + ": changes=" + item.changes
20998                    + " procState=" + item.processState
20999                    + " foreground=" + item.foregroundActivities
21000                    + " type=" + app.adjType + " source=" + app.adjSource
21001                    + " target=" + app.adjTarget);
21002        }
21003
21004        return success;
21005    }
21006
21007    private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
21008        final UidRecord.ChangeItem pendingChange;
21009        if (uidRec == null || uidRec.pendingChange == null) {
21010            if (mPendingUidChanges.size() == 0) {
21011                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21012                        "*** Enqueueing dispatch uid changed!");
21013                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
21014            }
21015            final int NA = mAvailUidChanges.size();
21016            if (NA > 0) {
21017                pendingChange = mAvailUidChanges.remove(NA-1);
21018                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21019                        "Retrieving available item: " + pendingChange);
21020            } else {
21021                pendingChange = new UidRecord.ChangeItem();
21022                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21023                        "Allocating new item: " + pendingChange);
21024            }
21025            if (uidRec != null) {
21026                uidRec.pendingChange = pendingChange;
21027                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
21028                    // If this uid is going away, and we haven't yet reported it is gone,
21029                    // then do so now.
21030                    change = UidRecord.CHANGE_GONE_IDLE;
21031                }
21032            } else if (uid < 0) {
21033                throw new IllegalArgumentException("No UidRecord or uid");
21034            }
21035            pendingChange.uidRecord = uidRec;
21036            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
21037            mPendingUidChanges.add(pendingChange);
21038        } else {
21039            pendingChange = uidRec.pendingChange;
21040            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
21041                change = UidRecord.CHANGE_GONE_IDLE;
21042            }
21043        }
21044        pendingChange.change = change;
21045        pendingChange.processState = uidRec != null
21046                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
21047        pendingChange.ephemeral = uidRec.ephemeral;
21048
21049        // Directly update the power manager, since we sit on top of it and it is critical
21050        // it be kept in sync (so wake locks will be held as soon as appropriate).
21051        if (mLocalPowerManager != null) {
21052            switch (change) {
21053                case UidRecord.CHANGE_GONE:
21054                case UidRecord.CHANGE_GONE_IDLE:
21055                    mLocalPowerManager.uidGone(pendingChange.uid);
21056                    break;
21057                case UidRecord.CHANGE_IDLE:
21058                    mLocalPowerManager.uidIdle(pendingChange.uid);
21059                    break;
21060                case UidRecord.CHANGE_ACTIVE:
21061                    mLocalPowerManager.uidActive(pendingChange.uid);
21062                    break;
21063                default:
21064                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
21065                            pendingChange.processState);
21066                    break;
21067            }
21068        }
21069    }
21070
21071    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
21072            String authority) {
21073        if (app == null) return;
21074        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21075            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
21076            if (userState == null) return;
21077            final long now = SystemClock.elapsedRealtime();
21078            Long lastReported = userState.mProviderLastReportedFg.get(authority);
21079            if (lastReported == null || lastReported < now - 60 * 1000L) {
21080                if (mSystemReady) {
21081                    // Cannot touch the user stats if not system ready
21082                    mUsageStatsService.reportContentProviderUsage(
21083                            authority, providerPkgName, app.userId);
21084                }
21085                userState.mProviderLastReportedFg.put(authority, now);
21086            }
21087        }
21088    }
21089
21090    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
21091        if (DEBUG_USAGE_STATS) {
21092            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
21093                    + "] state changes: old = " + app.setProcState + ", new = "
21094                    + app.curProcState);
21095        }
21096        if (mUsageStatsService == null) {
21097            return;
21098        }
21099        boolean isInteraction;
21100        // To avoid some abuse patterns, we are going to be careful about what we consider
21101        // to be an app interaction.  Being the top activity doesn't count while the display
21102        // is sleeping, nor do short foreground services.
21103        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
21104            isInteraction = true;
21105            app.fgInteractionTime = 0;
21106        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
21107            if (app.fgInteractionTime == 0) {
21108                app.fgInteractionTime = nowElapsed;
21109                isInteraction = false;
21110            } else {
21111                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
21112            }
21113        } else {
21114            // If the app was being forced to the foreground, by say a Toast, then
21115            // no need to treat it as an interaction
21116            isInteraction = app.forcingToForeground == null
21117                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21118            app.fgInteractionTime = 0;
21119        }
21120        if (isInteraction && (!app.reportedInteraction
21121                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
21122            app.interactionEventTime = nowElapsed;
21123            String[] packages = app.getPackageList();
21124            if (packages != null) {
21125                for (int i = 0; i < packages.length; i++) {
21126                    mUsageStatsService.reportEvent(packages[i], app.userId,
21127                            UsageEvents.Event.SYSTEM_INTERACTION);
21128                }
21129            }
21130        }
21131        app.reportedInteraction = isInteraction;
21132        if (!isInteraction) {
21133            app.interactionEventTime = 0;
21134        }
21135    }
21136
21137    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
21138        if (proc.thread != null) {
21139            if (proc.baseProcessTracker != null) {
21140                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
21141            }
21142        }
21143    }
21144
21145    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
21146            ProcessRecord TOP_APP, boolean doingAll, long now) {
21147        if (app.thread == null) {
21148            return false;
21149        }
21150
21151        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
21152
21153        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
21154    }
21155
21156    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
21157            boolean oomAdj) {
21158        if (isForeground != proc.foregroundServices) {
21159            proc.foregroundServices = isForeground;
21160            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
21161                    proc.info.uid);
21162            if (isForeground) {
21163                if (curProcs == null) {
21164                    curProcs = new ArrayList<ProcessRecord>();
21165                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
21166                }
21167                if (!curProcs.contains(proc)) {
21168                    curProcs.add(proc);
21169                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
21170                            proc.info.packageName, proc.info.uid);
21171                }
21172            } else {
21173                if (curProcs != null) {
21174                    if (curProcs.remove(proc)) {
21175                        mBatteryStatsService.noteEvent(
21176                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
21177                                proc.info.packageName, proc.info.uid);
21178                        if (curProcs.size() <= 0) {
21179                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
21180                        }
21181                    }
21182                }
21183            }
21184            if (oomAdj) {
21185                updateOomAdjLocked();
21186            }
21187        }
21188    }
21189
21190    private final ActivityRecord resumedAppLocked() {
21191        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
21192        String pkg;
21193        int uid;
21194        if (act != null) {
21195            pkg = act.packageName;
21196            uid = act.info.applicationInfo.uid;
21197        } else {
21198            pkg = null;
21199            uid = -1;
21200        }
21201        // Has the UID or resumed package name changed?
21202        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
21203                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
21204            if (mCurResumedPackage != null) {
21205                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
21206                        mCurResumedPackage, mCurResumedUid);
21207            }
21208            mCurResumedPackage = pkg;
21209            mCurResumedUid = uid;
21210            if (mCurResumedPackage != null) {
21211                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
21212                        mCurResumedPackage, mCurResumedUid);
21213            }
21214        }
21215        return act;
21216    }
21217
21218    final boolean updateOomAdjLocked(ProcessRecord app) {
21219        final ActivityRecord TOP_ACT = resumedAppLocked();
21220        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21221        final boolean wasCached = app.cached;
21222
21223        mAdjSeq++;
21224
21225        // This is the desired cached adjusment we want to tell it to use.
21226        // If our app is currently cached, we know it, and that is it.  Otherwise,
21227        // we don't know it yet, and it needs to now be cached we will then
21228        // need to do a complete oom adj.
21229        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
21230                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
21231        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
21232                SystemClock.uptimeMillis());
21233        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
21234            // Changed to/from cached state, so apps after it in the LRU
21235            // list may also be changed.
21236            updateOomAdjLocked();
21237        }
21238        return success;
21239    }
21240
21241    final void updateOomAdjLocked() {
21242        final ActivityRecord TOP_ACT = resumedAppLocked();
21243        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21244        final long now = SystemClock.uptimeMillis();
21245        final long nowElapsed = SystemClock.elapsedRealtime();
21246        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
21247        final int N = mLruProcesses.size();
21248
21249        if (false) {
21250            RuntimeException e = new RuntimeException();
21251            e.fillInStackTrace();
21252            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
21253        }
21254
21255        // Reset state in all uid records.
21256        for (int i=mActiveUids.size()-1; i>=0; i--) {
21257            final UidRecord uidRec = mActiveUids.valueAt(i);
21258            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21259                    "Starting update of " + uidRec);
21260            uidRec.reset();
21261        }
21262
21263        mStackSupervisor.rankTaskLayersIfNeeded();
21264
21265        mAdjSeq++;
21266        mNewNumServiceProcs = 0;
21267        mNewNumAServiceProcs = 0;
21268
21269        final int emptyProcessLimit;
21270        final int cachedProcessLimit;
21271        if (mProcessLimit <= 0) {
21272            emptyProcessLimit = cachedProcessLimit = 0;
21273        } else if (mProcessLimit == 1) {
21274            emptyProcessLimit = 1;
21275            cachedProcessLimit = 0;
21276        } else {
21277            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
21278            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
21279        }
21280
21281        // Let's determine how many processes we have running vs.
21282        // how many slots we have for background processes; we may want
21283        // to put multiple processes in a slot of there are enough of
21284        // them.
21285        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
21286                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
21287        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
21288        if (numEmptyProcs > cachedProcessLimit) {
21289            // If there are more empty processes than our limit on cached
21290            // processes, then use the cached process limit for the factor.
21291            // This ensures that the really old empty processes get pushed
21292            // down to the bottom, so if we are running low on memory we will
21293            // have a better chance at keeping around more cached processes
21294            // instead of a gazillion empty processes.
21295            numEmptyProcs = cachedProcessLimit;
21296        }
21297        int emptyFactor = numEmptyProcs/numSlots;
21298        if (emptyFactor < 1) emptyFactor = 1;
21299        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
21300        if (cachedFactor < 1) cachedFactor = 1;
21301        int stepCached = 0;
21302        int stepEmpty = 0;
21303        int numCached = 0;
21304        int numEmpty = 0;
21305        int numTrimming = 0;
21306
21307        mNumNonCachedProcs = 0;
21308        mNumCachedHiddenProcs = 0;
21309
21310        // First update the OOM adjustment for each of the
21311        // application processes based on their current state.
21312        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
21313        int nextCachedAdj = curCachedAdj+1;
21314        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
21315        int nextEmptyAdj = curEmptyAdj+2;
21316        for (int i=N-1; i>=0; i--) {
21317            ProcessRecord app = mLruProcesses.get(i);
21318            if (!app.killedByAm && app.thread != null) {
21319                app.procStateChanged = false;
21320                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
21321
21322                // If we haven't yet assigned the final cached adj
21323                // to the process, do that now.
21324                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21325                    switch (app.curProcState) {
21326                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21327                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21328                            // This process is a cached process holding activities...
21329                            // assign it the next cached value for that type, and then
21330                            // step that cached level.
21331                            app.curRawAdj = curCachedAdj;
21332                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21333                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21334                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21335                                    + ")");
21336                            if (curCachedAdj != nextCachedAdj) {
21337                                stepCached++;
21338                                if (stepCached >= cachedFactor) {
21339                                    stepCached = 0;
21340                                    curCachedAdj = nextCachedAdj;
21341                                    nextCachedAdj += 2;
21342                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21343                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21344                                    }
21345                                }
21346                            }
21347                            break;
21348                        default:
21349                            // For everything else, assign next empty cached process
21350                            // level and bump that up.  Note that this means that
21351                            // long-running services that have dropped down to the
21352                            // cached level will be treated as empty (since their process
21353                            // state is still as a service), which is what we want.
21354                            app.curRawAdj = curEmptyAdj;
21355                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21356                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21357                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21358                                    + ")");
21359                            if (curEmptyAdj != nextEmptyAdj) {
21360                                stepEmpty++;
21361                                if (stepEmpty >= emptyFactor) {
21362                                    stepEmpty = 0;
21363                                    curEmptyAdj = nextEmptyAdj;
21364                                    nextEmptyAdj += 2;
21365                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21366                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21367                                    }
21368                                }
21369                            }
21370                            break;
21371                    }
21372                }
21373
21374                applyOomAdjLocked(app, true, now, nowElapsed);
21375
21376                // Count the number of process types.
21377                switch (app.curProcState) {
21378                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21379                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21380                        mNumCachedHiddenProcs++;
21381                        numCached++;
21382                        if (numCached > cachedProcessLimit) {
21383                            app.kill("cached #" + numCached, true);
21384                        }
21385                        break;
21386                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21387                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21388                                && app.lastActivityTime < oldTime) {
21389                            app.kill("empty for "
21390                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21391                                    / 1000) + "s", true);
21392                        } else {
21393                            numEmpty++;
21394                            if (numEmpty > emptyProcessLimit) {
21395                                app.kill("empty #" + numEmpty, true);
21396                            }
21397                        }
21398                        break;
21399                    default:
21400                        mNumNonCachedProcs++;
21401                        break;
21402                }
21403
21404                if (app.isolated && app.services.size() <= 0) {
21405                    // If this is an isolated process, and there are no
21406                    // services running in it, then the process is no longer
21407                    // needed.  We agressively kill these because we can by
21408                    // definition not re-use the same process again, and it is
21409                    // good to avoid having whatever code was running in them
21410                    // left sitting around after no longer needed.
21411                    app.kill("isolated not needed", true);
21412                } else {
21413                    // Keeping this process, update its uid.
21414                    final UidRecord uidRec = app.uidRecord;
21415                    if (uidRec != null) {
21416                        uidRec.ephemeral = app.info.isEphemeralApp();
21417                        if (uidRec.curProcState > app.curProcState) {
21418                            uidRec.curProcState = app.curProcState;
21419                        }
21420                    }
21421                }
21422
21423                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21424                        && !app.killedByAm) {
21425                    numTrimming++;
21426                }
21427            }
21428        }
21429
21430        mNumServiceProcs = mNewNumServiceProcs;
21431
21432        // Now determine the memory trimming level of background processes.
21433        // Unfortunately we need to start at the back of the list to do this
21434        // properly.  We only do this if the number of background apps we
21435        // are managing to keep around is less than half the maximum we desire;
21436        // if we are keeping a good number around, we'll let them use whatever
21437        // memory they want.
21438        final int numCachedAndEmpty = numCached + numEmpty;
21439        int memFactor;
21440        if (numCached <= ProcessList.TRIM_CACHED_APPS
21441                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21442            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21443                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21444            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21445                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21446            } else {
21447                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21448            }
21449        } else {
21450            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21451        }
21452        // We always allow the memory level to go up (better).  We only allow it to go
21453        // down if we are in a state where that is allowed, *and* the total number of processes
21454        // has gone down since last time.
21455        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21456                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21457                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21458        if (memFactor > mLastMemoryLevel) {
21459            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21460                memFactor = mLastMemoryLevel;
21461                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21462            }
21463        }
21464        if (memFactor != mLastMemoryLevel) {
21465            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21466        }
21467        mLastMemoryLevel = memFactor;
21468        mLastNumProcesses = mLruProcesses.size();
21469        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21470        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21471        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21472            if (mLowRamStartTime == 0) {
21473                mLowRamStartTime = now;
21474            }
21475            int step = 0;
21476            int fgTrimLevel;
21477            switch (memFactor) {
21478                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21479                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21480                    break;
21481                case ProcessStats.ADJ_MEM_FACTOR_LOW:
21482                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21483                    break;
21484                default:
21485                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21486                    break;
21487            }
21488            int factor = numTrimming/3;
21489            int minFactor = 2;
21490            if (mHomeProcess != null) minFactor++;
21491            if (mPreviousProcess != null) minFactor++;
21492            if (factor < minFactor) factor = minFactor;
21493            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21494            for (int i=N-1; i>=0; i--) {
21495                ProcessRecord app = mLruProcesses.get(i);
21496                if (allChanged || app.procStateChanged) {
21497                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21498                    app.procStateChanged = false;
21499                }
21500                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21501                        && !app.killedByAm) {
21502                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
21503                        try {
21504                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21505                                    "Trimming memory of " + app.processName + " to " + curLevel);
21506                            app.thread.scheduleTrimMemory(curLevel);
21507                        } catch (RemoteException e) {
21508                        }
21509                        if (false) {
21510                            // For now we won't do this; our memory trimming seems
21511                            // to be good enough at this point that destroying
21512                            // activities causes more harm than good.
21513                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21514                                    && app != mHomeProcess && app != mPreviousProcess) {
21515                                // Need to do this on its own message because the stack may not
21516                                // be in a consistent state at this point.
21517                                // For these apps we will also finish their activities
21518                                // to help them free memory.
21519                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21520                            }
21521                        }
21522                    }
21523                    app.trimMemoryLevel = curLevel;
21524                    step++;
21525                    if (step >= factor) {
21526                        step = 0;
21527                        switch (curLevel) {
21528                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21529                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21530                                break;
21531                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21532                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21533                                break;
21534                        }
21535                    }
21536                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21537                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21538                            && app.thread != null) {
21539                        try {
21540                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21541                                    "Trimming memory of heavy-weight " + app.processName
21542                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21543                            app.thread.scheduleTrimMemory(
21544                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21545                        } catch (RemoteException e) {
21546                        }
21547                    }
21548                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21549                } else {
21550                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21551                            || app.systemNoUi) && app.pendingUiClean) {
21552                        // If this application is now in the background and it
21553                        // had done UI, then give it the special trim level to
21554                        // have it free UI resources.
21555                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21556                        if (app.trimMemoryLevel < level && app.thread != null) {
21557                            try {
21558                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21559                                        "Trimming memory of bg-ui " + app.processName
21560                                        + " to " + level);
21561                                app.thread.scheduleTrimMemory(level);
21562                            } catch (RemoteException e) {
21563                            }
21564                        }
21565                        app.pendingUiClean = false;
21566                    }
21567                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21568                        try {
21569                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21570                                    "Trimming memory of fg " + app.processName
21571                                    + " to " + fgTrimLevel);
21572                            app.thread.scheduleTrimMemory(fgTrimLevel);
21573                        } catch (RemoteException e) {
21574                        }
21575                    }
21576                    app.trimMemoryLevel = fgTrimLevel;
21577                }
21578            }
21579        } else {
21580            if (mLowRamStartTime != 0) {
21581                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21582                mLowRamStartTime = 0;
21583            }
21584            for (int i=N-1; i>=0; i--) {
21585                ProcessRecord app = mLruProcesses.get(i);
21586                if (allChanged || app.procStateChanged) {
21587                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
21588                    app.procStateChanged = false;
21589                }
21590                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21591                        || app.systemNoUi) && app.pendingUiClean) {
21592                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21593                            && app.thread != null) {
21594                        try {
21595                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21596                                    "Trimming memory of ui hidden " + app.processName
21597                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21598                            app.thread.scheduleTrimMemory(
21599                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21600                        } catch (RemoteException e) {
21601                        }
21602                    }
21603                    app.pendingUiClean = false;
21604                }
21605                app.trimMemoryLevel = 0;
21606            }
21607        }
21608
21609        if (mAlwaysFinishActivities) {
21610            // Need to do this on its own message because the stack may not
21611            // be in a consistent state at this point.
21612            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21613        }
21614
21615        if (allChanged) {
21616            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21617        }
21618
21619        // Update from any uid changes.
21620        if (mLocalPowerManager != null) {
21621            mLocalPowerManager.startUidChanges();
21622        }
21623        for (int i=mActiveUids.size()-1; i>=0; i--) {
21624            final UidRecord uidRec = mActiveUids.valueAt(i);
21625            int uidChange = UidRecord.CHANGE_PROCSTATE;
21626            if (uidRec.setProcState != uidRec.curProcState) {
21627                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21628                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21629                        + " to " + uidRec.curProcState);
21630                if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21631                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21632                        uidRec.lastBackgroundTime = nowElapsed;
21633                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21634                            // Note: the background settle time is in elapsed realtime, while
21635                            // the handler time base is uptime.  All this means is that we may
21636                            // stop background uids later than we had intended, but that only
21637                            // happens because the device was sleeping so we are okay anyway.
21638                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21639                        }
21640                    }
21641                } else {
21642                    if (uidRec.idle) {
21643                        uidChange = UidRecord.CHANGE_ACTIVE;
21644                        uidRec.idle = false;
21645                    }
21646                    uidRec.lastBackgroundTime = 0;
21647                }
21648                uidRec.setProcState = uidRec.curProcState;
21649                enqueueUidChangeLocked(uidRec, -1, uidChange);
21650                noteUidProcessState(uidRec.uid, uidRec.curProcState);
21651            }
21652        }
21653        if (mLocalPowerManager != null) {
21654            mLocalPowerManager.finishUidChanges();
21655        }
21656
21657        if (mProcessStats.shouldWriteNowLocked(now)) {
21658            mHandler.post(new Runnable() {
21659                @Override public void run() {
21660                    synchronized (ActivityManagerService.this) {
21661                        mProcessStats.writeStateAsyncLocked();
21662                    }
21663                }
21664            });
21665        }
21666
21667        if (DEBUG_OOM_ADJ) {
21668            final long duration = SystemClock.uptimeMillis() - now;
21669            if (false) {
21670                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21671                        new RuntimeException("here").fillInStackTrace());
21672            } else {
21673                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21674            }
21675        }
21676    }
21677
21678    @Override
21679    public void makePackageIdle(String packageName, int userId) {
21680        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
21681                != PackageManager.PERMISSION_GRANTED) {
21682            String msg = "Permission Denial: makePackageIdle() from pid="
21683                    + Binder.getCallingPid()
21684                    + ", uid=" + Binder.getCallingUid()
21685                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
21686            Slog.w(TAG, msg);
21687            throw new SecurityException(msg);
21688        }
21689        final int callingPid = Binder.getCallingPid();
21690        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
21691                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
21692        long callingId = Binder.clearCallingIdentity();
21693        synchronized(this) {
21694            try {
21695                IPackageManager pm = AppGlobals.getPackageManager();
21696                int pkgUid = -1;
21697                try {
21698                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
21699                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
21700                } catch (RemoteException e) {
21701                }
21702                if (pkgUid == -1) {
21703                    throw new IllegalArgumentException("Unknown package name " + packageName);
21704                }
21705
21706                if (mLocalPowerManager != null) {
21707                    mLocalPowerManager.startUidChanges();
21708                }
21709                final int appId = UserHandle.getAppId(pkgUid);
21710                final int N = mActiveUids.size();
21711                for (int i=N-1; i>=0; i--) {
21712                    final UidRecord uidRec = mActiveUids.valueAt(i);
21713                    final long bgTime = uidRec.lastBackgroundTime;
21714                    if (bgTime > 0 && !uidRec.idle) {
21715                        if (UserHandle.getAppId(uidRec.uid) == appId) {
21716                            if (userId == UserHandle.USER_ALL ||
21717                                    userId == UserHandle.getUserId(uidRec.uid)) {
21718                                uidRec.idle = true;
21719                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
21720                                        + " from package " + packageName + " user " + userId);
21721                                doStopUidLocked(uidRec.uid, uidRec);
21722                            }
21723                        }
21724                    }
21725                }
21726            } finally {
21727                if (mLocalPowerManager != null) {
21728                    mLocalPowerManager.finishUidChanges();
21729                }
21730                Binder.restoreCallingIdentity(callingId);
21731            }
21732        }
21733    }
21734
21735    final void idleUids() {
21736        synchronized (this) {
21737            final int N = mActiveUids.size();
21738            if (N <= 0) {
21739                return;
21740            }
21741            final long nowElapsed = SystemClock.elapsedRealtime();
21742            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21743            long nextTime = 0;
21744            if (mLocalPowerManager != null) {
21745                mLocalPowerManager.startUidChanges();
21746            }
21747            for (int i=N-1; i>=0; i--) {
21748                final UidRecord uidRec = mActiveUids.valueAt(i);
21749                final long bgTime = uidRec.lastBackgroundTime;
21750                if (bgTime > 0 && !uidRec.idle) {
21751                    if (bgTime <= maxBgTime) {
21752                        uidRec.idle = true;
21753                        doStopUidLocked(uidRec.uid, uidRec);
21754                    } else {
21755                        if (nextTime == 0 || nextTime > bgTime) {
21756                            nextTime = bgTime;
21757                        }
21758                    }
21759                }
21760            }
21761            if (mLocalPowerManager != null) {
21762                mLocalPowerManager.finishUidChanges();
21763            }
21764            if (nextTime > 0) {
21765                mHandler.removeMessages(IDLE_UIDS_MSG);
21766                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21767                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21768            }
21769        }
21770    }
21771
21772    final void runInBackgroundDisabled(int uid) {
21773        synchronized (this) {
21774            UidRecord uidRec = mActiveUids.get(uid);
21775            if (uidRec != null) {
21776                // This uid is actually running...  should it be considered background now?
21777                if (uidRec.idle) {
21778                    doStopUidLocked(uidRec.uid, uidRec);
21779                }
21780            } else {
21781                // This uid isn't actually running...  still send a report about it being "stopped".
21782                doStopUidLocked(uid, null);
21783            }
21784        }
21785    }
21786
21787    final void doStopUidLocked(int uid, final UidRecord uidRec) {
21788        mServices.stopInBackgroundLocked(uid);
21789        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21790    }
21791
21792    final void trimApplications() {
21793        synchronized (this) {
21794            int i;
21795
21796            // First remove any unused application processes whose package
21797            // has been removed.
21798            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21799                final ProcessRecord app = mRemovedProcesses.get(i);
21800                if (app.activities.size() == 0
21801                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
21802                    Slog.i(
21803                        TAG, "Exiting empty application process "
21804                        + app.toShortString() + " ("
21805                        + (app.thread != null ? app.thread.asBinder() : null)
21806                        + ")\n");
21807                    if (app.pid > 0 && app.pid != MY_PID) {
21808                        app.kill("empty", false);
21809                    } else {
21810                        try {
21811                            app.thread.scheduleExit();
21812                        } catch (Exception e) {
21813                            // Ignore exceptions.
21814                        }
21815                    }
21816                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21817                    mRemovedProcesses.remove(i);
21818
21819                    if (app.persistent) {
21820                        addAppLocked(app.info, false, null /* ABI override */);
21821                    }
21822                }
21823            }
21824
21825            // Now update the oom adj for all processes.
21826            updateOomAdjLocked();
21827        }
21828    }
21829
21830    /** This method sends the specified signal to each of the persistent apps */
21831    public void signalPersistentProcesses(int sig) throws RemoteException {
21832        if (sig != Process.SIGNAL_USR1) {
21833            throw new SecurityException("Only SIGNAL_USR1 is allowed");
21834        }
21835
21836        synchronized (this) {
21837            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21838                    != PackageManager.PERMISSION_GRANTED) {
21839                throw new SecurityException("Requires permission "
21840                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21841            }
21842
21843            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21844                ProcessRecord r = mLruProcesses.get(i);
21845                if (r.thread != null && r.persistent) {
21846                    Process.sendSignal(r.pid, sig);
21847                }
21848            }
21849        }
21850    }
21851
21852    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21853        if (proc == null || proc == mProfileProc) {
21854            proc = mProfileProc;
21855            profileType = mProfileType;
21856            clearProfilerLocked();
21857        }
21858        if (proc == null) {
21859            return;
21860        }
21861        try {
21862            proc.thread.profilerControl(false, null, profileType);
21863        } catch (RemoteException e) {
21864            throw new IllegalStateException("Process disappeared");
21865        }
21866    }
21867
21868    private void clearProfilerLocked() {
21869        if (mProfileFd != null) {
21870            try {
21871                mProfileFd.close();
21872            } catch (IOException e) {
21873            }
21874        }
21875        mProfileApp = null;
21876        mProfileProc = null;
21877        mProfileFile = null;
21878        mProfileType = 0;
21879        mAutoStopProfiler = false;
21880        mSamplingInterval = 0;
21881    }
21882
21883    public boolean profileControl(String process, int userId, boolean start,
21884            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21885
21886        try {
21887            synchronized (this) {
21888                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21889                // its own permission.
21890                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21891                        != PackageManager.PERMISSION_GRANTED) {
21892                    throw new SecurityException("Requires permission "
21893                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21894                }
21895
21896                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21897                    throw new IllegalArgumentException("null profile info or fd");
21898                }
21899
21900                ProcessRecord proc = null;
21901                if (process != null) {
21902                    proc = findProcessLocked(process, userId, "profileControl");
21903                }
21904
21905                if (start && (proc == null || proc.thread == null)) {
21906                    throw new IllegalArgumentException("Unknown process: " + process);
21907                }
21908
21909                if (start) {
21910                    stopProfilerLocked(null, 0);
21911                    setProfileApp(proc.info, proc.processName, profilerInfo);
21912                    mProfileProc = proc;
21913                    mProfileType = profileType;
21914                    ParcelFileDescriptor fd = profilerInfo.profileFd;
21915                    try {
21916                        fd = fd.dup();
21917                    } catch (IOException e) {
21918                        fd = null;
21919                    }
21920                    profilerInfo.profileFd = fd;
21921                    proc.thread.profilerControl(start, profilerInfo, profileType);
21922                    fd = null;
21923                    try {
21924                        mProfileFd.close();
21925                    } catch (IOException e) {
21926                    }
21927                    mProfileFd = null;
21928                } else {
21929                    stopProfilerLocked(proc, profileType);
21930                    if (profilerInfo != null && profilerInfo.profileFd != null) {
21931                        try {
21932                            profilerInfo.profileFd.close();
21933                        } catch (IOException e) {
21934                        }
21935                    }
21936                }
21937
21938                return true;
21939            }
21940        } catch (RemoteException e) {
21941            throw new IllegalStateException("Process disappeared");
21942        } finally {
21943            if (profilerInfo != null && profilerInfo.profileFd != null) {
21944                try {
21945                    profilerInfo.profileFd.close();
21946                } catch (IOException e) {
21947                }
21948            }
21949        }
21950    }
21951
21952    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21953        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21954                userId, true, ALLOW_FULL_ONLY, callName, null);
21955        ProcessRecord proc = null;
21956        try {
21957            int pid = Integer.parseInt(process);
21958            synchronized (mPidsSelfLocked) {
21959                proc = mPidsSelfLocked.get(pid);
21960            }
21961        } catch (NumberFormatException e) {
21962        }
21963
21964        if (proc == null) {
21965            ArrayMap<String, SparseArray<ProcessRecord>> all
21966                    = mProcessNames.getMap();
21967            SparseArray<ProcessRecord> procs = all.get(process);
21968            if (procs != null && procs.size() > 0) {
21969                proc = procs.valueAt(0);
21970                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21971                    for (int i=1; i<procs.size(); i++) {
21972                        ProcessRecord thisProc = procs.valueAt(i);
21973                        if (thisProc.userId == userId) {
21974                            proc = thisProc;
21975                            break;
21976                        }
21977                    }
21978                }
21979            }
21980        }
21981
21982        return proc;
21983    }
21984
21985    public boolean dumpHeap(String process, int userId, boolean managed,
21986            String path, ParcelFileDescriptor fd) throws RemoteException {
21987
21988        try {
21989            synchronized (this) {
21990                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21991                // its own permission (same as profileControl).
21992                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21993                        != PackageManager.PERMISSION_GRANTED) {
21994                    throw new SecurityException("Requires permission "
21995                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21996                }
21997
21998                if (fd == null) {
21999                    throw new IllegalArgumentException("null fd");
22000                }
22001
22002                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
22003                if (proc == null || proc.thread == null) {
22004                    throw new IllegalArgumentException("Unknown process: " + process);
22005                }
22006
22007                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22008                if (!isDebuggable) {
22009                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22010                        throw new SecurityException("Process not debuggable: " + proc);
22011                    }
22012                }
22013
22014                proc.thread.dumpHeap(managed, path, fd);
22015                fd = null;
22016                return true;
22017            }
22018        } catch (RemoteException e) {
22019            throw new IllegalStateException("Process disappeared");
22020        } finally {
22021            if (fd != null) {
22022                try {
22023                    fd.close();
22024                } catch (IOException e) {
22025                }
22026            }
22027        }
22028    }
22029
22030    @Override
22031    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
22032            String reportPackage) {
22033        if (processName != null) {
22034            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
22035                    "setDumpHeapDebugLimit()");
22036        } else {
22037            synchronized (mPidsSelfLocked) {
22038                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
22039                if (proc == null) {
22040                    throw new SecurityException("No process found for calling pid "
22041                            + Binder.getCallingPid());
22042                }
22043                if (!Build.IS_DEBUGGABLE
22044                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22045                    throw new SecurityException("Not running a debuggable build");
22046                }
22047                processName = proc.processName;
22048                uid = proc.uid;
22049                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
22050                    throw new SecurityException("Package " + reportPackage + " is not running in "
22051                            + proc);
22052                }
22053            }
22054        }
22055        synchronized (this) {
22056            if (maxMemSize > 0) {
22057                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
22058            } else {
22059                if (uid != 0) {
22060                    mMemWatchProcesses.remove(processName, uid);
22061                } else {
22062                    mMemWatchProcesses.getMap().remove(processName);
22063                }
22064            }
22065        }
22066    }
22067
22068    @Override
22069    public void dumpHeapFinished(String path) {
22070        synchronized (this) {
22071            if (Binder.getCallingPid() != mMemWatchDumpPid) {
22072                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
22073                        + " does not match last pid " + mMemWatchDumpPid);
22074                return;
22075            }
22076            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
22077                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
22078                        + " does not match last path " + mMemWatchDumpFile);
22079                return;
22080            }
22081            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
22082            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
22083        }
22084    }
22085
22086    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
22087    public void monitor() {
22088        synchronized (this) { }
22089    }
22090
22091    void onCoreSettingsChange(Bundle settings) {
22092        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22093            ProcessRecord processRecord = mLruProcesses.get(i);
22094            try {
22095                if (processRecord.thread != null) {
22096                    processRecord.thread.setCoreSettings(settings);
22097                }
22098            } catch (RemoteException re) {
22099                /* ignore */
22100            }
22101        }
22102    }
22103
22104    // Multi-user methods
22105
22106    /**
22107     * Start user, if its not already running, but don't bring it to foreground.
22108     */
22109    @Override
22110    public boolean startUserInBackground(final int userId) {
22111        return mUserController.startUser(userId, /* foreground */ false);
22112    }
22113
22114    @Override
22115    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
22116        return mUserController.unlockUser(userId, token, secret, listener);
22117    }
22118
22119    @Override
22120    public boolean switchUser(final int targetUserId) {
22121        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
22122        int currentUserId;
22123        UserInfo targetUserInfo;
22124        synchronized (this) {
22125            currentUserId = mUserController.getCurrentUserIdLocked();
22126            targetUserInfo = mUserController.getUserInfo(targetUserId);
22127            if (targetUserId == currentUserId) {
22128                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
22129                return true;
22130            }
22131            if (targetUserInfo == null) {
22132                Slog.w(TAG, "No user info for user #" + targetUserId);
22133                return false;
22134            }
22135            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
22136                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
22137                        + " when device is in demo mode");
22138                return false;
22139            }
22140            if (!targetUserInfo.supportsSwitchTo()) {
22141                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
22142                return false;
22143            }
22144            if (targetUserInfo.isManagedProfile()) {
22145                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
22146                return false;
22147            }
22148            mUserController.setTargetUserIdLocked(targetUserId);
22149        }
22150        if (mUserController.mUserSwitchUiEnabled) {
22151            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
22152            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
22153            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
22154            mUiHandler.sendMessage(mHandler.obtainMessage(
22155                    START_USER_SWITCH_UI_MSG, userNames));
22156        } else {
22157            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
22158            mHandler.sendMessage(mHandler.obtainMessage(
22159                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
22160        }
22161        return true;
22162    }
22163
22164    void scheduleStartProfilesLocked() {
22165        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
22166            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
22167                    DateUtils.SECOND_IN_MILLIS);
22168        }
22169    }
22170
22171    @Override
22172    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
22173        return mUserController.stopUser(userId, force, callback);
22174    }
22175
22176    @Override
22177    public UserInfo getCurrentUser() {
22178        return mUserController.getCurrentUser();
22179    }
22180
22181    String getStartedUserState(int userId) {
22182        synchronized (this) {
22183            final UserState userState = mUserController.getStartedUserStateLocked(userId);
22184            return UserState.stateToString(userState.state);
22185        }
22186    }
22187
22188    @Override
22189    public boolean isUserRunning(int userId, int flags) {
22190        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
22191                && checkCallingPermission(INTERACT_ACROSS_USERS)
22192                    != PackageManager.PERMISSION_GRANTED) {
22193            String msg = "Permission Denial: isUserRunning() from pid="
22194                    + Binder.getCallingPid()
22195                    + ", uid=" + Binder.getCallingUid()
22196                    + " requires " + INTERACT_ACROSS_USERS;
22197            Slog.w(TAG, msg);
22198            throw new SecurityException(msg);
22199        }
22200        synchronized (this) {
22201            return mUserController.isUserRunningLocked(userId, flags);
22202        }
22203    }
22204
22205    @Override
22206    public int[] getRunningUserIds() {
22207        if (checkCallingPermission(INTERACT_ACROSS_USERS)
22208                != PackageManager.PERMISSION_GRANTED) {
22209            String msg = "Permission Denial: isUserRunning() from pid="
22210                    + Binder.getCallingPid()
22211                    + ", uid=" + Binder.getCallingUid()
22212                    + " requires " + INTERACT_ACROSS_USERS;
22213            Slog.w(TAG, msg);
22214            throw new SecurityException(msg);
22215        }
22216        synchronized (this) {
22217            return mUserController.getStartedUserArrayLocked();
22218        }
22219    }
22220
22221    @Override
22222    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
22223        mUserController.registerUserSwitchObserver(observer, name);
22224    }
22225
22226    @Override
22227    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
22228        mUserController.unregisterUserSwitchObserver(observer);
22229    }
22230
22231    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
22232        if (info == null) return null;
22233        ApplicationInfo newInfo = new ApplicationInfo(info);
22234        newInfo.initForUser(userId);
22235        return newInfo;
22236    }
22237
22238    public boolean isUserStopped(int userId) {
22239        synchronized (this) {
22240            return mUserController.getStartedUserStateLocked(userId) == null;
22241        }
22242    }
22243
22244    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
22245        if (aInfo == null
22246                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
22247            return aInfo;
22248        }
22249
22250        ActivityInfo info = new ActivityInfo(aInfo);
22251        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
22252        return info;
22253    }
22254
22255    private boolean processSanityChecksLocked(ProcessRecord process) {
22256        if (process == null || process.thread == null) {
22257            return false;
22258        }
22259
22260        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22261        if (!isDebuggable) {
22262            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22263                return false;
22264            }
22265        }
22266
22267        return true;
22268    }
22269
22270    public boolean startBinderTracking() throws RemoteException {
22271        synchronized (this) {
22272            mBinderTransactionTrackingEnabled = true;
22273            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22274            // permission (same as profileControl).
22275            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22276                    != PackageManager.PERMISSION_GRANTED) {
22277                throw new SecurityException("Requires permission "
22278                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22279            }
22280
22281            for (int i = 0; i < mLruProcesses.size(); i++) {
22282                ProcessRecord process = mLruProcesses.get(i);
22283                if (!processSanityChecksLocked(process)) {
22284                    continue;
22285                }
22286                try {
22287                    process.thread.startBinderTracking();
22288                } catch (RemoteException e) {
22289                    Log.v(TAG, "Process disappared");
22290                }
22291            }
22292            return true;
22293        }
22294    }
22295
22296    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
22297        try {
22298            synchronized (this) {
22299                mBinderTransactionTrackingEnabled = false;
22300                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
22301                // permission (same as profileControl).
22302                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22303                        != PackageManager.PERMISSION_GRANTED) {
22304                    throw new SecurityException("Requires permission "
22305                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22306                }
22307
22308                if (fd == null) {
22309                    throw new IllegalArgumentException("null fd");
22310                }
22311
22312                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
22313                pw.println("Binder transaction traces for all processes.\n");
22314                for (ProcessRecord process : mLruProcesses) {
22315                    if (!processSanityChecksLocked(process)) {
22316                        continue;
22317                    }
22318
22319                    pw.println("Traces for process: " + process.processName);
22320                    pw.flush();
22321                    try {
22322                        TransferPipe tp = new TransferPipe();
22323                        try {
22324                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
22325                            tp.go(fd.getFileDescriptor());
22326                        } finally {
22327                            tp.kill();
22328                        }
22329                    } catch (IOException e) {
22330                        pw.println("Failure while dumping IPC traces from " + process +
22331                                ".  Exception: " + e);
22332                        pw.flush();
22333                    } catch (RemoteException e) {
22334                        pw.println("Got a RemoteException while dumping IPC traces from " +
22335                                process + ".  Exception: " + e);
22336                        pw.flush();
22337                    }
22338                }
22339                fd = null;
22340                return true;
22341            }
22342        } finally {
22343            if (fd != null) {
22344                try {
22345                    fd.close();
22346                } catch (IOException e) {
22347                }
22348            }
22349        }
22350    }
22351
22352    private final class LocalService extends ActivityManagerInternal {
22353        @Override
22354        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
22355                int targetUserId) {
22356            synchronized (ActivityManagerService.this) {
22357                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
22358                        targetPkg, intent, null, targetUserId);
22359            }
22360        }
22361
22362        @Override
22363        public String checkContentProviderAccess(String authority, int userId) {
22364            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
22365        }
22366
22367        @Override
22368        public void onWakefulnessChanged(int wakefulness) {
22369            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
22370        }
22371
22372        @Override
22373        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
22374                String processName, String abiOverride, int uid, Runnable crashHandler) {
22375            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
22376                    processName, abiOverride, uid, crashHandler);
22377        }
22378
22379        @Override
22380        public SleepToken acquireSleepToken(String tag) {
22381            Preconditions.checkNotNull(tag);
22382
22383            synchronized (ActivityManagerService.this) {
22384                SleepTokenImpl token = new SleepTokenImpl(tag);
22385                mSleepTokens.add(token);
22386                updateSleepIfNeededLocked();
22387                return token;
22388            }
22389        }
22390
22391        @Override
22392        public ComponentName getHomeActivityForUser(int userId) {
22393            synchronized (ActivityManagerService.this) {
22394                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
22395                return homeActivity == null ? null : homeActivity.realActivity;
22396            }
22397        }
22398
22399        @Override
22400        public void onUserRemoved(int userId) {
22401            synchronized (ActivityManagerService.this) {
22402                ActivityManagerService.this.onUserStoppedLocked(userId);
22403            }
22404        }
22405
22406        @Override
22407        public void onLocalVoiceInteractionStarted(IBinder activity,
22408                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
22409            synchronized (ActivityManagerService.this) {
22410                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
22411                        voiceSession, voiceInteractor);
22412            }
22413        }
22414
22415        @Override
22416        public void notifyStartingWindowDrawn() {
22417            synchronized (ActivityManagerService.this) {
22418                mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22419            }
22420        }
22421
22422        @Override
22423        public void notifyAppTransitionStarting(int reason) {
22424            synchronized (ActivityManagerService.this) {
22425                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22426            }
22427        }
22428
22429        @Override
22430        public void notifyAppTransitionFinished() {
22431            synchronized (ActivityManagerService.this) {
22432                mStackSupervisor.notifyAppTransitionDone();
22433            }
22434        }
22435
22436        @Override
22437        public void notifyAppTransitionCancelled() {
22438            synchronized (ActivityManagerService.this) {
22439                mStackSupervisor.notifyAppTransitionDone();
22440            }
22441        }
22442
22443        @Override
22444        public List<IBinder> getTopVisibleActivities() {
22445            synchronized (ActivityManagerService.this) {
22446                return mStackSupervisor.getTopVisibleActivities();
22447            }
22448        }
22449
22450        @Override
22451        public void notifyDockedStackMinimizedChanged(boolean minimized) {
22452            synchronized (ActivityManagerService.this) {
22453                mStackSupervisor.setDockedStackMinimized(minimized);
22454            }
22455        }
22456
22457        @Override
22458        public void killForegroundAppsForUser(int userHandle) {
22459            synchronized (ActivityManagerService.this) {
22460                final ArrayList<ProcessRecord> procs = new ArrayList<>();
22461                final int NP = mProcessNames.getMap().size();
22462                for (int ip = 0; ip < NP; ip++) {
22463                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22464                    final int NA = apps.size();
22465                    for (int ia = 0; ia < NA; ia++) {
22466                        final ProcessRecord app = apps.valueAt(ia);
22467                        if (app.persistent) {
22468                            // We don't kill persistent processes.
22469                            continue;
22470                        }
22471                        if (app.removed) {
22472                            procs.add(app);
22473                        } else if (app.userId == userHandle && app.foregroundActivities) {
22474                            app.removed = true;
22475                            procs.add(app);
22476                        }
22477                    }
22478                }
22479
22480                final int N = procs.size();
22481                for (int i = 0; i < N; i++) {
22482                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
22483                }
22484            }
22485        }
22486
22487        @Override
22488        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22489            if (!(target instanceof PendingIntentRecord)) {
22490                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22491                return;
22492            }
22493            ((PendingIntentRecord) target).setWhitelistDuration(duration);
22494        }
22495
22496        @Override
22497        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22498                int userId) {
22499            Preconditions.checkNotNull(values, "Configuration must not be null");
22500            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22501            synchronized (ActivityManagerService.this) {
22502                updateConfigurationLocked(values, null, false, true, userId,
22503                        false /* deferResume */);
22504            }
22505        }
22506
22507        @Override
22508        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22509                Bundle bOptions) {
22510            Preconditions.checkNotNull(intents, "intents");
22511            final String[] resolvedTypes = new String[intents.length];
22512            for (int i = 0; i < intents.length; i++) {
22513                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22514            }
22515
22516            // UID of the package on user userId.
22517            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22518            // packageUid may not be initialized.
22519            int packageUid = 0;
22520            try {
22521                packageUid = AppGlobals.getPackageManager().getPackageUid(
22522                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22523            } catch (RemoteException e) {
22524                // Shouldn't happen.
22525            }
22526
22527            synchronized (ActivityManagerService.this) {
22528                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22529                        /*resultTo*/ null, bOptions, userId);
22530            }
22531        }
22532
22533        @Override
22534        public int getUidProcessState(int uid) {
22535            return getUidState(uid);
22536        }
22537
22538        @Override
22539        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
22540            synchronized (ActivityManagerService.this) {
22541
22542                // We might change the visibilities here, so prepare an empty app transition which
22543                // might be overridden later if we actually change visibilities.
22544                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
22545                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22546                mWindowManager.executeAppTransition();
22547            }
22548            if (callback != null) {
22549                callback.run();
22550            }
22551        }
22552
22553        @Override
22554        public boolean isSystemReady() {
22555            // no need to synchronize(this) just to read & return the value
22556            return mSystemReady;
22557        }
22558
22559        @Override
22560        public void notifyKeyguardTrustedChanged() {
22561            synchronized (ActivityManagerService.this) {
22562                if (mKeyguardController.isKeyguardShowing()) {
22563                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
22564                }
22565            }
22566        }
22567    }
22568
22569    private final class SleepTokenImpl extends SleepToken {
22570        private final String mTag;
22571        private final long mAcquireTime;
22572
22573        public SleepTokenImpl(String tag) {
22574            mTag = tag;
22575            mAcquireTime = SystemClock.uptimeMillis();
22576        }
22577
22578        @Override
22579        public void release() {
22580            synchronized (ActivityManagerService.this) {
22581                if (mSleepTokens.remove(this)) {
22582                    updateSleepIfNeededLocked();
22583                }
22584            }
22585        }
22586
22587        @Override
22588        public String toString() {
22589            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22590        }
22591    }
22592
22593    /**
22594     * An implementation of IAppTask, that allows an app to manage its own tasks via
22595     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22596     * only the process that calls getAppTasks() can call the AppTask methods.
22597     */
22598    class AppTaskImpl extends IAppTask.Stub {
22599        private int mTaskId;
22600        private int mCallingUid;
22601
22602        public AppTaskImpl(int taskId, int callingUid) {
22603            mTaskId = taskId;
22604            mCallingUid = callingUid;
22605        }
22606
22607        private void checkCaller() {
22608            if (mCallingUid != Binder.getCallingUid()) {
22609                throw new SecurityException("Caller " + mCallingUid
22610                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22611            }
22612        }
22613
22614        @Override
22615        public void finishAndRemoveTask() {
22616            checkCaller();
22617
22618            synchronized (ActivityManagerService.this) {
22619                long origId = Binder.clearCallingIdentity();
22620                try {
22621                    // We remove the task from recents to preserve backwards
22622                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
22623                            REMOVE_FROM_RECENTS)) {
22624                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22625                    }
22626                } finally {
22627                    Binder.restoreCallingIdentity(origId);
22628                }
22629            }
22630        }
22631
22632        @Override
22633        public ActivityManager.RecentTaskInfo getTaskInfo() {
22634            checkCaller();
22635
22636            synchronized (ActivityManagerService.this) {
22637                long origId = Binder.clearCallingIdentity();
22638                try {
22639                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22640                    if (tr == null) {
22641                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22642                    }
22643                    return createRecentTaskInfoFromTaskRecord(tr);
22644                } finally {
22645                    Binder.restoreCallingIdentity(origId);
22646                }
22647            }
22648        }
22649
22650        @Override
22651        public void moveToFront() {
22652            checkCaller();
22653            // Will bring task to front if it already has a root activity.
22654            final long origId = Binder.clearCallingIdentity();
22655            try {
22656                synchronized (this) {
22657                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22658                }
22659            } finally {
22660                Binder.restoreCallingIdentity(origId);
22661            }
22662        }
22663
22664        @Override
22665        public int startActivity(IBinder whoThread, String callingPackage,
22666                Intent intent, String resolvedType, Bundle bOptions) {
22667            checkCaller();
22668
22669            int callingUser = UserHandle.getCallingUserId();
22670            TaskRecord tr;
22671            IApplicationThread appThread;
22672            synchronized (ActivityManagerService.this) {
22673                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22674                if (tr == null) {
22675                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22676                }
22677                appThread = IApplicationThread.Stub.asInterface(whoThread);
22678                if (appThread == null) {
22679                    throw new IllegalArgumentException("Bad app thread " + appThread);
22680                }
22681            }
22682            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22683                    resolvedType, null, null, null, null, 0, 0, null, null,
22684                    null, bOptions, false, callingUser, null, tr);
22685        }
22686
22687        @Override
22688        public void setExcludeFromRecents(boolean exclude) {
22689            checkCaller();
22690
22691            synchronized (ActivityManagerService.this) {
22692                long origId = Binder.clearCallingIdentity();
22693                try {
22694                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22695                    if (tr == null) {
22696                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22697                    }
22698                    Intent intent = tr.getBaseIntent();
22699                    if (exclude) {
22700                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22701                    } else {
22702                        intent.setFlags(intent.getFlags()
22703                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22704                    }
22705                } finally {
22706                    Binder.restoreCallingIdentity(origId);
22707                }
22708            }
22709        }
22710    }
22711
22712    /**
22713     * Kill processes for the user with id userId and that depend on the package named packageName
22714     */
22715    @Override
22716    public void killPackageDependents(String packageName, int userId) {
22717        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22718        if (packageName == null) {
22719            throw new NullPointerException(
22720                    "Cannot kill the dependents of a package without its name.");
22721        }
22722
22723        long callingId = Binder.clearCallingIdentity();
22724        IPackageManager pm = AppGlobals.getPackageManager();
22725        int pkgUid = -1;
22726        try {
22727            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22728        } catch (RemoteException e) {
22729        }
22730        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22731            throw new IllegalArgumentException(
22732                    "Cannot kill dependents of non-existing package " + packageName);
22733        }
22734        try {
22735            synchronized(this) {
22736                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22737                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22738                        "dep: " + packageName);
22739            }
22740        } finally {
22741            Binder.restoreCallingIdentity(callingId);
22742        }
22743    }
22744
22745    @Override
22746    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22747        final int userId = intent.getCreatorUserHandle().getIdentifier();
22748        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22749            return false;
22750        }
22751        IIntentSender target = intent.getTarget();
22752        if (!(target instanceof PendingIntentRecord)) {
22753            return false;
22754        }
22755        final PendingIntentRecord record = (PendingIntentRecord) target;
22756        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22757                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22758        // For direct boot aware activities, they can be shown without triggering a work challenge
22759        // before the profile user is unlocked.
22760        return rInfo != null && rInfo.activityInfo != null;
22761    }
22762
22763    @Override
22764    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
22765            throws RemoteException {
22766        final long callingId = Binder.clearCallingIdentity();
22767        try {
22768            mKeyguardController.dismissKeyguard(token, callback);
22769        } finally {
22770            Binder.restoreCallingIdentity(callingId);
22771        }
22772    }
22773
22774    @Override
22775    public int restartUserInBackground(final int userId) {
22776        return mUserController.restartUser(userId, /* foreground */ false);
22777    }
22778
22779    /**
22780     * Attach an agent to the specified process (proces name or PID)
22781     */
22782    public void attachAgent(String process, String path) {
22783        try {
22784            synchronized (this) {
22785                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
22786                if (proc == null || proc.thread == null) {
22787                    throw new IllegalArgumentException("Unknown process: " + process);
22788                }
22789
22790                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22791                if (!isDebuggable) {
22792                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22793                        throw new SecurityException("Process not debuggable: " + proc);
22794                    }
22795                }
22796
22797                proc.thread.attachAgent(path);
22798            }
22799        } catch (RemoteException e) {
22800            throw new IllegalStateException("Process disappeared");
22801        }
22802    }
22803}
22804