ActivityManagerService.java revision 99493dbc94989d4493ca6acb0db265a02f49f62e
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.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
26import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
27import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
28import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
29import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
30import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
31import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
32import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
33import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
34import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
35import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
36import static android.content.pm.PackageManager.GET_PROVIDERS;
37import static android.content.pm.PackageManager.MATCH_ANY_USER;
38import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
39import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
40import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
41import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
42import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
43import static android.content.pm.PackageManager.PERMISSION_GRANTED;
44import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
45import static android.os.Build.VERSION_CODES.N;
46import static android.os.Process.PROC_CHAR;
47import static android.os.Process.PROC_OUT_LONG;
48import static android.os.Process.PROC_PARENS;
49import static android.os.Process.PROC_SPACE_TERM;
50import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
51import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
52import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
53import static android.provider.Settings.Global.DEBUG_APP;
54import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
55import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
56import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
57import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
58import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
59import static android.provider.Settings.System.FONT_SCALE;
60import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
61import static android.view.Display.DEFAULT_DISPLAY;
62import static android.view.Display.INVALID_DISPLAY;
63import static com.android.internal.util.XmlUtils.readBooleanAttribute;
64import static com.android.internal.util.XmlUtils.readIntAttribute;
65import static com.android.internal.util.XmlUtils.readLongAttribute;
66import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
67import static com.android.internal.util.XmlUtils.writeIntAttribute;
68import static com.android.internal.util.XmlUtils.writeLongAttribute;
69import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
70import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
71import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
72import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
73import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
74import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
75import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
76import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
77import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
78import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
79import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
80import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
81import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
82import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
83import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
84import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
85import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
86import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
87import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
88import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
89import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
90import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
91import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
92import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
93import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
94import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
95import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
96import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
97import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
98import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
99import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
100import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
101import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
102import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
103import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
104import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
105import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
106import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
107import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
108import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
109import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
110import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
111import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
112import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
113import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
114import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
115import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
116import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
117import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
118import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
119import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
120import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
121import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
122import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
123import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
124import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
125import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
126import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
127import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
128import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
129import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
130import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
131import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
132import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
133import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
134import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
135import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
136import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
137import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
138import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
139import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
140import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
141import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
142import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
143import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
144import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
145import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
146import static com.android.server.wm.AppTransition.TRANSIT_NONE;
147import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
148import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
149import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
150import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
151import static org.xmlpull.v1.XmlPullParser.START_TAG;
152
153import android.Manifest;
154import android.Manifest.permission;
155import android.annotation.NonNull;
156import android.annotation.Nullable;
157import android.annotation.UserIdInt;
158import android.app.Activity;
159import android.app.ActivityManager;
160import android.app.ActivityManager.RunningTaskInfo;
161import android.app.ActivityManager.StackId;
162import android.app.ActivityManager.StackInfo;
163import android.app.ActivityManager.TaskSnapshot;
164import android.app.ActivityManager.TaskThumbnailInfo;
165import android.app.ActivityManagerInternal;
166import android.app.ActivityManagerInternal.SleepToken;
167import android.app.ActivityOptions;
168import android.app.ActivityThread;
169import android.app.AlertDialog;
170import android.app.AppGlobals;
171import android.app.AppOpsManager;
172import android.app.ApplicationErrorReport;
173import android.app.ApplicationThreadConstants;
174import android.app.BroadcastOptions;
175import android.app.ContentProviderHolder;
176import android.app.Dialog;
177import android.app.IActivityContainer;
178import android.app.IActivityContainerCallback;
179import android.app.IActivityController;
180import android.app.IActivityManager;
181import android.app.IAppTask;
182import android.app.IApplicationThread;
183import android.app.IInstrumentationWatcher;
184import android.app.INotificationManager;
185import android.app.IProcessObserver;
186import android.app.IServiceConnection;
187import android.app.IStopUserCallback;
188import android.app.ITaskStackListener;
189import android.app.IUiAutomationConnection;
190import android.app.IUidObserver;
191import android.app.IUserSwitchObserver;
192import android.app.Instrumentation;
193import android.app.Notification;
194import android.app.NotificationManager;
195import android.app.PendingIntent;
196import android.app.PictureInPictureArgs;
197import android.app.ProfilerInfo;
198import android.app.RemoteAction;
199import android.app.WaitResult;
200import android.app.admin.DevicePolicyManager;
201import android.app.assist.AssistContent;
202import android.app.assist.AssistStructure;
203import android.app.backup.IBackupManager;
204import android.app.usage.UsageEvents;
205import android.app.usage.UsageStatsManagerInternal;
206import android.appwidget.AppWidgetManager;
207import android.content.ActivityNotFoundException;
208import android.content.BroadcastReceiver;
209import android.content.ClipData;
210import android.content.ComponentCallbacks2;
211import android.content.ComponentName;
212import android.content.ContentProvider;
213import android.content.ContentResolver;
214import android.content.Context;
215import android.content.DialogInterface;
216import android.content.IContentProvider;
217import android.content.IIntentReceiver;
218import android.content.IIntentSender;
219import android.content.Intent;
220import android.content.IntentFilter;
221import android.content.IntentSender;
222import android.content.pm.ActivityInfo;
223import android.content.pm.ApplicationInfo;
224import android.content.pm.ConfigurationInfo;
225import android.content.pm.IPackageDataObserver;
226import android.content.pm.IPackageManager;
227import android.content.pm.InstrumentationInfo;
228import android.content.pm.PackageInfo;
229import android.content.pm.PackageManager;
230import android.content.pm.PackageManager.NameNotFoundException;
231import android.content.pm.PackageManagerInternal;
232import android.content.pm.ParceledListSlice;
233import android.content.pm.PathPermission;
234import android.content.pm.PermissionInfo;
235import android.content.pm.ProviderInfo;
236import android.content.pm.ResolveInfo;
237import android.content.pm.SELinuxUtil;
238import android.content.pm.ServiceInfo;
239import android.content.pm.UserInfo;
240import android.content.res.CompatibilityInfo;
241import android.content.res.Configuration;
242import android.content.res.Resources;
243import android.database.ContentObserver;
244import android.graphics.Bitmap;
245import android.graphics.Point;
246import android.graphics.Rect;
247import android.location.LocationManager;
248import android.media.audiofx.AudioEffect;
249import android.metrics.LogMaker;
250import android.net.Proxy;
251import android.net.ProxyInfo;
252import android.net.Uri;
253import android.os.BatteryStats;
254import android.os.Binder;
255import android.os.Build;
256import android.os.Bundle;
257import android.os.Debug;
258import android.os.DropBoxManager;
259import android.os.Environment;
260import android.os.FactoryTest;
261import android.os.FileObserver;
262import android.os.FileUtils;
263import android.os.Handler;
264import android.os.IBinder;
265import android.os.IDeviceIdentifiersPolicyService;
266import android.os.IPermissionController;
267import android.os.IProcessInfoService;
268import android.os.IProgressListener;
269import android.os.LocaleList;
270import android.os.Looper;
271import android.os.Message;
272import android.os.Parcel;
273import android.os.ParcelFileDescriptor;
274import android.os.PersistableBundle;
275import android.os.PowerManager;
276import android.os.PowerManagerInternal;
277import android.os.Process;
278import android.os.RemoteCallbackList;
279import android.os.RemoteException;
280import android.os.ResultReceiver;
281import android.os.ServiceManager;
282import android.os.ShellCallback;
283import android.os.StrictMode;
284import android.os.SystemClock;
285import android.os.SystemProperties;
286import android.os.Trace;
287import android.os.TransactionTooLargeException;
288import android.os.UpdateLock;
289import android.os.UserHandle;
290import android.os.UserManager;
291import android.os.WorkSource;
292import android.os.storage.IStorageManager;
293import android.os.storage.StorageManager;
294import android.os.storage.StorageManagerInternal;
295import android.provider.Downloads;
296import android.provider.Settings;
297import android.service.voice.IVoiceInteractionSession;
298import android.service.voice.VoiceInteractionManagerInternal;
299import android.service.voice.VoiceInteractionSession;
300import android.service.vr.IPersistentVrStateCallbacks;
301import android.telecom.TelecomManager;
302import android.text.TextUtils;
303import android.text.format.DateUtils;
304import android.text.format.Time;
305import android.text.style.SuggestionSpan;
306import android.util.ArrayMap;
307import android.util.ArraySet;
308import android.util.AtomicFile;
309import android.util.BootTimingsTraceLog;
310import android.util.DebugUtils;
311import android.util.DisplayMetrics;
312import android.util.EventLog;
313import android.util.Log;
314import android.util.Pair;
315import android.util.PrintWriterPrinter;
316import android.util.Slog;
317import android.util.SparseArray;
318import android.util.SparseIntArray;
319import android.util.TimeUtils;
320import android.util.Xml;
321import android.view.Gravity;
322import android.view.LayoutInflater;
323import android.view.View;
324import android.view.WindowManager;
325
326import com.android.internal.notification.SystemNotificationChannels;
327import com.google.android.collect.Lists;
328import com.google.android.collect.Maps;
329
330import com.android.internal.R;
331import com.android.internal.annotations.GuardedBy;
332import com.android.internal.annotations.VisibleForTesting;
333import com.android.internal.app.AssistUtils;
334import com.android.internal.app.DumpHeapActivity;
335import com.android.internal.app.IAppOpsCallback;
336import com.android.internal.app.IAppOpsService;
337import com.android.internal.app.IVoiceInteractor;
338import com.android.internal.app.ProcessMap;
339import com.android.internal.app.SystemUserHomeActivity;
340import com.android.internal.app.procstats.ProcessStats;
341import com.android.internal.logging.MetricsLogger;
342import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
343import com.android.internal.os.BackgroundThread;
344import com.android.internal.os.BatteryStatsImpl;
345import com.android.internal.os.IResultReceiver;
346import com.android.internal.os.ProcessCpuTracker;
347import com.android.internal.os.TransferPipe;
348import com.android.internal.os.Zygote;
349import com.android.internal.policy.IKeyguardDismissCallback;
350import com.android.internal.telephony.TelephonyIntents;
351import com.android.internal.util.ArrayUtils;
352import com.android.internal.util.FastPrintWriter;
353import com.android.internal.util.FastXmlSerializer;
354import com.android.internal.util.MemInfoReader;
355import com.android.internal.util.Preconditions;
356import com.android.server.AppOpsService;
357import com.android.server.AttributeCache;
358import com.android.server.DeviceIdleController;
359import com.android.server.IntentResolver;
360import com.android.server.LocalServices;
361import com.android.server.LockGuard;
362import com.android.server.NetworkManagementInternal;
363import com.android.server.RescueParty;
364import com.android.server.ServiceThread;
365import com.android.server.SystemConfig;
366import com.android.server.SystemService;
367import com.android.server.SystemServiceManager;
368import com.android.server.Watchdog;
369import com.android.server.am.ActivityStack.ActivityState;
370import com.android.server.firewall.IntentFirewall;
371import com.android.server.pm.Installer;
372import com.android.server.pm.Installer.InstallerException;
373import com.android.server.statusbar.StatusBarManagerInternal;
374import com.android.server.vr.VrManagerInternal;
375import com.android.server.wm.WindowManagerService;
376
377import org.xmlpull.v1.XmlPullParser;
378import org.xmlpull.v1.XmlPullParserException;
379import org.xmlpull.v1.XmlSerializer;
380
381import java.io.File;
382import java.io.FileDescriptor;
383import java.io.FileInputStream;
384import java.io.FileNotFoundException;
385import java.io.FileOutputStream;
386import java.io.IOException;
387import java.io.InputStreamReader;
388import java.io.PrintWriter;
389import java.io.StringWriter;
390import java.io.UnsupportedEncodingException;
391import java.lang.ref.WeakReference;
392import java.nio.charset.StandardCharsets;
393import java.util.ArrayList;
394import java.util.Arrays;
395import java.util.Collections;
396import java.util.Comparator;
397import java.util.HashMap;
398import java.util.HashSet;
399import java.util.Iterator;
400import java.util.List;
401import java.util.Locale;
402import java.util.Map;
403import java.util.Objects;
404import java.util.Set;
405import java.util.concurrent.CountDownLatch;
406import java.util.concurrent.atomic.AtomicBoolean;
407import java.util.concurrent.atomic.AtomicLong;
408
409import dalvik.system.VMRuntime;
410
411import libcore.io.IoUtils;
412import libcore.util.EmptyArray;
413
414public class ActivityManagerService extends IActivityManager.Stub
415        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
416
417    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
418    private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
419    private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
420    private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
421    private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
422    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
423    private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
424    private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
425    private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
426    private static final String TAG_LRU = TAG + POSTFIX_LRU;
427    private static final String TAG_MU = TAG + POSTFIX_MU;
428    private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
429    private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
430    private static final String TAG_POWER = TAG + POSTFIX_POWER;
431    private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
432    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
433    private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
434    private static final String TAG_PSS = TAG + POSTFIX_PSS;
435    private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
436    private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
437    private static final String TAG_STACK = TAG + POSTFIX_STACK;
438    private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
439    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
440    private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
441    private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
442    private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
443
444    // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
445    // here so that while the job scheduler can depend on AMS, the other way around
446    // need not be the case.
447    public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
448
449    /** Control over CPU and battery monitoring */
450    // write battery stats every 30 minutes.
451    static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
452    static final boolean MONITOR_CPU_USAGE = true;
453    // don't sample cpu less than every 5 seconds.
454    static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
455    // wait possibly forever for next cpu sample.
456    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
457    static final boolean MONITOR_THREAD_CPU_USAGE = false;
458
459    // The flags that are set for all calls we make to the package manager.
460    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
461
462    static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
463
464    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
465
466    // Amount of time after a call to stopAppSwitches() during which we will
467    // prevent further untrusted switches from happening.
468    static final long APP_SWITCH_DELAY_TIME = 5*1000;
469
470    // How long we wait for a launched process to attach to the activity manager
471    // before we decide it's never going to come up for real.
472    static final int PROC_START_TIMEOUT = 10*1000;
473    // How long we wait for an attached process to publish its content providers
474    // before we decide it must be hung.
475    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
476
477    // How long we will retain processes hosting content providers in the "last activity"
478    // state before allowing them to drop down to the regular cached LRU list.  This is
479    // to avoid thrashing of provider processes under low memory situations.
480    static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
481
482    // How long we wait for a launched process to attach to the activity manager
483    // before we decide it's never going to come up for real, when the process was
484    // started with a wrapper for instrumentation (such as Valgrind) because it
485    // could take much longer than usual.
486    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
487
488    // How long to wait after going idle before forcing apps to GC.
489    static final int GC_TIMEOUT = 5*1000;
490
491    // The minimum amount of time between successive GC requests for a process.
492    static final int GC_MIN_INTERVAL = 60*1000;
493
494    // The minimum amount of time between successive PSS requests for a process.
495    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
496
497    // The minimum amount of time between successive PSS requests for a process
498    // when the request is due to the memory state being lowered.
499    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
500
501    // The rate at which we check for apps using excessive power -- 15 mins.
502    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
503
504    // The minimum sample duration we will allow before deciding we have
505    // enough data on wake locks to start killing things.
506    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
507
508    // The minimum sample duration we will allow before deciding we have
509    // enough data on CPU usage to start killing things.
510    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
511
512    // How long we allow a receiver to run before giving up on it.
513    static final int BROADCAST_FG_TIMEOUT = 10*1000;
514    static final int BROADCAST_BG_TIMEOUT = 60*1000;
515
516    // How long we wait until we timeout on key dispatching.
517    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
518
519    // How long we wait until we timeout on key dispatching during instrumentation.
520    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
521
522    // This is the amount of time an app needs to be running a foreground service before
523    // we will consider it to be doing interaction for usage stats.
524    static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
525
526    // Maximum amount of time we will allow to elapse before re-reporting usage stats
527    // interaction with foreground processes.
528    static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
529
530    // This is the amount of time we allow an app to settle after it goes into the background,
531    // before we start restricting what it can do.
532    static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
533
534    // How long to wait in getAssistContextExtras for the activity and foreground services
535    // to respond with the result.
536    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
537
538    // How long top wait when going through the modern assist (which doesn't need to block
539    // on getting this result before starting to launch its UI).
540    static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
541
542    // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
543    static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
544
545    // Maximum number of persisted Uri grants a package is allowed
546    static final int MAX_PERSISTED_URI_GRANTS = 128;
547
548    static final int MY_PID = Process.myPid();
549
550    static final String[] EMPTY_STRING_ARRAY = new String[0];
551
552    // How many bytes to write into the dropbox log before truncating
553    static final int DROPBOX_MAX_SIZE = 192 * 1024;
554    // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
555    // as one line, but close enough for now.
556    static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
557
558    // Access modes for handleIncomingUser.
559    static final int ALLOW_NON_FULL = 0;
560    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
561    static final int ALLOW_FULL_ONLY = 2;
562
563    // Necessary ApplicationInfo flags to mark an app as persistent
564    private static final int PERSISTENT_MASK =
565            ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
566
567    // Intent sent when remote bugreport collection has been completed
568    private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
569            "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
570
571    // Used to indicate that an app transition should be animated.
572    static final boolean ANIMATE = true;
573
574    // Determines whether to take full screen screenshots
575    static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
576
577    /**
578     * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
579     */
580    private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 0; // 0 sec
581
582    /**
583     * State indicating that there is no need for any blocking for network.
584     */
585    @VisibleForTesting
586    static final int NETWORK_STATE_NO_CHANGE = 0;
587
588    /**
589     * State indicating that the main thread needs to be informed about the network wait.
590     */
591    @VisibleForTesting
592    static final int NETWORK_STATE_BLOCK = 1;
593
594    /**
595     * State indicating that any threads waiting for network state to get updated can be unblocked.
596     */
597    @VisibleForTesting
598    static final int NETWORK_STATE_UNBLOCK = 2;
599
600    // Max character limit for a notification title. If the notification title is larger than this
601    // the notification will not be legible to the user.
602    private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
603
604    /** All system services */
605    SystemServiceManager mSystemServiceManager;
606    AssistUtils mAssistUtils;
607
608    private Installer mInstaller;
609
610    /** Run all ActivityStacks through this */
611    final ActivityStackSupervisor mStackSupervisor;
612    private final KeyguardController mKeyguardController;
613
614    final ActivityStarter mActivityStarter;
615
616    final TaskChangeNotificationController mTaskChangeNotificationController;
617
618    final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
619
620    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
621
622    public final IntentFirewall mIntentFirewall;
623
624    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
625    // default action automatically.  Important for devices without direct input
626    // devices.
627    private boolean mShowDialogs = true;
628    // VR state flags.
629    static final int NON_VR_MODE = 0;
630    static final int VR_MODE = 1;
631    static final int PERSISTENT_VR_MODE = 2;
632    private int mVrState = NON_VR_MODE;
633    private int mTopAppVrThreadTid = 0;
634    private int mPersistentVrThreadTid = 0;
635    final IPersistentVrStateCallbacks mPersistentVrModeListener =
636            new IPersistentVrStateCallbacks.Stub() {
637        @Override
638        public void onPersistentVrStateChanged(boolean enabled) {
639            synchronized(ActivityManagerService.this) {
640                // There are 4 possible cases here:
641                //
642                // Cases for enabled == true
643                // Invariant: mVrState != PERSISTENT_VR_MODE;
644                //    This is guaranteed as only this function sets mVrState to PERSISTENT_VR_MODE
645                // Invariant: mPersistentVrThreadTid == 0
646                //   This is guaranteed by VrManagerService, which only emits callbacks when the
647                //   mode changes, and in setPersistentVrThread, which only sets
648                //   mPersistentVrThreadTid when mVrState = PERSISTENT_VR_MODE
649                // Case 1: mTopAppVrThreadTid > 0 (someone called setVrThread successfully and is
650                // the top-app)
651                //     We reset the app which currently has SCHED_FIFO (mPersistentVrThreadTid) to
652                //     SCHED_OTHER
653                // Case 2: mTopAppVrThreadTid == 0
654                //     Do nothing
655                //
656                // Cases for enabled == false
657                // Invariant: mVrState == PERSISTENT_VR_MODE;
658                //     This is guaranteed by VrManagerService, which only emits callbacks when the
659                //     mode changes, and the only other assignment of mVrState outside of this
660                //     function checks if mVrState != PERSISTENT_VR_MODE
661                // Invariant: mTopAppVrThreadTid == 0
662                //     This is guaranteed in that mTopAppVrThreadTid is only set to a tid when
663                //     mVrState is VR_MODE, and is explicitly set to 0 when setPersistentVrThread is
664                //     called
665                //   mPersistentVrThreadTid > 0 (someone called setPersistentVrThread successfully)
666                //     3. Reset mPersistentVrThreadTidto SCHED_OTHER
667                //   mPersistentVrThreadTid == 0
668                //     4. Do nothing
669                if (enabled) {
670                    mVrState = PERSISTENT_VR_MODE;
671                } else {
672                    // Leaving persistent mode implies leaving VR mode.
673                    mVrState = NON_VR_MODE;
674                }
675
676                if (mVrState == PERSISTENT_VR_MODE) {
677                    if (mTopAppVrThreadTid > 0) {
678                        // Ensure that when entering persistent VR mode the last top-app loses
679                        // SCHED_FIFO.
680                        Process.setThreadScheduler(mTopAppVrThreadTid, Process.SCHED_OTHER, 0);
681                        mTopAppVrThreadTid = 0;
682                    }
683                } else if (mPersistentVrThreadTid > 0) {
684                    // Ensure that when leaving persistent VR mode we reschedule the high priority
685                    // persistent thread.
686                    Process.setThreadScheduler(mPersistentVrThreadTid, Process.SCHED_OTHER, 0);
687                    mPersistentVrThreadTid = 0;
688                }
689            }
690        }
691    };
692
693    // VR Compatibility Display Id.
694    int mVrCompatibilityDisplayId = INVALID_DISPLAY;
695
696    // Whether we should use SCHED_FIFO for UI and RenderThreads.
697    private boolean mUseFifoUiScheduling = false;
698
699    BroadcastQueue mFgBroadcastQueue;
700    BroadcastQueue mBgBroadcastQueue;
701    // Convenient for easy iteration over the queues. Foreground is first
702    // so that dispatch of foreground broadcasts gets precedence.
703    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
704
705    BroadcastStats mLastBroadcastStats;
706    BroadcastStats mCurBroadcastStats;
707
708    BroadcastQueue broadcastQueueForIntent(Intent intent) {
709        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
710        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
711                "Broadcast intent " + intent + " on "
712                + (isFg ? "foreground" : "background") + " queue");
713        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
714    }
715
716    /**
717     * The last resumed activity. This is identical to the current resumed activity most
718     * of the time but could be different when we're pausing one activity before we resume
719     * another activity.
720     */
721    private ActivityRecord mLastResumedActivity;
722
723    /**
724     * If non-null, we are tracking the time the user spends in the currently focused app.
725     */
726    private AppTimeTracker mCurAppTimeTracker;
727
728    /**
729     * List of intents that were used to start the most recent tasks.
730     */
731    final RecentTasks mRecentTasks;
732
733    /**
734     * For addAppTask: cached of the last activity component that was added.
735     */
736    ComponentName mLastAddedTaskComponent;
737
738    /**
739     * For addAppTask: cached of the last activity uid that was added.
740     */
741    int mLastAddedTaskUid;
742
743    /**
744     * For addAppTask: cached of the last ActivityInfo that was added.
745     */
746    ActivityInfo mLastAddedTaskActivity;
747
748    /**
749     * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
750     */
751    SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
752
753    /**
754     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
755     */
756    String mDeviceOwnerName;
757
758    final UserController mUserController;
759
760    final AppErrors mAppErrors;
761
762    /**
763     * Indicates the maximum time spent waiting for the network rules to get updated.
764     */
765    @VisibleForTesting
766    long mWaitForNetworkTimeoutMs;
767
768    public boolean canShowErrorDialogs() {
769        return mShowDialogs && !mSleeping && !mShuttingDown
770                && !mKeyguardController.isKeyguardShowing();
771    }
772
773    private static final class PriorityState {
774        // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
775        // the current thread is currently in. When it drops down to zero, we will no longer boost
776        // the thread's priority.
777        private int regionCounter = 0;
778
779        // The thread's previous priority before boosting.
780        private int prevPriority = Integer.MIN_VALUE;
781    }
782
783    static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
784        @Override protected PriorityState initialValue() {
785            return new PriorityState();
786        }
787    };
788
789    static void boostPriorityForLockedSection() {
790        int tid = Process.myTid();
791        int prevPriority = Process.getThreadPriority(tid);
792        PriorityState state = sThreadPriorityState.get();
793        if (state.regionCounter == 0 && prevPriority > -2) {
794            state.prevPriority = prevPriority;
795            Process.setThreadPriority(tid, -2);
796        }
797        state.regionCounter++;
798        if (LockGuard.ENABLED) {
799            LockGuard.guard(LockGuard.INDEX_ACTIVITY);
800        }
801    }
802
803    static void resetPriorityAfterLockedSection() {
804        PriorityState state = sThreadPriorityState.get();
805        state.regionCounter--;
806        if (state.regionCounter == 0 && state.prevPriority > -2) {
807            Process.setThreadPriority(Process.myTid(), state.prevPriority);
808        }
809    }
810
811    public class PendingAssistExtras extends Binder implements Runnable {
812        public final ActivityRecord activity;
813        public boolean isHome;
814        public final Bundle extras;
815        public final Intent intent;
816        public final String hint;
817        public final IResultReceiver receiver;
818        public final int userHandle;
819        public boolean haveResult = false;
820        public Bundle result = null;
821        public AssistStructure structure = null;
822        public AssistContent content = null;
823        public Bundle receiverExtras;
824
825        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
826                String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
827            activity = _activity;
828            extras = _extras;
829            intent = _intent;
830            hint = _hint;
831            receiver = _receiver;
832            receiverExtras = _receiverExtras;
833            userHandle = _userHandle;
834        }
835
836        @Override
837        public void run() {
838            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
839            synchronized (this) {
840                haveResult = true;
841                notifyAll();
842            }
843            pendingAssistExtrasTimedOut(this);
844        }
845    }
846
847    final ArrayList<PendingAssistExtras> mPendingAssistExtras
848            = new ArrayList<PendingAssistExtras>();
849
850    /**
851     * Process management.
852     */
853    final ProcessList mProcessList = new ProcessList();
854
855    /**
856     * All of the applications we currently have running organized by name.
857     * The keys are strings of the application package name (as
858     * returned by the package manager), and the keys are ApplicationRecord
859     * objects.
860     */
861    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
862
863    /**
864     * Tracking long-term execution of processes to look for abuse and other
865     * bad app behavior.
866     */
867    final ProcessStatsService mProcessStats;
868
869    /**
870     * The currently running isolated processes.
871     */
872    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
873
874    /**
875     * Counter for assigning isolated process uids, to avoid frequently reusing the
876     * same ones.
877     */
878    int mNextIsolatedProcessUid = 0;
879
880    /**
881     * The currently running heavy-weight process, if any.
882     */
883    ProcessRecord mHeavyWeightProcess = null;
884
885    /**
886     * Non-persistent app uid whitelist for background restrictions
887     */
888    int[] mBackgroundUidWhitelist = new int[] {
889            Process.BLUETOOTH_UID
890    };
891
892    /**
893     * Broadcast actions that will always be deliverable to unlaunched/background apps
894     */
895    ArraySet<String> mBackgroundLaunchBroadcasts;
896
897    /**
898     * All of the processes we currently have running organized by pid.
899     * The keys are the pid running the application.
900     *
901     * <p>NOTE: This object is protected by its own lock, NOT the global
902     * activity manager lock!
903     */
904    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
905
906    /**
907     * All of the processes that have been forced to be foreground.  The key
908     * is the pid of the caller who requested it (we hold a death
909     * link on it).
910     */
911    abstract class ForegroundToken implements IBinder.DeathRecipient {
912        int pid;
913        IBinder token;
914    }
915    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
916
917    /**
918     * List of records for processes that someone had tried to start before the
919     * system was ready.  We don't start them at that point, but ensure they
920     * are started by the time booting is complete.
921     */
922    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
923
924    /**
925     * List of persistent applications that are in the process
926     * of being started.
927     */
928    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
929
930    /**
931     * Processes that are being forcibly torn down.
932     */
933    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
934
935    /**
936     * List of running applications, sorted by recent usage.
937     * The first entry in the list is the least recently used.
938     */
939    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
940
941    /**
942     * Where in mLruProcesses that the processes hosting activities start.
943     */
944    int mLruProcessActivityStart = 0;
945
946    /**
947     * Where in mLruProcesses that the processes hosting services start.
948     * This is after (lower index) than mLruProcessesActivityStart.
949     */
950    int mLruProcessServiceStart = 0;
951
952    /**
953     * List of processes that should gc as soon as things are idle.
954     */
955    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
956
957    /**
958     * Processes we want to collect PSS data from.
959     */
960    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
961
962    private boolean mBinderTransactionTrackingEnabled = false;
963
964    /**
965     * Last time we requested PSS data of all processes.
966     */
967    long mLastFullPssTime = SystemClock.uptimeMillis();
968
969    /**
970     * If set, the next time we collect PSS data we should do a full collection
971     * with data from native processes and the kernel.
972     */
973    boolean mFullPssPending = false;
974
975    /**
976     * This is the process holding what we currently consider to be
977     * the "home" activity.
978     */
979    ProcessRecord mHomeProcess;
980
981    /**
982     * This is the process holding the activity the user last visited that
983     * is in a different process from the one they are currently in.
984     */
985    ProcessRecord mPreviousProcess;
986
987    /**
988     * The time at which the previous process was last visible.
989     */
990    long mPreviousProcessVisibleTime;
991
992    /**
993     * Track all uids that have actively running processes.
994     */
995    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
996
997    /**
998     * This is for verifying the UID report flow.
999     */
1000    static final boolean VALIDATE_UID_STATES = true;
1001    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
1002
1003    /**
1004     * Packages that the user has asked to have run in screen size
1005     * compatibility mode instead of filling the screen.
1006     */
1007    final CompatModePackages mCompatModePackages;
1008
1009    /**
1010     * Set of IntentSenderRecord objects that are currently active.
1011     */
1012    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
1013            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
1014
1015    /**
1016     * Fingerprints (hashCode()) of stack traces that we've
1017     * already logged DropBox entries for.  Guarded by itself.  If
1018     * something (rogue user app) forces this over
1019     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
1020     */
1021    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
1022    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
1023
1024    /**
1025     * Strict Mode background batched logging state.
1026     *
1027     * The string buffer is guarded by itself, and its lock is also
1028     * used to determine if another batched write is already
1029     * in-flight.
1030     */
1031    private final StringBuilder mStrictModeBuffer = new StringBuilder();
1032
1033    /**
1034     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
1035     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
1036     */
1037    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
1038
1039    /**
1040     * Resolver for broadcast intents to registered receivers.
1041     * Holds BroadcastFilter (subclass of IntentFilter).
1042     */
1043    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1044            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
1045        @Override
1046        protected boolean allowFilterResult(
1047                BroadcastFilter filter, List<BroadcastFilter> dest) {
1048            IBinder target = filter.receiverList.receiver.asBinder();
1049            for (int i = dest.size() - 1; i >= 0; i--) {
1050                if (dest.get(i).receiverList.receiver.asBinder() == target) {
1051                    return false;
1052                }
1053            }
1054            return true;
1055        }
1056
1057        @Override
1058        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
1059            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
1060                    || userId == filter.owningUserId) {
1061                return super.newResult(filter, match, userId);
1062            }
1063            return null;
1064        }
1065
1066        @Override
1067        protected BroadcastFilter[] newArray(int size) {
1068            return new BroadcastFilter[size];
1069        }
1070
1071        @Override
1072        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1073            return packageName.equals(filter.packageName);
1074        }
1075    };
1076
1077    /**
1078     * State of all active sticky broadcasts per user.  Keys are the action of the
1079     * sticky Intent, values are an ArrayList of all broadcasted intents with
1080     * that action (which should usually be one).  The SparseArray is keyed
1081     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1082     * for stickies that are sent to all users.
1083     */
1084    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1085            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1086
1087    final ActiveServices mServices;
1088
1089    final static class Association {
1090        final int mSourceUid;
1091        final String mSourceProcess;
1092        final int mTargetUid;
1093        final ComponentName mTargetComponent;
1094        final String mTargetProcess;
1095
1096        int mCount;
1097        long mTime;
1098
1099        int mNesting;
1100        long mStartTime;
1101
1102        // states of the source process when the bind occurred.
1103        int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1104        long mLastStateUptime;
1105        long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1106                - ActivityManager.MIN_PROCESS_STATE+1];
1107
1108        Association(int sourceUid, String sourceProcess, int targetUid,
1109                ComponentName targetComponent, String targetProcess) {
1110            mSourceUid = sourceUid;
1111            mSourceProcess = sourceProcess;
1112            mTargetUid = targetUid;
1113            mTargetComponent = targetComponent;
1114            mTargetProcess = targetProcess;
1115        }
1116    }
1117
1118    /**
1119     * When service association tracking is enabled, this is all of the associations we
1120     * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1121     * -> association data.
1122     */
1123    final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1124            mAssociations = new SparseArray<>();
1125    boolean mTrackingAssociations;
1126
1127    /**
1128     * Backup/restore process management
1129     */
1130    String mBackupAppName = null;
1131    BackupRecord mBackupTarget = null;
1132
1133    final ProviderMap mProviderMap;
1134
1135    /**
1136     * List of content providers who have clients waiting for them.  The
1137     * application is currently being launched and the provider will be
1138     * removed from this list once it is published.
1139     */
1140    final ArrayList<ContentProviderRecord> mLaunchingProviders
1141            = new ArrayList<ContentProviderRecord>();
1142
1143    /**
1144     * File storing persisted {@link #mGrantedUriPermissions}.
1145     */
1146    private final AtomicFile mGrantFile;
1147
1148    /** XML constants used in {@link #mGrantFile} */
1149    private static final String TAG_URI_GRANTS = "uri-grants";
1150    private static final String TAG_URI_GRANT = "uri-grant";
1151    private static final String ATTR_USER_HANDLE = "userHandle";
1152    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1153    private static final String ATTR_TARGET_USER_ID = "targetUserId";
1154    private static final String ATTR_SOURCE_PKG = "sourcePkg";
1155    private static final String ATTR_TARGET_PKG = "targetPkg";
1156    private static final String ATTR_URI = "uri";
1157    private static final String ATTR_MODE_FLAGS = "modeFlags";
1158    private static final String ATTR_CREATED_TIME = "createdTime";
1159    private static final String ATTR_PREFIX = "prefix";
1160
1161    /**
1162     * Global set of specific {@link Uri} permissions that have been granted.
1163     * This optimized lookup structure maps from {@link UriPermission#targetUid}
1164     * to {@link UriPermission#uri} to {@link UriPermission}.
1165     */
1166    @GuardedBy("this")
1167    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1168            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1169
1170    public static class GrantUri {
1171        public final int sourceUserId;
1172        public final Uri uri;
1173        public boolean prefix;
1174
1175        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1176            this.sourceUserId = sourceUserId;
1177            this.uri = uri;
1178            this.prefix = prefix;
1179        }
1180
1181        @Override
1182        public int hashCode() {
1183            int hashCode = 1;
1184            hashCode = 31 * hashCode + sourceUserId;
1185            hashCode = 31 * hashCode + uri.hashCode();
1186            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1187            return hashCode;
1188        }
1189
1190        @Override
1191        public boolean equals(Object o) {
1192            if (o instanceof GrantUri) {
1193                GrantUri other = (GrantUri) o;
1194                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1195                        && prefix == other.prefix;
1196            }
1197            return false;
1198        }
1199
1200        @Override
1201        public String toString() {
1202            String result = uri.toString() + " [user " + sourceUserId + "]";
1203            if (prefix) result += " [prefix]";
1204            return result;
1205        }
1206
1207        public String toSafeString() {
1208            String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1209            if (prefix) result += " [prefix]";
1210            return result;
1211        }
1212
1213        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1214            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1215                    ContentProvider.getUriWithoutUserId(uri), false);
1216        }
1217    }
1218
1219    CoreSettingsObserver mCoreSettingsObserver;
1220
1221    FontScaleSettingObserver mFontScaleSettingObserver;
1222
1223    private final class FontScaleSettingObserver extends ContentObserver {
1224        private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1225
1226        public FontScaleSettingObserver() {
1227            super(mHandler);
1228            ContentResolver resolver = mContext.getContentResolver();
1229            resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1230        }
1231
1232        @Override
1233        public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1234            if (mFontScaleUri.equals(uri)) {
1235                updateFontScaleIfNeeded(userId);
1236            }
1237        }
1238    }
1239
1240    /**
1241     * Thread-local storage used to carry caller permissions over through
1242     * indirect content-provider access.
1243     */
1244    private class Identity {
1245        public final IBinder token;
1246        public final int pid;
1247        public final int uid;
1248
1249        Identity(IBinder _token, int _pid, int _uid) {
1250            token = _token;
1251            pid = _pid;
1252            uid = _uid;
1253        }
1254    }
1255
1256    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1257
1258    /**
1259     * All information we have collected about the runtime performance of
1260     * any user id that can impact battery performance.
1261     */
1262    final BatteryStatsService mBatteryStatsService;
1263
1264    /**
1265     * Information about component usage
1266     */
1267    UsageStatsManagerInternal mUsageStatsService;
1268
1269    /**
1270     * Access to DeviceIdleController service.
1271     */
1272    DeviceIdleController.LocalService mLocalDeviceIdleController;
1273
1274    /**
1275     * Set of app ids that are whitelisted for device idle and thus background check.
1276     */
1277    int[] mDeviceIdleWhitelist = new int[0];
1278
1279    /**
1280     * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1281     */
1282    int[] mDeviceIdleTempWhitelist = new int[0];
1283
1284    /**
1285     * Information about and control over application operations
1286     */
1287    final AppOpsService mAppOpsService;
1288
1289    /** Current sequencing integer of the configuration, for skipping old configurations. */
1290    private int mConfigurationSeq;
1291
1292    /**
1293     * Temp object used when global and/or display override configuration is updated. It is also
1294     * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1295     * anyone...
1296     */
1297    private Configuration mTempConfig = new Configuration();
1298
1299    private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1300            new UpdateConfigurationResult();
1301    private static final class UpdateConfigurationResult {
1302        // Configuration changes that were updated.
1303        int changes;
1304        // If the activity was relaunched to match the new configuration.
1305        boolean activityRelaunched;
1306
1307        void reset() {
1308            changes = 0;
1309            activityRelaunched = false;
1310        }
1311    }
1312
1313    boolean mSuppressResizeConfigChanges;
1314
1315    /**
1316     * Hardware-reported OpenGLES version.
1317     */
1318    final int GL_ES_VERSION;
1319
1320    /**
1321     * List of initialization arguments to pass to all processes when binding applications to them.
1322     * For example, references to the commonly used services.
1323     */
1324    HashMap<String, IBinder> mAppBindArgs;
1325    HashMap<String, IBinder> mIsolatedAppBindArgs;
1326
1327    /**
1328     * Temporary to avoid allocations.  Protected by main lock.
1329     */
1330    final StringBuilder mStringBuilder = new StringBuilder(256);
1331
1332    /**
1333     * Used to control how we initialize the service.
1334     */
1335    ComponentName mTopComponent;
1336    String mTopAction = Intent.ACTION_MAIN;
1337    String mTopData;
1338
1339    volatile boolean mProcessesReady = false;
1340    volatile boolean mSystemReady = false;
1341    volatile boolean mOnBattery = false;
1342    volatile int mFactoryTest;
1343
1344    @GuardedBy("this") boolean mBooting = false;
1345    @GuardedBy("this") boolean mCallFinishBooting = false;
1346    @GuardedBy("this") boolean mBootAnimationComplete = false;
1347    @GuardedBy("this") boolean mLaunchWarningShown = false;
1348    @GuardedBy("this") boolean mCheckedForSetup = false;
1349
1350    Context mContext;
1351
1352    /**
1353     * The time at which we will allow normal application switches again,
1354     * after a call to {@link #stopAppSwitches()}.
1355     */
1356    long mAppSwitchesAllowedTime;
1357
1358    /**
1359     * This is set to true after the first switch after mAppSwitchesAllowedTime
1360     * is set; any switches after that will clear the time.
1361     */
1362    boolean mDidAppSwitch;
1363
1364    /**
1365     * Last time (in realtime) at which we checked for power usage.
1366     */
1367    long mLastPowerCheckRealtime;
1368
1369    /**
1370     * Last time (in uptime) at which we checked for power usage.
1371     */
1372    long mLastPowerCheckUptime;
1373
1374    /**
1375     * Set while we are wanting to sleep, to prevent any
1376     * activities from being started/resumed.
1377     *
1378     * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1379     *
1380     * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1381     * while in the sleep state until there is a pending transition out of sleep, in which case
1382     * mSleeping is set to false, and remains false while awake.
1383     *
1384     * Whether mSleeping can quickly toggled between true/false without the device actually
1385     * display changing states is undefined.
1386     */
1387    private boolean mSleeping = false;
1388
1389    /**
1390     * The process state used for processes that are running the top activities.
1391     * This changes between TOP and TOP_SLEEPING to following mSleeping.
1392     */
1393    int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1394
1395    /**
1396     * Set while we are running a voice interaction.  This overrides
1397     * sleeping while it is active.
1398     */
1399    private IVoiceInteractionSession mRunningVoice;
1400
1401    /**
1402     * For some direct access we need to power manager.
1403     */
1404    PowerManagerInternal mLocalPowerManager;
1405
1406    /**
1407     * We want to hold a wake lock while running a voice interaction session, since
1408     * this may happen with the screen off and we need to keep the CPU running to
1409     * be able to continue to interact with the user.
1410     */
1411    PowerManager.WakeLock mVoiceWakeLock;
1412
1413    /**
1414     * State of external calls telling us if the device is awake or asleep.
1415     */
1416    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1417
1418    /**
1419     * A list of tokens that cause the top activity to be put to sleep.
1420     * They are used by components that may hide and block interaction with underlying
1421     * activities.
1422     */
1423    final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1424
1425    /**
1426     * Set if we are shutting down the system, similar to sleeping.
1427     */
1428    boolean mShuttingDown = false;
1429
1430    /**
1431     * Current sequence id for oom_adj computation traversal.
1432     */
1433    int mAdjSeq = 0;
1434
1435    /**
1436     * Current sequence id for process LRU updating.
1437     */
1438    int mLruSeq = 0;
1439
1440    /**
1441     * Keep track of the non-cached/empty process we last found, to help
1442     * determine how to distribute cached/empty processes next time.
1443     */
1444    int mNumNonCachedProcs = 0;
1445
1446    /**
1447     * Keep track of the number of cached hidden procs, to balance oom adj
1448     * distribution between those and empty procs.
1449     */
1450    int mNumCachedHiddenProcs = 0;
1451
1452    /**
1453     * Keep track of the number of service processes we last found, to
1454     * determine on the next iteration which should be B services.
1455     */
1456    int mNumServiceProcs = 0;
1457    int mNewNumAServiceProcs = 0;
1458    int mNewNumServiceProcs = 0;
1459
1460    /**
1461     * Allow the current computed overall memory level of the system to go down?
1462     * This is set to false when we are killing processes for reasons other than
1463     * memory management, so that the now smaller process list will not be taken as
1464     * an indication that memory is tighter.
1465     */
1466    boolean mAllowLowerMemLevel = false;
1467
1468    /**
1469     * The last computed memory level, for holding when we are in a state that
1470     * processes are going away for other reasons.
1471     */
1472    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1473
1474    /**
1475     * The last total number of process we have, to determine if changes actually look
1476     * like a shrinking number of process due to lower RAM.
1477     */
1478    int mLastNumProcesses;
1479
1480    /**
1481     * The uptime of the last time we performed idle maintenance.
1482     */
1483    long mLastIdleTime = SystemClock.uptimeMillis();
1484
1485    /**
1486     * Total time spent with RAM that has been added in the past since the last idle time.
1487     */
1488    long mLowRamTimeSinceLastIdle = 0;
1489
1490    /**
1491     * If RAM is currently low, when that horrible situation started.
1492     */
1493    long mLowRamStartTime = 0;
1494
1495    /**
1496     * For reporting to battery stats the current top application.
1497     */
1498    private String mCurResumedPackage = null;
1499    private int mCurResumedUid = -1;
1500
1501    /**
1502     * For reporting to battery stats the apps currently running foreground
1503     * service.  The ProcessMap is package/uid tuples; each of these contain
1504     * an array of the currently foreground processes.
1505     */
1506    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1507            = new ProcessMap<ArrayList<ProcessRecord>>();
1508
1509    /**
1510     * This is set if we had to do a delayed dexopt of an app before launching
1511     * it, to increase the ANR timeouts in that case.
1512     */
1513    boolean mDidDexOpt;
1514
1515    /**
1516     * Set if the systemServer made a call to enterSafeMode.
1517     */
1518    boolean mSafeMode;
1519
1520    /**
1521     * If true, we are running under a test environment so will sample PSS from processes
1522     * much more rapidly to try to collect better data when the tests are rapidly
1523     * running through apps.
1524     */
1525    boolean mTestPssMode = false;
1526
1527    String mDebugApp = null;
1528    boolean mWaitForDebugger = false;
1529    boolean mDebugTransient = false;
1530    String mOrigDebugApp = null;
1531    boolean mOrigWaitForDebugger = false;
1532    boolean mAlwaysFinishActivities = false;
1533    boolean mForceResizableActivities;
1534    boolean mSupportsMultiWindow;
1535    boolean mSupportsSplitScreenMultiWindow;
1536    boolean mSupportsFreeformWindowManagement;
1537    boolean mSupportsPictureInPicture;
1538    boolean mSupportsLeanbackOnly;
1539    IActivityController mController = null;
1540    boolean mControllerIsAMonkey = false;
1541    String mProfileApp = null;
1542    ProcessRecord mProfileProc = null;
1543    String mProfileFile;
1544    ParcelFileDescriptor mProfileFd;
1545    int mSamplingInterval = 0;
1546    boolean mAutoStopProfiler = false;
1547    boolean mStreamingOutput = false;
1548    int mProfileType = 0;
1549    final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1550    String mMemWatchDumpProcName;
1551    String mMemWatchDumpFile;
1552    int mMemWatchDumpPid;
1553    int mMemWatchDumpUid;
1554    String mTrackAllocationApp = null;
1555    String mNativeDebuggingApp = null;
1556
1557    final long[] mTmpLong = new long[2];
1558
1559    private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1560
1561    /**
1562     * A global counter for generating sequence numbers.
1563     * This value will be used when incrementing sequence numbers in individual uidRecords.
1564     *
1565     * Having a global counter ensures that seq numbers are monotonically increasing for a
1566     * particular uid even when the uidRecord is re-created.
1567     */
1568    @GuardedBy("this")
1569    @VisibleForTesting
1570    long mProcStateSeqCounter = 0;
1571
1572    private final Injector mInjector;
1573
1574    static final class ProcessChangeItem {
1575        static final int CHANGE_ACTIVITIES = 1<<0;
1576        int changes;
1577        int uid;
1578        int pid;
1579        int processState;
1580        boolean foregroundActivities;
1581    }
1582
1583    static final class UidObserverRegistration {
1584        final int uid;
1585        final String pkg;
1586        final int which;
1587        final int cutpoint;
1588
1589        final SparseIntArray lastProcStates;
1590
1591        UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1592            uid = _uid;
1593            pkg = _pkg;
1594            which = _which;
1595            cutpoint = _cutpoint;
1596            if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1597                lastProcStates = new SparseIntArray();
1598            } else {
1599                lastProcStates = null;
1600            }
1601        }
1602    }
1603
1604    final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1605    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1606
1607    final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1608    final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1609
1610    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1611    UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1612
1613    final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1614    final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1615
1616    /**
1617     * Runtime CPU use collection thread.  This object's lock is used to
1618     * perform synchronization with the thread (notifying it to run).
1619     */
1620    final Thread mProcessCpuThread;
1621
1622    /**
1623     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1624     * Must acquire this object's lock when accessing it.
1625     * NOTE: this lock will be held while doing long operations (trawling
1626     * through all processes in /proc), so it should never be acquired by
1627     * any critical paths such as when holding the main activity manager lock.
1628     */
1629    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1630            MONITOR_THREAD_CPU_USAGE);
1631    final AtomicLong mLastCpuTime = new AtomicLong(0);
1632    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1633    final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1634
1635    long mLastWriteTime = 0;
1636
1637    /**
1638     * Used to retain an update lock when the foreground activity is in
1639     * immersive mode.
1640     */
1641    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1642
1643    /**
1644     * Set to true after the system has finished booting.
1645     */
1646    boolean mBooted = false;
1647
1648    WindowManagerService mWindowManager;
1649    final ActivityThread mSystemThread;
1650
1651    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1652        final ProcessRecord mApp;
1653        final int mPid;
1654        final IApplicationThread mAppThread;
1655
1656        AppDeathRecipient(ProcessRecord app, int pid,
1657                IApplicationThread thread) {
1658            if (DEBUG_ALL) Slog.v(
1659                TAG, "New death recipient " + this
1660                + " for thread " + thread.asBinder());
1661            mApp = app;
1662            mPid = pid;
1663            mAppThread = thread;
1664        }
1665
1666        @Override
1667        public void binderDied() {
1668            if (DEBUG_ALL) Slog.v(
1669                TAG, "Death received in " + this
1670                + " for thread " + mAppThread.asBinder());
1671            synchronized(ActivityManagerService.this) {
1672                appDiedLocked(mApp, mPid, mAppThread, true);
1673            }
1674        }
1675    }
1676
1677    static final int SHOW_ERROR_UI_MSG = 1;
1678    static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1679    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1680    static final int UPDATE_CONFIGURATION_MSG = 4;
1681    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1682    static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1683    static final int SERVICE_TIMEOUT_MSG = 12;
1684    static final int UPDATE_TIME_ZONE = 13;
1685    static final int SHOW_UID_ERROR_UI_MSG = 14;
1686    static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1687    static final int PROC_START_TIMEOUT_MSG = 20;
1688    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1689    static final int KILL_APPLICATION_MSG = 22;
1690    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1691    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1692    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1693    static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1694    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1695    static final int CLEAR_DNS_CACHE_MSG = 28;
1696    static final int UPDATE_HTTP_PROXY_MSG = 29;
1697    static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1698    static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1699    static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1700    static final int REPORT_MEM_USAGE_MSG = 33;
1701    static final int REPORT_USER_SWITCH_MSG = 34;
1702    static final int CONTINUE_USER_SWITCH_MSG = 35;
1703    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1704    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1705    static final int PERSIST_URI_GRANTS_MSG = 38;
1706    static final int REQUEST_ALL_PSS_MSG = 39;
1707    static final int START_PROFILES_MSG = 40;
1708    static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1709    static final int SYSTEM_USER_START_MSG = 42;
1710    static final int SYSTEM_USER_CURRENT_MSG = 43;
1711    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1712    static final int FINISH_BOOTING_MSG = 45;
1713    static final int START_USER_SWITCH_UI_MSG = 46;
1714    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1715    static final int DISMISS_DIALOG_UI_MSG = 48;
1716    static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1717    static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1718    static final int DELETE_DUMPHEAP_MSG = 51;
1719    static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1720    static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1721    static final int REPORT_TIME_TRACKER_MSG = 54;
1722    static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1723    static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1724    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1725    static final int IDLE_UIDS_MSG = 58;
1726    static final int SYSTEM_USER_UNLOCK_MSG = 59;
1727    static final int LOG_STACK_STATE = 60;
1728    static final int VR_MODE_CHANGE_MSG = 61;
1729    static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1730    static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1731    static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1732    static final int NOTIFY_VR_SLEEPING_MSG = 65;
1733    static final int START_USER_SWITCH_FG_MSG = 712;
1734
1735    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1736    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1737    static final int FIRST_COMPAT_MODE_MSG = 300;
1738    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1739
1740    static ServiceThread sKillThread = null;
1741    static KillHandler sKillHandler = null;
1742
1743    CompatModeDialog mCompatModeDialog;
1744    UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1745    long mLastMemUsageReportTime = 0;
1746
1747    /**
1748     * Flag whether the current user is a "monkey", i.e. whether
1749     * the UI is driven by a UI automation tool.
1750     */
1751    private boolean mUserIsMonkey;
1752
1753    /** Flag whether the device has a Recents UI */
1754    boolean mHasRecents;
1755
1756    /** The dimensions of the thumbnails in the Recents UI. */
1757    int mThumbnailWidth;
1758    int mThumbnailHeight;
1759    float mFullscreenThumbnailScale;
1760
1761    final ServiceThread mHandlerThread;
1762    final MainHandler mHandler;
1763    final Handler mUiHandler;
1764
1765    final ActivityManagerConstants mConstants;
1766
1767    PackageManagerInternal mPackageManagerInt;
1768
1769    // VoiceInteraction session ID that changes for each new request except when
1770    // being called for multiwindow assist in a single session.
1771    private int mViSessionId = 1000;
1772
1773    final boolean mPermissionReviewRequired;
1774
1775    /**
1776     * Current global configuration information. Contains general settings for the entire system,
1777     * also corresponds to the merged configuration of the default display.
1778     */
1779    Configuration getGlobalConfiguration() {
1780        return mStackSupervisor.getConfiguration();
1781    }
1782
1783    final class KillHandler extends Handler {
1784        static final int KILL_PROCESS_GROUP_MSG = 4000;
1785
1786        public KillHandler(Looper looper) {
1787            super(looper, null, true);
1788        }
1789
1790        @Override
1791        public void handleMessage(Message msg) {
1792            switch (msg.what) {
1793                case KILL_PROCESS_GROUP_MSG:
1794                {
1795                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1796                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1797                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1798                }
1799                break;
1800
1801                default:
1802                    super.handleMessage(msg);
1803            }
1804        }
1805    }
1806
1807    final class UiHandler extends Handler {
1808        public UiHandler() {
1809            super(com.android.server.UiThread.get().getLooper(), null, true);
1810        }
1811
1812        @Override
1813        public void handleMessage(Message msg) {
1814            switch (msg.what) {
1815            case SHOW_ERROR_UI_MSG: {
1816                mAppErrors.handleShowAppErrorUi(msg);
1817                ensureBootCompleted();
1818            } break;
1819            case SHOW_NOT_RESPONDING_UI_MSG: {
1820                mAppErrors.handleShowAnrUi(msg);
1821                ensureBootCompleted();
1822            } break;
1823            case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1824                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1825                synchronized (ActivityManagerService.this) {
1826                    ProcessRecord proc = (ProcessRecord) data.get("app");
1827                    if (proc == null) {
1828                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1829                        break;
1830                    }
1831                    if (proc.crashDialog != null) {
1832                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1833                        return;
1834                    }
1835                    AppErrorResult res = (AppErrorResult) data.get("result");
1836                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1837                        Dialog d = new StrictModeViolationDialog(mContext,
1838                                ActivityManagerService.this, res, proc);
1839                        d.show();
1840                        proc.crashDialog = d;
1841                    } else {
1842                        // The device is asleep, so just pretend that the user
1843                        // saw a crash dialog and hit "force quit".
1844                        res.set(0);
1845                    }
1846                }
1847                ensureBootCompleted();
1848            } break;
1849            case SHOW_FACTORY_ERROR_UI_MSG: {
1850                Dialog d = new FactoryErrorDialog(
1851                    mContext, msg.getData().getCharSequence("msg"));
1852                d.show();
1853                ensureBootCompleted();
1854            } break;
1855            case WAIT_FOR_DEBUGGER_UI_MSG: {
1856                synchronized (ActivityManagerService.this) {
1857                    ProcessRecord app = (ProcessRecord)msg.obj;
1858                    if (msg.arg1 != 0) {
1859                        if (!app.waitedForDebugger) {
1860                            Dialog d = new AppWaitingForDebuggerDialog(
1861                                    ActivityManagerService.this,
1862                                    mContext, app);
1863                            app.waitDialog = d;
1864                            app.waitedForDebugger = true;
1865                            d.show();
1866                        }
1867                    } else {
1868                        if (app.waitDialog != null) {
1869                            app.waitDialog.dismiss();
1870                            app.waitDialog = null;
1871                        }
1872                    }
1873                }
1874            } break;
1875            case SHOW_UID_ERROR_UI_MSG: {
1876                if (mShowDialogs) {
1877                    AlertDialog d = new BaseErrorDialog(mContext);
1878                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1879                    d.setCancelable(false);
1880                    d.setTitle(mContext.getText(R.string.android_system_label));
1881                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1882                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1883                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1884                    d.show();
1885                }
1886            } break;
1887            case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1888                if (mShowDialogs) {
1889                    AlertDialog d = new BaseErrorDialog(mContext);
1890                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1891                    d.setCancelable(false);
1892                    d.setTitle(mContext.getText(R.string.android_system_label));
1893                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1894                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1895                            obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1896                    d.show();
1897                }
1898            } break;
1899            case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1900                synchronized (ActivityManagerService.this) {
1901                    ActivityRecord ar = (ActivityRecord) msg.obj;
1902                    if (mCompatModeDialog != null) {
1903                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1904                                ar.info.applicationInfo.packageName)) {
1905                            return;
1906                        }
1907                        mCompatModeDialog.dismiss();
1908                        mCompatModeDialog = null;
1909                    }
1910                    if (ar != null && false) {
1911                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1912                                ar.packageName)) {
1913                            int mode = mCompatModePackages.computeCompatModeLocked(
1914                                    ar.info.applicationInfo);
1915                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1916                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1917                                mCompatModeDialog = new CompatModeDialog(
1918                                        ActivityManagerService.this, mContext,
1919                                        ar.info.applicationInfo);
1920                                mCompatModeDialog.show();
1921                            }
1922                        }
1923                    }
1924                }
1925                break;
1926            }
1927            case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1928                synchronized (ActivityManagerService.this) {
1929                    final ActivityRecord ar = (ActivityRecord) msg.obj;
1930                    if (mUnsupportedDisplaySizeDialog != null) {
1931                        mUnsupportedDisplaySizeDialog.dismiss();
1932                        mUnsupportedDisplaySizeDialog = null;
1933                    }
1934                    if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1935                            ar.packageName)) {
1936                        // TODO(multi-display): Show dialog on appropriate display.
1937                        mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1938                                ActivityManagerService.this, mContext, ar.info.applicationInfo);
1939                        mUnsupportedDisplaySizeDialog.show();
1940                    }
1941                }
1942                break;
1943            }
1944            case START_USER_SWITCH_UI_MSG: {
1945                mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1946                break;
1947            }
1948            case DISMISS_DIALOG_UI_MSG: {
1949                final Dialog d = (Dialog) msg.obj;
1950                d.dismiss();
1951                break;
1952            }
1953            case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1954                dispatchProcessesChanged();
1955                break;
1956            }
1957            case DISPATCH_PROCESS_DIED_UI_MSG: {
1958                final int pid = msg.arg1;
1959                final int uid = msg.arg2;
1960                dispatchProcessDied(pid, uid);
1961                break;
1962            }
1963            case DISPATCH_UIDS_CHANGED_UI_MSG: {
1964                dispatchUidsChanged();
1965            } break;
1966            }
1967        }
1968    }
1969
1970    final class MainHandler extends Handler {
1971        public MainHandler(Looper looper) {
1972            super(looper, null, true);
1973        }
1974
1975        @Override
1976        public void handleMessage(Message msg) {
1977            switch (msg.what) {
1978            case UPDATE_CONFIGURATION_MSG: {
1979                final ContentResolver resolver = mContext.getContentResolver();
1980                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1981                        msg.arg1);
1982            } break;
1983            case GC_BACKGROUND_PROCESSES_MSG: {
1984                synchronized (ActivityManagerService.this) {
1985                    performAppGcsIfAppropriateLocked();
1986                }
1987            } break;
1988            case SERVICE_TIMEOUT_MSG: {
1989                if (mDidDexOpt) {
1990                    mDidDexOpt = false;
1991                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1992                    nmsg.obj = msg.obj;
1993                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1994                    return;
1995                }
1996                mServices.serviceTimeout((ProcessRecord)msg.obj);
1997            } break;
1998            case UPDATE_TIME_ZONE: {
1999                synchronized (ActivityManagerService.this) {
2000                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2001                        ProcessRecord r = mLruProcesses.get(i);
2002                        if (r.thread != null) {
2003                            try {
2004                                r.thread.updateTimeZone();
2005                            } catch (RemoteException ex) {
2006                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
2007                            }
2008                        }
2009                    }
2010                }
2011            } break;
2012            case CLEAR_DNS_CACHE_MSG: {
2013                synchronized (ActivityManagerService.this) {
2014                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2015                        ProcessRecord r = mLruProcesses.get(i);
2016                        if (r.thread != null) {
2017                            try {
2018                                r.thread.clearDnsCache();
2019                            } catch (RemoteException ex) {
2020                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2021                            }
2022                        }
2023                    }
2024                }
2025            } break;
2026            case UPDATE_HTTP_PROXY_MSG: {
2027                ProxyInfo proxy = (ProxyInfo)msg.obj;
2028                String host = "";
2029                String port = "";
2030                String exclList = "";
2031                Uri pacFileUrl = Uri.EMPTY;
2032                if (proxy != null) {
2033                    host = proxy.getHost();
2034                    port = Integer.toString(proxy.getPort());
2035                    exclList = proxy.getExclusionListAsString();
2036                    pacFileUrl = proxy.getPacFileUrl();
2037                }
2038                synchronized (ActivityManagerService.this) {
2039                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2040                        ProcessRecord r = mLruProcesses.get(i);
2041                        if (r.thread != null) {
2042                            try {
2043                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2044                            } catch (RemoteException ex) {
2045                                Slog.w(TAG, "Failed to update http proxy for: " +
2046                                        r.info.processName);
2047                            }
2048                        }
2049                    }
2050                }
2051            } break;
2052            case PROC_START_TIMEOUT_MSG: {
2053                if (mDidDexOpt) {
2054                    mDidDexOpt = false;
2055                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2056                    nmsg.obj = msg.obj;
2057                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
2058                    return;
2059                }
2060                ProcessRecord app = (ProcessRecord)msg.obj;
2061                synchronized (ActivityManagerService.this) {
2062                    processStartTimedOutLocked(app);
2063                }
2064            } break;
2065            case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2066                ProcessRecord app = (ProcessRecord)msg.obj;
2067                synchronized (ActivityManagerService.this) {
2068                    processContentProviderPublishTimedOutLocked(app);
2069                }
2070            } break;
2071            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2072                synchronized (ActivityManagerService.this) {
2073                    mActivityStarter.doPendingActivityLaunchesLocked(true);
2074                }
2075            } break;
2076            case KILL_APPLICATION_MSG: {
2077                synchronized (ActivityManagerService.this) {
2078                    final int appId = msg.arg1;
2079                    final int userId = msg.arg2;
2080                    Bundle bundle = (Bundle)msg.obj;
2081                    String pkg = bundle.getString("pkg");
2082                    String reason = bundle.getString("reason");
2083                    forceStopPackageLocked(pkg, appId, false, false, true, false,
2084                            false, userId, reason);
2085                }
2086            } break;
2087            case FINALIZE_PENDING_INTENT_MSG: {
2088                ((PendingIntentRecord)msg.obj).completeFinalize();
2089            } break;
2090            case POST_HEAVY_NOTIFICATION_MSG: {
2091                INotificationManager inm = NotificationManager.getService();
2092                if (inm == null) {
2093                    return;
2094                }
2095
2096                ActivityRecord root = (ActivityRecord)msg.obj;
2097                ProcessRecord process = root.app;
2098                if (process == null) {
2099                    return;
2100                }
2101
2102                try {
2103                    Context context = mContext.createPackageContext(process.info.packageName, 0);
2104                    String text = mContext.getString(R.string.heavy_weight_notification,
2105                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
2106                    Notification notification =
2107                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2108                            .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2109                            .setWhen(0)
2110                            .setOngoing(true)
2111                            .setTicker(text)
2112                            .setColor(mContext.getColor(
2113                                    com.android.internal.R.color.system_notification_accent_color))
2114                            .setContentTitle(text)
2115                            .setContentText(
2116                                    mContext.getText(R.string.heavy_weight_notification_detail))
2117                            .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2118                                    root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2119                                    new UserHandle(root.userId)))
2120                            .build();
2121                    try {
2122                        int[] outId = new int[1];
2123                        inm.enqueueNotificationWithTag("android", "android", null,
2124                                R.string.heavy_weight_notification,
2125                                notification, outId, root.userId);
2126                    } catch (RuntimeException e) {
2127                        Slog.w(ActivityManagerService.TAG,
2128                                "Error showing notification for heavy-weight app", e);
2129                    } catch (RemoteException e) {
2130                    }
2131                } catch (NameNotFoundException e) {
2132                    Slog.w(TAG, "Unable to create context for heavy notification", e);
2133                }
2134            } break;
2135            case CANCEL_HEAVY_NOTIFICATION_MSG: {
2136                INotificationManager inm = NotificationManager.getService();
2137                if (inm == null) {
2138                    return;
2139                }
2140                try {
2141                    inm.cancelNotificationWithTag("android", null,
2142                            R.string.heavy_weight_notification,  msg.arg1);
2143                } catch (RuntimeException e) {
2144                    Slog.w(ActivityManagerService.TAG,
2145                            "Error canceling notification for service", e);
2146                } catch (RemoteException e) {
2147                }
2148            } break;
2149            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
2150                synchronized (ActivityManagerService.this) {
2151                    checkExcessivePowerUsageLocked(true);
2152                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2153                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
2154                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
2155                }
2156            } break;
2157            case REPORT_MEM_USAGE_MSG: {
2158                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2159                Thread thread = new Thread() {
2160                    @Override public void run() {
2161                        reportMemUsage(memInfos);
2162                    }
2163                };
2164                thread.start();
2165                break;
2166            }
2167            case START_USER_SWITCH_FG_MSG: {
2168                mUserController.startUserInForeground(msg.arg1);
2169                break;
2170            }
2171            case REPORT_USER_SWITCH_MSG: {
2172                mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2173                break;
2174            }
2175            case CONTINUE_USER_SWITCH_MSG: {
2176                mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2177                break;
2178            }
2179            case USER_SWITCH_TIMEOUT_MSG: {
2180                mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2181                break;
2182            }
2183            case IMMERSIVE_MODE_LOCK_MSG: {
2184                final boolean nextState = (msg.arg1 != 0);
2185                if (mUpdateLock.isHeld() != nextState) {
2186                    if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2187                            "Applying new update lock state '" + nextState
2188                            + "' for " + (ActivityRecord)msg.obj);
2189                    if (nextState) {
2190                        mUpdateLock.acquire();
2191                    } else {
2192                        mUpdateLock.release();
2193                    }
2194                }
2195                break;
2196            }
2197            case PERSIST_URI_GRANTS_MSG: {
2198                writeGrantedUriPermissions();
2199                break;
2200            }
2201            case REQUEST_ALL_PSS_MSG: {
2202                synchronized (ActivityManagerService.this) {
2203                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2204                }
2205                break;
2206            }
2207            case START_PROFILES_MSG: {
2208                synchronized (ActivityManagerService.this) {
2209                    mUserController.startProfilesLocked();
2210                }
2211                break;
2212            }
2213            case UPDATE_TIME_PREFERENCE_MSG: {
2214                // The user's time format preference might have changed.
2215                // For convenience we re-use the Intent extra values.
2216                synchronized (ActivityManagerService.this) {
2217                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2218                        ProcessRecord r = mLruProcesses.get(i);
2219                        if (r.thread != null) {
2220                            try {
2221                                r.thread.updateTimePrefs(msg.arg1);
2222                            } catch (RemoteException ex) {
2223                                Slog.w(TAG, "Failed to update preferences for: "
2224                                        + r.info.processName);
2225                            }
2226                        }
2227                    }
2228                }
2229                break;
2230            }
2231            case SYSTEM_USER_START_MSG: {
2232                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2233                        Integer.toString(msg.arg1), msg.arg1);
2234                mSystemServiceManager.startUser(msg.arg1);
2235                break;
2236            }
2237            case SYSTEM_USER_UNLOCK_MSG: {
2238                final int userId = msg.arg1;
2239                mSystemServiceManager.unlockUser(userId);
2240                synchronized (ActivityManagerService.this) {
2241                    mRecentTasks.loadUserRecentsLocked(userId);
2242                }
2243                if (userId == UserHandle.USER_SYSTEM) {
2244                    startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2245                }
2246                installEncryptionUnawareProviders(userId);
2247                mUserController.finishUserUnlocked((UserState) msg.obj);
2248                break;
2249            }
2250            case SYSTEM_USER_CURRENT_MSG: {
2251                mBatteryStatsService.noteEvent(
2252                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2253                        Integer.toString(msg.arg2), msg.arg2);
2254                mBatteryStatsService.noteEvent(
2255                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2256                        Integer.toString(msg.arg1), msg.arg1);
2257                mSystemServiceManager.switchUser(msg.arg1);
2258                break;
2259            }
2260            case ENTER_ANIMATION_COMPLETE_MSG: {
2261                synchronized (ActivityManagerService.this) {
2262                    ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2263                    if (r != null && r.app != null && r.app.thread != null) {
2264                        try {
2265                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2266                        } catch (RemoteException e) {
2267                        }
2268                    }
2269                }
2270                break;
2271            }
2272            case FINISH_BOOTING_MSG: {
2273                if (msg.arg1 != 0) {
2274                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2275                    finishBooting();
2276                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2277                }
2278                if (msg.arg2 != 0) {
2279                    enableScreenAfterBoot();
2280                }
2281                break;
2282            }
2283            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2284                try {
2285                    Locale l = (Locale) msg.obj;
2286                    IBinder service = ServiceManager.getService("mount");
2287                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2288                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2289                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2290                } catch (RemoteException e) {
2291                    Log.e(TAG, "Error storing locale for decryption UI", e);
2292                }
2293                break;
2294            }
2295            case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2296                final int uid = msg.arg1;
2297                final byte[] firstPacket = (byte[]) msg.obj;
2298
2299                synchronized (mPidsSelfLocked) {
2300                    for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2301                        final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2302                        if (p.uid == uid) {
2303                            try {
2304                                p.thread.notifyCleartextNetwork(firstPacket);
2305                            } catch (RemoteException ignored) {
2306                            }
2307                        }
2308                    }
2309                }
2310                break;
2311            }
2312            case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2313                final String procName;
2314                final int uid;
2315                final long memLimit;
2316                final String reportPackage;
2317                synchronized (ActivityManagerService.this) {
2318                    procName = mMemWatchDumpProcName;
2319                    uid = mMemWatchDumpUid;
2320                    Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2321                    if (val == null) {
2322                        val = mMemWatchProcesses.get(procName, 0);
2323                    }
2324                    if (val != null) {
2325                        memLimit = val.first;
2326                        reportPackage = val.second;
2327                    } else {
2328                        memLimit = 0;
2329                        reportPackage = null;
2330                    }
2331                }
2332                if (procName == null) {
2333                    return;
2334                }
2335
2336                if (DEBUG_PSS) Slog.d(TAG_PSS,
2337                        "Showing dump heap notification from " + procName + "/" + uid);
2338
2339                INotificationManager inm = NotificationManager.getService();
2340                if (inm == null) {
2341                    return;
2342                }
2343
2344                String text = mContext.getString(R.string.dump_heap_notification, procName);
2345
2346
2347                Intent deleteIntent = new Intent();
2348                deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2349                Intent intent = new Intent();
2350                intent.setClassName("android", DumpHeapActivity.class.getName());
2351                intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2352                intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2353                if (reportPackage != null) {
2354                    intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2355                }
2356                int userId = UserHandle.getUserId(uid);
2357                Notification notification =
2358                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2359                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2360                        .setWhen(0)
2361                        .setOngoing(true)
2362                        .setAutoCancel(true)
2363                        .setTicker(text)
2364                        .setColor(mContext.getColor(
2365                                com.android.internal.R.color.system_notification_accent_color))
2366                        .setContentTitle(text)
2367                        .setContentText(
2368                                mContext.getText(R.string.dump_heap_notification_detail))
2369                        .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2370                                intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2371                                new UserHandle(userId)))
2372                        .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2373                                deleteIntent, 0, UserHandle.SYSTEM))
2374                        .build();
2375
2376                try {
2377                    int[] outId = new int[1];
2378                    inm.enqueueNotificationWithTag("android", "android", null,
2379                            R.string.dump_heap_notification,
2380                            notification, outId, userId);
2381                } catch (RuntimeException e) {
2382                    Slog.w(ActivityManagerService.TAG,
2383                            "Error showing notification for dump heap", e);
2384                } catch (RemoteException e) {
2385                }
2386            } break;
2387            case DELETE_DUMPHEAP_MSG: {
2388                revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2389                        DumpHeapActivity.JAVA_URI,
2390                        Intent.FLAG_GRANT_READ_URI_PERMISSION
2391                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2392                        UserHandle.myUserId());
2393                synchronized (ActivityManagerService.this) {
2394                    mMemWatchDumpFile = null;
2395                    mMemWatchDumpProcName = null;
2396                    mMemWatchDumpPid = -1;
2397                    mMemWatchDumpUid = -1;
2398                }
2399            } break;
2400            case FOREGROUND_PROFILE_CHANGED_MSG: {
2401                mUserController.dispatchForegroundProfileChanged(msg.arg1);
2402            } break;
2403            case REPORT_TIME_TRACKER_MSG: {
2404                AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2405                tracker.deliverResult(mContext);
2406            } break;
2407            case REPORT_USER_SWITCH_COMPLETE_MSG: {
2408                mUserController.dispatchUserSwitchComplete(msg.arg1);
2409            } break;
2410            case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2411                mUserController.dispatchLockedBootComplete(msg.arg1);
2412            } break;
2413            case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2414                IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2415                try {
2416                    connection.shutdown();
2417                } catch (RemoteException e) {
2418                    Slog.w(TAG, "Error shutting down UiAutomationConnection");
2419                }
2420                // Only a UiAutomation can set this flag and now that
2421                // it is finished we make sure it is reset to its default.
2422                mUserIsMonkey = false;
2423            } break;
2424            case IDLE_UIDS_MSG: {
2425                idleUids();
2426            } break;
2427            case VR_MODE_CHANGE_MSG: {
2428                VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2429                if (vrService == null) {
2430                    break;
2431                }
2432                final ActivityRecord r = (ActivityRecord) msg.obj;
2433                boolean vrMode;
2434                boolean inVrMode;
2435                ComponentName requestedPackage;
2436                ComponentName callingPackage;
2437                int userId;
2438                synchronized (ActivityManagerService.this) {
2439                    vrMode = r.requestedVrComponent != null;
2440                    inVrMode = mVrState != NON_VR_MODE;
2441                    requestedPackage = r.requestedVrComponent;
2442                    userId = r.userId;
2443                    callingPackage = r.info.getComponentName();
2444                    if (vrMode != inVrMode) {
2445                        // Don't change state if we're in persistent VR mode, but do update thread
2446                        // priorities if necessary.
2447                        if (mVrState != PERSISTENT_VR_MODE) {
2448                            mVrState = vrMode ? VR_MODE : NON_VR_MODE;
2449                        }
2450                        mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), vrMode);
2451                        if (r.app != null) {
2452                            ProcessRecord proc = r.app;
2453                            if (proc.vrThreadTid > 0) {
2454                                if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2455                                    try {
2456                                        if (mVrState == VR_MODE) {
2457                                            Process.setThreadScheduler(proc.vrThreadTid,
2458                                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2459                                            mTopAppVrThreadTid = proc.vrThreadTid;
2460                                        } else {
2461                                            Process.setThreadScheduler(proc.vrThreadTid,
2462                                                Process.SCHED_OTHER, 0);
2463                                            mTopAppVrThreadTid = 0;
2464                                        }
2465                                    } catch (IllegalArgumentException e) {
2466                                        Slog.w(TAG, "Failed to set scheduling policy, thread does"
2467                                                + " not exist:\n" + e);
2468                                    }
2469                                }
2470                            }
2471                        }
2472                    }
2473                }
2474                vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2475            } break;
2476            case NOTIFY_VR_SLEEPING_MSG: {
2477                notifyVrManagerOfSleepState(msg.arg1 != 0);
2478            } break;
2479            case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2480                synchronized (ActivityManagerService.this) {
2481                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2482                        ProcessRecord r = mLruProcesses.get(i);
2483                        if (r.thread != null) {
2484                            try {
2485                                r.thread.handleTrustStorageUpdate();
2486                            } catch (RemoteException ex) {
2487                                Slog.w(TAG, "Failed to handle trust storage update for: " +
2488                                        r.info.processName);
2489                            }
2490                        }
2491                    }
2492                }
2493            } break;
2494            }
2495        }
2496    };
2497
2498    static final int COLLECT_PSS_BG_MSG = 1;
2499
2500    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2501        @Override
2502        public void handleMessage(Message msg) {
2503            switch (msg.what) {
2504            case COLLECT_PSS_BG_MSG: {
2505                long start = SystemClock.uptimeMillis();
2506                MemInfoReader memInfo = null;
2507                synchronized (ActivityManagerService.this) {
2508                    if (mFullPssPending) {
2509                        mFullPssPending = false;
2510                        memInfo = new MemInfoReader();
2511                    }
2512                }
2513                if (memInfo != null) {
2514                    updateCpuStatsNow();
2515                    long nativeTotalPss = 0;
2516                    final List<ProcessCpuTracker.Stats> stats;
2517                    synchronized (mProcessCpuTracker) {
2518                        stats = mProcessCpuTracker.getStats( (st)-> {
2519                            return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2520                        });
2521                    }
2522                    final int N = stats.size();
2523                    for (int j = 0; j < N; j++) {
2524                        synchronized (mPidsSelfLocked) {
2525                            if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2526                                // This is one of our own processes; skip it.
2527                                continue;
2528                            }
2529                        }
2530                        nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2531                    }
2532                    memInfo.readMemInfo();
2533                    synchronized (ActivityManagerService.this) {
2534                        if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2535                                + (SystemClock.uptimeMillis()-start) + "ms");
2536                        final long cachedKb = memInfo.getCachedSizeKb();
2537                        final long freeKb = memInfo.getFreeSizeKb();
2538                        final long zramKb = memInfo.getZramTotalSizeKb();
2539                        final long kernelKb = memInfo.getKernelUsedSizeKb();
2540                        EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2541                                kernelKb*1024, nativeTotalPss*1024);
2542                        mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2543                                nativeTotalPss);
2544                    }
2545                }
2546
2547                int num = 0;
2548                long[] tmp = new long[2];
2549                do {
2550                    ProcessRecord proc;
2551                    int procState;
2552                    int pid;
2553                    long lastPssTime;
2554                    synchronized (ActivityManagerService.this) {
2555                        if (mPendingPssProcesses.size() <= 0) {
2556                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2557                                    "Collected PSS of " + num + " processes in "
2558                                    + (SystemClock.uptimeMillis() - start) + "ms");
2559                            mPendingPssProcesses.clear();
2560                            return;
2561                        }
2562                        proc = mPendingPssProcesses.remove(0);
2563                        procState = proc.pssProcState;
2564                        lastPssTime = proc.lastPssTime;
2565                        if (proc.thread != null && procState == proc.setProcState
2566                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2567                                        < SystemClock.uptimeMillis()) {
2568                            pid = proc.pid;
2569                        } else {
2570                            proc = null;
2571                            pid = 0;
2572                        }
2573                    }
2574                    if (proc != null) {
2575                        long pss = Debug.getPss(pid, tmp, null);
2576                        synchronized (ActivityManagerService.this) {
2577                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
2578                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2579                                num++;
2580                                recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2581                                        SystemClock.uptimeMillis());
2582                            }
2583                        }
2584                    }
2585                } while (true);
2586            }
2587            }
2588        }
2589    };
2590
2591    public void setSystemProcess() {
2592        try {
2593            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2594            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2595            ServiceManager.addService("meminfo", new MemBinder(this));
2596            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2597            ServiceManager.addService("dbinfo", new DbBinder(this));
2598            if (MONITOR_CPU_USAGE) {
2599                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2600            }
2601            ServiceManager.addService("permission", new PermissionController(this));
2602            ServiceManager.addService("processinfo", new ProcessInfoService(this));
2603
2604            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2605                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2606            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2607
2608            synchronized (this) {
2609                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2610                app.persistent = true;
2611                app.pid = MY_PID;
2612                app.maxAdj = ProcessList.SYSTEM_ADJ;
2613                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2614                synchronized (mPidsSelfLocked) {
2615                    mPidsSelfLocked.put(app.pid, app);
2616                }
2617                updateLruProcessLocked(app, false, null);
2618                updateOomAdjLocked();
2619            }
2620        } catch (PackageManager.NameNotFoundException e) {
2621            throw new RuntimeException(
2622                    "Unable to find android system package", e);
2623        }
2624    }
2625
2626    public void setWindowManager(WindowManagerService wm) {
2627        mWindowManager = wm;
2628        mStackSupervisor.setWindowManager(wm);
2629        mActivityStarter.setWindowManager(wm);
2630    }
2631
2632    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2633        mUsageStatsService = usageStatsManager;
2634    }
2635
2636    public void startObservingNativeCrashes() {
2637        final NativeCrashListener ncl = new NativeCrashListener(this);
2638        ncl.start();
2639    }
2640
2641    public IAppOpsService getAppOpsService() {
2642        return mAppOpsService;
2643    }
2644
2645    static class MemBinder extends Binder {
2646        ActivityManagerService mActivityManagerService;
2647        MemBinder(ActivityManagerService activityManagerService) {
2648            mActivityManagerService = activityManagerService;
2649        }
2650
2651        @Override
2652        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2653            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2654                    != PackageManager.PERMISSION_GRANTED) {
2655                pw.println("Permission Denial: can't dump meminfo from from pid="
2656                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2657                        + " without permission " + android.Manifest.permission.DUMP);
2658                return;
2659            }
2660
2661            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2662        }
2663    }
2664
2665    static class GraphicsBinder extends Binder {
2666        ActivityManagerService mActivityManagerService;
2667        GraphicsBinder(ActivityManagerService activityManagerService) {
2668            mActivityManagerService = activityManagerService;
2669        }
2670
2671        @Override
2672        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2673            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2674                    != PackageManager.PERMISSION_GRANTED) {
2675                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2676                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2677                        + " without permission " + android.Manifest.permission.DUMP);
2678                return;
2679            }
2680
2681            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2682        }
2683    }
2684
2685    static class DbBinder extends Binder {
2686        ActivityManagerService mActivityManagerService;
2687        DbBinder(ActivityManagerService activityManagerService) {
2688            mActivityManagerService = activityManagerService;
2689        }
2690
2691        @Override
2692        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2693            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2694                    != PackageManager.PERMISSION_GRANTED) {
2695                pw.println("Permission Denial: can't dump dbinfo from from pid="
2696                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2697                        + " without permission " + android.Manifest.permission.DUMP);
2698                return;
2699            }
2700
2701            mActivityManagerService.dumpDbInfo(fd, pw, args);
2702        }
2703    }
2704
2705    static class CpuBinder extends Binder {
2706        ActivityManagerService mActivityManagerService;
2707        CpuBinder(ActivityManagerService activityManagerService) {
2708            mActivityManagerService = activityManagerService;
2709        }
2710
2711        @Override
2712        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2713            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2714                    != PackageManager.PERMISSION_GRANTED) {
2715                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2716                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2717                        + " without permission " + android.Manifest.permission.DUMP);
2718                return;
2719            }
2720
2721            synchronized (mActivityManagerService.mProcessCpuTracker) {
2722                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2723                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2724                        SystemClock.uptimeMillis()));
2725            }
2726        }
2727    }
2728
2729    public static final class Lifecycle extends SystemService {
2730        private final ActivityManagerService mService;
2731
2732        public Lifecycle(Context context) {
2733            super(context);
2734            mService = new ActivityManagerService(context);
2735        }
2736
2737        @Override
2738        public void onStart() {
2739            mService.start();
2740        }
2741
2742        public ActivityManagerService getService() {
2743            return mService;
2744        }
2745    }
2746
2747    @VisibleForTesting
2748    public ActivityManagerService(Injector injector) {
2749        mInjector = injector;
2750        mContext = mInjector.getContext();
2751        GL_ES_VERSION = 0;
2752        mActivityStarter = null;
2753        mAppErrors = null;
2754        mAppOpsService = mInjector.getAppOpsService(null, null);
2755        mBatteryStatsService = null;
2756        mCompatModePackages = null;
2757        mConstants = null;
2758        mGrantFile = null;
2759        mHandler = null;
2760        mHandlerThread = null;
2761        mIntentFirewall = null;
2762        mKeyguardController = null;
2763        mPermissionReviewRequired = false;
2764        mProcessCpuThread = null;
2765        mProcessStats = null;
2766        mProviderMap = null;
2767        mRecentTasks = null;
2768        mServices = null;
2769        mStackSupervisor = null;
2770        mSystemThread = null;
2771        mTaskChangeNotificationController = null;
2772        mUiHandler = injector.getUiHandler(null);
2773        mUserController = null;
2774    }
2775
2776    // Note: This method is invoked on the main thread but may need to attach various
2777    // handlers to other threads.  So take care to be explicit about the looper.
2778    public ActivityManagerService(Context systemContext) {
2779        LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2780        mInjector = new Injector();
2781        mContext = systemContext;
2782        mFactoryTest = FactoryTest.getMode();
2783        mSystemThread = ActivityThread.currentActivityThread();
2784
2785        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2786
2787        mPermissionReviewRequired = mContext.getResources().getBoolean(
2788                com.android.internal.R.bool.config_permissionReviewRequired);
2789
2790        mHandlerThread = new ServiceThread(TAG,
2791                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2792        mHandlerThread.start();
2793        mHandler = new MainHandler(mHandlerThread.getLooper());
2794        mUiHandler = mInjector.getUiHandler(this);
2795
2796        mConstants = new ActivityManagerConstants(this, mHandler);
2797
2798        if (DEBUG_BACKGROUND_CHECK) {
2799            Slog.d(TAG, "Enforcing O+ bg restrictions: " + mConstants.ENFORCE_BG_CHECK);
2800            StringBuilder sb = new StringBuilder(200);
2801            sb.append("  ");
2802            for (String a : getBackgroundLaunchBroadcasts()) {
2803                sb.append(' '); sb.append(a);
2804            }
2805            Slog.d(TAG, "Background implicit broadcasts:");
2806            Slog.d(TAG, sb.toString());
2807        }
2808
2809        /* static; one-time init here */
2810        if (sKillHandler == null) {
2811            sKillThread = new ServiceThread(TAG + ":kill",
2812                    android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2813            sKillThread.start();
2814            sKillHandler = new KillHandler(sKillThread.getLooper());
2815        }
2816
2817        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2818                "foreground", BROADCAST_FG_TIMEOUT, false);
2819        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2820                "background", BROADCAST_BG_TIMEOUT, true);
2821        mBroadcastQueues[0] = mFgBroadcastQueue;
2822        mBroadcastQueues[1] = mBgBroadcastQueue;
2823
2824        mServices = new ActiveServices(this);
2825        mProviderMap = new ProviderMap(this);
2826        mAppErrors = new AppErrors(mContext, this);
2827
2828        // TODO: Move creation of battery stats service outside of activity manager service.
2829        File dataDir = Environment.getDataDirectory();
2830        File systemDir = new File(dataDir, "system");
2831        systemDir.mkdirs();
2832        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2833        mBatteryStatsService.getActiveStatistics().readLocked();
2834        mBatteryStatsService.scheduleWriteToDisk();
2835        mOnBattery = DEBUG_POWER ? true
2836                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2837        mBatteryStatsService.getActiveStatistics().setCallback(this);
2838
2839        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2840
2841        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2842        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2843                new IAppOpsCallback.Stub() {
2844                    @Override public void opChanged(int op, int uid, String packageName) {
2845                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2846                            if (mAppOpsService.checkOperation(op, uid, packageName)
2847                                    != AppOpsManager.MODE_ALLOWED) {
2848                                runInBackgroundDisabled(uid);
2849                            }
2850                        }
2851                    }
2852                });
2853
2854        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2855
2856        mUserController = new UserController(this);
2857
2858        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2859            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2860
2861        if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2862            mUseFifoUiScheduling = true;
2863        }
2864
2865        mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2866        mTempConfig.setToDefaults();
2867        mTempConfig.setLocales(LocaleList.getDefault());
2868        mConfigurationSeq = mTempConfig.seq = 1;
2869        mStackSupervisor = new ActivityStackSupervisor(this);
2870        mStackSupervisor.onConfigurationChanged(mTempConfig);
2871        mKeyguardController = mStackSupervisor.mKeyguardController;
2872        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2873        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2874        mTaskChangeNotificationController =
2875                new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2876        mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2877        mRecentTasks = new RecentTasks(this, mStackSupervisor);
2878
2879        mProcessCpuThread = new Thread("CpuTracker") {
2880            @Override
2881            public void run() {
2882                synchronized (mProcessCpuTracker) {
2883                    mProcessCpuInitLatch.countDown();
2884                    mProcessCpuTracker.init();
2885                }
2886                while (true) {
2887                    try {
2888                        try {
2889                            synchronized(this) {
2890                                final long now = SystemClock.uptimeMillis();
2891                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2892                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2893                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2894                                //        + ", write delay=" + nextWriteDelay);
2895                                if (nextWriteDelay < nextCpuDelay) {
2896                                    nextCpuDelay = nextWriteDelay;
2897                                }
2898                                if (nextCpuDelay > 0) {
2899                                    mProcessCpuMutexFree.set(true);
2900                                    this.wait(nextCpuDelay);
2901                                }
2902                            }
2903                        } catch (InterruptedException e) {
2904                        }
2905                        updateCpuStatsNow();
2906                    } catch (Exception e) {
2907                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2908                    }
2909                }
2910            }
2911        };
2912
2913        Watchdog.getInstance().addMonitor(this);
2914        Watchdog.getInstance().addThread(mHandler);
2915    }
2916
2917    public void setSystemServiceManager(SystemServiceManager mgr) {
2918        mSystemServiceManager = mgr;
2919    }
2920
2921    public void setInstaller(Installer installer) {
2922        mInstaller = installer;
2923    }
2924
2925    private void start() {
2926        Process.removeAllProcessGroups();
2927        mProcessCpuThread.start();
2928
2929        mBatteryStatsService.publish(mContext);
2930        mAppOpsService.publish(mContext);
2931        Slog.d("AppOps", "AppOpsService published");
2932        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2933        // Wait for the synchronized block started in mProcessCpuThread,
2934        // so that any other acccess to mProcessCpuTracker from main thread
2935        // will be blocked during mProcessCpuTracker initialization.
2936        try {
2937            mProcessCpuInitLatch.await();
2938        } catch (InterruptedException e) {
2939            Slog.wtf(TAG, "Interrupted wait during start", e);
2940            Thread.currentThread().interrupt();
2941            throw new IllegalStateException("Interrupted wait during start");
2942        }
2943    }
2944
2945    void onUserStoppedLocked(int userId) {
2946        mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2947    }
2948
2949    public void initPowerManagement() {
2950        mStackSupervisor.initPowerManagement();
2951        mBatteryStatsService.initPowerManagement();
2952        mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2953        PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2954        mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2955        mVoiceWakeLock.setReferenceCounted(false);
2956    }
2957
2958    private ArraySet<String> getBackgroundLaunchBroadcasts() {
2959        if (mBackgroundLaunchBroadcasts == null) {
2960            mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2961        }
2962        return mBackgroundLaunchBroadcasts;
2963    }
2964
2965    @Override
2966    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2967            throws RemoteException {
2968        if (code == SYSPROPS_TRANSACTION) {
2969            // We need to tell all apps about the system property change.
2970            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2971            synchronized(this) {
2972                final int NP = mProcessNames.getMap().size();
2973                for (int ip=0; ip<NP; ip++) {
2974                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2975                    final int NA = apps.size();
2976                    for (int ia=0; ia<NA; ia++) {
2977                        ProcessRecord app = apps.valueAt(ia);
2978                        if (app.thread != null) {
2979                            procs.add(app.thread.asBinder());
2980                        }
2981                    }
2982                }
2983            }
2984
2985            int N = procs.size();
2986            for (int i=0; i<N; i++) {
2987                Parcel data2 = Parcel.obtain();
2988                try {
2989                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2990                            Binder.FLAG_ONEWAY);
2991                } catch (RemoteException e) {
2992                }
2993                data2.recycle();
2994            }
2995        }
2996        try {
2997            return super.onTransact(code, data, reply, flags);
2998        } catch (RuntimeException e) {
2999            // The activity manager only throws security exceptions, so let's
3000            // log all others.
3001            if (!(e instanceof SecurityException)) {
3002                Slog.wtf(TAG, "Activity Manager Crash", e);
3003            }
3004            throw e;
3005        }
3006    }
3007
3008    void updateCpuStats() {
3009        final long now = SystemClock.uptimeMillis();
3010        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
3011            return;
3012        }
3013        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
3014            synchronized (mProcessCpuThread) {
3015                mProcessCpuThread.notify();
3016            }
3017        }
3018    }
3019
3020    void updateCpuStatsNow() {
3021        synchronized (mProcessCpuTracker) {
3022            mProcessCpuMutexFree.set(false);
3023            final long now = SystemClock.uptimeMillis();
3024            boolean haveNewCpuStats = false;
3025
3026            if (MONITOR_CPU_USAGE &&
3027                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
3028                mLastCpuTime.set(now);
3029                mProcessCpuTracker.update();
3030                if (mProcessCpuTracker.hasGoodLastStats()) {
3031                    haveNewCpuStats = true;
3032                    //Slog.i(TAG, mProcessCpu.printCurrentState());
3033                    //Slog.i(TAG, "Total CPU usage: "
3034                    //        + mProcessCpu.getTotalCpuPercent() + "%");
3035
3036                    // Slog the cpu usage if the property is set.
3037                    if ("true".equals(SystemProperties.get("events.cpu"))) {
3038                        int user = mProcessCpuTracker.getLastUserTime();
3039                        int system = mProcessCpuTracker.getLastSystemTime();
3040                        int iowait = mProcessCpuTracker.getLastIoWaitTime();
3041                        int irq = mProcessCpuTracker.getLastIrqTime();
3042                        int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
3043                        int idle = mProcessCpuTracker.getLastIdleTime();
3044
3045                        int total = user + system + iowait + irq + softIrq + idle;
3046                        if (total == 0) total = 1;
3047
3048                        EventLog.writeEvent(EventLogTags.CPU,
3049                                ((user+system+iowait+irq+softIrq) * 100) / total,
3050                                (user * 100) / total,
3051                                (system * 100) / total,
3052                                (iowait * 100) / total,
3053                                (irq * 100) / total,
3054                                (softIrq * 100) / total);
3055                    }
3056                }
3057            }
3058
3059            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3060            synchronized(bstats) {
3061                synchronized(mPidsSelfLocked) {
3062                    if (haveNewCpuStats) {
3063                        if (bstats.startAddingCpuLocked()) {
3064                            int totalUTime = 0;
3065                            int totalSTime = 0;
3066                            final int N = mProcessCpuTracker.countStats();
3067                            for (int i=0; i<N; i++) {
3068                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3069                                if (!st.working) {
3070                                    continue;
3071                                }
3072                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3073                                totalUTime += st.rel_utime;
3074                                totalSTime += st.rel_stime;
3075                                if (pr != null) {
3076                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3077                                    if (ps == null || !ps.isActive()) {
3078                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3079                                                pr.info.uid, pr.processName);
3080                                    }
3081                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3082                                    pr.curCpuTime += st.rel_utime + st.rel_stime;
3083                                } else {
3084                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3085                                    if (ps == null || !ps.isActive()) {
3086                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
3087                                                bstats.mapUid(st.uid), st.name);
3088                                    }
3089                                    ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3090                                }
3091                            }
3092                            final int userTime = mProcessCpuTracker.getLastUserTime();
3093                            final int systemTime = mProcessCpuTracker.getLastSystemTime();
3094                            final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3095                            final int irqTime = mProcessCpuTracker.getLastIrqTime();
3096                            final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3097                            final int idleTime = mProcessCpuTracker.getLastIdleTime();
3098                            bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3099                                    systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3100                        }
3101                    }
3102                }
3103
3104                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3105                    mLastWriteTime = now;
3106                    mBatteryStatsService.scheduleWriteToDisk();
3107                }
3108            }
3109        }
3110    }
3111
3112    @Override
3113    public void batteryNeedsCpuUpdate() {
3114        updateCpuStatsNow();
3115    }
3116
3117    @Override
3118    public void batteryPowerChanged(boolean onBattery) {
3119        // When plugging in, update the CPU stats first before changing
3120        // the plug state.
3121        updateCpuStatsNow();
3122        synchronized (this) {
3123            synchronized(mPidsSelfLocked) {
3124                mOnBattery = DEBUG_POWER ? true : onBattery;
3125            }
3126        }
3127    }
3128
3129    @Override
3130    public void batterySendBroadcast(Intent intent) {
3131        synchronized (this) {
3132            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3133                    AppOpsManager.OP_NONE, null, false, false,
3134                    -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
3135        }
3136    }
3137
3138    /**
3139     * Initialize the application bind args. These are passed to each
3140     * process when the bindApplication() IPC is sent to the process. They're
3141     * lazily setup to make sure the services are running when they're asked for.
3142     */
3143    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3144        // Isolated processes won't get this optimization, so that we don't
3145        // violate the rules about which services they have access to.
3146        if (isolated) {
3147            if (mIsolatedAppBindArgs == null) {
3148                mIsolatedAppBindArgs = new HashMap<>();
3149                mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3150            }
3151            return mIsolatedAppBindArgs;
3152        }
3153
3154        if (mAppBindArgs == null) {
3155            mAppBindArgs = new HashMap<>();
3156
3157            // Setup the application init args
3158            mAppBindArgs.put("package", ServiceManager.getService("package"));
3159            mAppBindArgs.put("window", ServiceManager.getService("window"));
3160            mAppBindArgs.put(Context.ALARM_SERVICE,
3161                    ServiceManager.getService(Context.ALARM_SERVICE));
3162        }
3163        return mAppBindArgs;
3164    }
3165
3166    /**
3167     * Update AMS states when an activity is resumed. This should only be called by
3168     * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3169     */
3170    void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3171        if (r.task.isApplicationTask()) {
3172            if (mCurAppTimeTracker != r.appTimeTracker) {
3173                // We are switching app tracking.  Complete the current one.
3174                if (mCurAppTimeTracker != null) {
3175                    mCurAppTimeTracker.stop();
3176                    mHandler.obtainMessage(
3177                            REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3178                    mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3179                    mCurAppTimeTracker = null;
3180                }
3181                if (r.appTimeTracker != null) {
3182                    mCurAppTimeTracker = r.appTimeTracker;
3183                    startTimeTrackingFocusedActivityLocked();
3184                }
3185            } else {
3186                startTimeTrackingFocusedActivityLocked();
3187            }
3188        } else {
3189            r.appTimeTracker = null;
3190        }
3191        // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3192        // TODO: Probably not, because we don't want to resume voice on switching
3193        // back to this activity
3194        if (r.task.voiceInteractor != null) {
3195            startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3196        } else {
3197            finishRunningVoiceLocked();
3198
3199            if (mLastResumedActivity != null) {
3200                final IVoiceInteractionSession session;
3201
3202                if (mLastResumedActivity.task != null
3203                        && mLastResumedActivity.task.voiceSession != null) {
3204                    session = mLastResumedActivity.task.voiceSession;
3205                } else {
3206                    session = mLastResumedActivity.voiceSession;
3207                }
3208
3209                if (session != null) {
3210                    // We had been in a voice interaction session, but now focused has
3211                    // move to something different.  Just finish the session, we can't
3212                    // return to it and retain the proper state and synchronization with
3213                    // the voice interaction service.
3214                    finishVoiceTask(session);
3215                }
3216            }
3217        }
3218
3219        mWindowManager.setFocusedApp(r.appToken, true);
3220
3221        applyUpdateLockStateLocked(r);
3222        applyUpdateVrModeLocked(r);
3223        if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3224            mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3225            mHandler.obtainMessage(
3226                    FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3227        }
3228
3229        mLastResumedActivity = r;
3230
3231        EventLogTags.writeAmSetResumedActivity(
3232                r == null ? -1 : r.userId,
3233                r == null ? "NULL" : r.shortComponentName,
3234                reason);
3235    }
3236
3237    @Override
3238    public void setFocusedStack(int stackId) {
3239        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3240        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3241        final long callingId = Binder.clearCallingIdentity();
3242        try {
3243            synchronized (this) {
3244                final ActivityStack stack = mStackSupervisor.getStack(stackId);
3245                if (stack == null) {
3246                    return;
3247                }
3248                final ActivityRecord r = stack.topRunningActivityLocked();
3249                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3250                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3251                }
3252            }
3253        } finally {
3254            Binder.restoreCallingIdentity(callingId);
3255        }
3256    }
3257
3258    @Override
3259    public void setFocusedTask(int taskId) {
3260        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3261        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3262        final long callingId = Binder.clearCallingIdentity();
3263        try {
3264            synchronized (this) {
3265                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3266                if (task == null) {
3267                    return;
3268                }
3269                final ActivityRecord r = task.topRunningActivityLocked();
3270                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3271                    mStackSupervisor.resumeFocusedStackTopActivityLocked();
3272                }
3273            }
3274        } finally {
3275            Binder.restoreCallingIdentity(callingId);
3276        }
3277    }
3278
3279    /** Sets the task stack listener that gets callbacks when a task stack changes. */
3280    @Override
3281    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3282        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3283        mTaskChangeNotificationController.registerTaskStackListener(listener);
3284    }
3285
3286    /**
3287     * Unregister a task stack listener so that it stops receiving callbacks.
3288     */
3289    @Override
3290    public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3291         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3292         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3293     }
3294
3295    @Override
3296    public void notifyActivityDrawn(IBinder token) {
3297        if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3298        synchronized (this) {
3299            ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3300            if (r != null) {
3301                r.getStack().notifyActivityDrawnLocked(r);
3302            }
3303        }
3304    }
3305
3306    final void applyUpdateLockStateLocked(ActivityRecord r) {
3307        // Modifications to the UpdateLock state are done on our handler, outside
3308        // the activity manager's locks.  The new state is determined based on the
3309        // state *now* of the relevant activity record.  The object is passed to
3310        // the handler solely for logging detail, not to be consulted/modified.
3311        final boolean nextState = r != null && r.immersive;
3312        mHandler.sendMessage(
3313                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3314    }
3315
3316    final void applyUpdateVrModeLocked(ActivityRecord r) {
3317        mHandler.sendMessage(
3318                mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3319    }
3320
3321    private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3322        mHandler.sendMessage(
3323                mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3324    }
3325
3326    private void notifyVrManagerOfSleepState(boolean isSleeping) {
3327        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3328        if (vrService == null) {
3329            return;
3330        }
3331        vrService.onSleepStateChanged(isSleeping);
3332    }
3333
3334    final void showAskCompatModeDialogLocked(ActivityRecord r) {
3335        Message msg = Message.obtain();
3336        msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3337        msg.obj = r.task.askedCompatMode ? null : r;
3338        mUiHandler.sendMessage(msg);
3339    }
3340
3341    final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3342        final Configuration globalConfig = getGlobalConfiguration();
3343        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3344                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3345            final Message msg = Message.obtain();
3346            msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3347            msg.obj = r;
3348            mUiHandler.sendMessage(msg);
3349        }
3350    }
3351
3352    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3353            String what, Object obj, ProcessRecord srcApp) {
3354        app.lastActivityTime = now;
3355
3356        if (app.activities.size() > 0) {
3357            // Don't want to touch dependent processes that are hosting activities.
3358            return index;
3359        }
3360
3361        int lrui = mLruProcesses.lastIndexOf(app);
3362        if (lrui < 0) {
3363            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3364                    + what + " " + obj + " from " + srcApp);
3365            return index;
3366        }
3367
3368        if (lrui >= index) {
3369            // Don't want to cause this to move dependent processes *back* in the
3370            // list as if they were less frequently used.
3371            return index;
3372        }
3373
3374        if (lrui >= mLruProcessActivityStart) {
3375            // Don't want to touch dependent processes that are hosting activities.
3376            return index;
3377        }
3378
3379        mLruProcesses.remove(lrui);
3380        if (index > 0) {
3381            index--;
3382        }
3383        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3384                + " in LRU list: " + app);
3385        mLruProcesses.add(index, app);
3386        return index;
3387    }
3388
3389    static void killProcessGroup(int uid, int pid) {
3390        if (sKillHandler != null) {
3391            sKillHandler.sendMessage(
3392                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3393        } else {
3394            Slog.w(TAG, "Asked to kill process group before system bringup!");
3395            Process.killProcessGroup(uid, pid);
3396        }
3397    }
3398
3399    final void removeLruProcessLocked(ProcessRecord app) {
3400        int lrui = mLruProcesses.lastIndexOf(app);
3401        if (lrui >= 0) {
3402            if (!app.killed) {
3403                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3404                Process.killProcessQuiet(app.pid);
3405                killProcessGroup(app.uid, app.pid);
3406            }
3407            if (lrui <= mLruProcessActivityStart) {
3408                mLruProcessActivityStart--;
3409            }
3410            if (lrui <= mLruProcessServiceStart) {
3411                mLruProcessServiceStart--;
3412            }
3413            mLruProcesses.remove(lrui);
3414        }
3415    }
3416
3417    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3418            ProcessRecord client) {
3419        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3420                || app.treatLikeActivity;
3421        final boolean hasService = false; // not impl yet. app.services.size() > 0;
3422        if (!activityChange && hasActivity) {
3423            // The process has activities, so we are only allowing activity-based adjustments
3424            // to move it.  It should be kept in the front of the list with other
3425            // processes that have activities, and we don't want those to change their
3426            // order except due to activity operations.
3427            return;
3428        }
3429
3430        mLruSeq++;
3431        final long now = SystemClock.uptimeMillis();
3432        app.lastActivityTime = now;
3433
3434        // First a quick reject: if the app is already at the position we will
3435        // put it, then there is nothing to do.
3436        if (hasActivity) {
3437            final int N = mLruProcesses.size();
3438            if (N > 0 && mLruProcesses.get(N-1) == app) {
3439                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3440                return;
3441            }
3442        } else {
3443            if (mLruProcessServiceStart > 0
3444                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3445                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3446                return;
3447            }
3448        }
3449
3450        int lrui = mLruProcesses.lastIndexOf(app);
3451
3452        if (app.persistent && lrui >= 0) {
3453            // We don't care about the position of persistent processes, as long as
3454            // they are in the list.
3455            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3456            return;
3457        }
3458
3459        /* In progress: compute new position first, so we can avoid doing work
3460           if the process is not actually going to move.  Not yet working.
3461        int addIndex;
3462        int nextIndex;
3463        boolean inActivity = false, inService = false;
3464        if (hasActivity) {
3465            // Process has activities, put it at the very tipsy-top.
3466            addIndex = mLruProcesses.size();
3467            nextIndex = mLruProcessServiceStart;
3468            inActivity = true;
3469        } else if (hasService) {
3470            // Process has services, put it at the top of the service list.
3471            addIndex = mLruProcessActivityStart;
3472            nextIndex = mLruProcessServiceStart;
3473            inActivity = true;
3474            inService = true;
3475        } else  {
3476            // Process not otherwise of interest, it goes to the top of the non-service area.
3477            addIndex = mLruProcessServiceStart;
3478            if (client != null) {
3479                int clientIndex = mLruProcesses.lastIndexOf(client);
3480                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3481                        + app);
3482                if (clientIndex >= 0 && addIndex > clientIndex) {
3483                    addIndex = clientIndex;
3484                }
3485            }
3486            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3487        }
3488
3489        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3490                + mLruProcessActivityStart + "): " + app);
3491        */
3492
3493        if (lrui >= 0) {
3494            if (lrui < mLruProcessActivityStart) {
3495                mLruProcessActivityStart--;
3496            }
3497            if (lrui < mLruProcessServiceStart) {
3498                mLruProcessServiceStart--;
3499            }
3500            /*
3501            if (addIndex > lrui) {
3502                addIndex--;
3503            }
3504            if (nextIndex > lrui) {
3505                nextIndex--;
3506            }
3507            */
3508            mLruProcesses.remove(lrui);
3509        }
3510
3511        /*
3512        mLruProcesses.add(addIndex, app);
3513        if (inActivity) {
3514            mLruProcessActivityStart++;
3515        }
3516        if (inService) {
3517            mLruProcessActivityStart++;
3518        }
3519        */
3520
3521        int nextIndex;
3522        if (hasActivity) {
3523            final int N = mLruProcesses.size();
3524            if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3525                // Process doesn't have activities, but has clients with
3526                // activities...  move it up, but one below the top (the top
3527                // should always have a real activity).
3528                if (DEBUG_LRU) Slog.d(TAG_LRU,
3529                        "Adding to second-top of LRU activity list: " + app);
3530                mLruProcesses.add(N - 1, app);
3531                // To keep it from spamming the LRU list (by making a bunch of clients),
3532                // we will push down any other entries owned by the app.
3533                final int uid = app.info.uid;
3534                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3535                    ProcessRecord subProc = mLruProcesses.get(i);
3536                    if (subProc.info.uid == uid) {
3537                        // We want to push this one down the list.  If the process after
3538                        // it is for the same uid, however, don't do so, because we don't
3539                        // want them internally to be re-ordered.
3540                        if (mLruProcesses.get(i - 1).info.uid != uid) {
3541                            if (DEBUG_LRU) Slog.d(TAG_LRU,
3542                                    "Pushing uid " + uid + " swapping at " + i + ": "
3543                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3544                            ProcessRecord tmp = mLruProcesses.get(i);
3545                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
3546                            mLruProcesses.set(i - 1, tmp);
3547                            i--;
3548                        }
3549                    } else {
3550                        // A gap, we can stop here.
3551                        break;
3552                    }
3553                }
3554            } else {
3555                // Process has activities, put it at the very tipsy-top.
3556                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3557                mLruProcesses.add(app);
3558            }
3559            nextIndex = mLruProcessServiceStart;
3560        } else if (hasService) {
3561            // Process has services, put it at the top of the service list.
3562            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3563            mLruProcesses.add(mLruProcessActivityStart, app);
3564            nextIndex = mLruProcessServiceStart;
3565            mLruProcessActivityStart++;
3566        } else  {
3567            // Process not otherwise of interest, it goes to the top of the non-service area.
3568            int index = mLruProcessServiceStart;
3569            if (client != null) {
3570                // If there is a client, don't allow the process to be moved up higher
3571                // in the list than that client.
3572                int clientIndex = mLruProcesses.lastIndexOf(client);
3573                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3574                        + " when updating " + app);
3575                if (clientIndex <= lrui) {
3576                    // Don't allow the client index restriction to push it down farther in the
3577                    // list than it already is.
3578                    clientIndex = lrui;
3579                }
3580                if (clientIndex >= 0 && index > clientIndex) {
3581                    index = clientIndex;
3582                }
3583            }
3584            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3585            mLruProcesses.add(index, app);
3586            nextIndex = index-1;
3587            mLruProcessActivityStart++;
3588            mLruProcessServiceStart++;
3589        }
3590
3591        // If the app is currently using a content provider or service,
3592        // bump those processes as well.
3593        for (int j=app.connections.size()-1; j>=0; j--) {
3594            ConnectionRecord cr = app.connections.valueAt(j);
3595            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3596                    && cr.binding.service.app != null
3597                    && cr.binding.service.app.lruSeq != mLruSeq
3598                    && !cr.binding.service.app.persistent) {
3599                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3600                        "service connection", cr, app);
3601            }
3602        }
3603        for (int j=app.conProviders.size()-1; j>=0; j--) {
3604            ContentProviderRecord cpr = app.conProviders.get(j).provider;
3605            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3606                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3607                        "provider reference", cpr, app);
3608            }
3609        }
3610    }
3611
3612    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3613        if (uid == Process.SYSTEM_UID) {
3614            // The system gets to run in any process.  If there are multiple
3615            // processes with the same uid, just pick the first (this
3616            // should never happen).
3617            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3618            if (procs == null) return null;
3619            final int procCount = procs.size();
3620            for (int i = 0; i < procCount; i++) {
3621                final int procUid = procs.keyAt(i);
3622                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3623                    // Don't use an app process or different user process for system component.
3624                    continue;
3625                }
3626                return procs.valueAt(i);
3627            }
3628        }
3629        ProcessRecord proc = mProcessNames.get(processName, uid);
3630        if (false && proc != null && !keepIfLarge
3631                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3632                && proc.lastCachedPss >= 4000) {
3633            // Turn this condition on to cause killing to happen regularly, for testing.
3634            if (proc.baseProcessTracker != null) {
3635                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3636            }
3637            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3638        } else if (proc != null && !keepIfLarge
3639                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3640                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3641            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3642            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3643                if (proc.baseProcessTracker != null) {
3644                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3645                }
3646                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3647            }
3648        }
3649        return proc;
3650    }
3651
3652    void notifyPackageUse(String packageName, int reason) {
3653        IPackageManager pm = AppGlobals.getPackageManager();
3654        try {
3655            pm.notifyPackageUse(packageName, reason);
3656        } catch (RemoteException e) {
3657        }
3658    }
3659
3660    boolean isNextTransitionForward() {
3661        int transit = mWindowManager.getPendingAppTransition();
3662        return transit == TRANSIT_ACTIVITY_OPEN
3663                || transit == TRANSIT_TASK_OPEN
3664                || transit == TRANSIT_TASK_TO_FRONT;
3665    }
3666
3667    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3668            String processName, String abiOverride, int uid, Runnable crashHandler) {
3669        synchronized(this) {
3670            ApplicationInfo info = new ApplicationInfo();
3671            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3672            // For isolated processes, the former contains the parent's uid and the latter the
3673            // actual uid of the isolated process.
3674            // In the special case introduced by this method (which is, starting an isolated
3675            // process directly from the SystemServer without an actual parent app process) the
3676            // closest thing to a parent's uid is SYSTEM_UID.
3677            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3678            // the |isolated| logic in the ProcessRecord constructor.
3679            info.uid = Process.SYSTEM_UID;
3680            info.processName = processName;
3681            info.className = entryPoint;
3682            info.packageName = "android";
3683            info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3684            ProcessRecord proc = startProcessLocked(processName, info /* info */,
3685                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3686                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3687                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3688                    crashHandler);
3689            return proc != null ? proc.pid : 0;
3690        }
3691    }
3692
3693    final ProcessRecord startProcessLocked(String processName,
3694            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3695            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3696            boolean isolated, boolean keepIfLarge) {
3697        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3698                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3699                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3700                null /* crashHandler */);
3701    }
3702
3703    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3704            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3705            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3706            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3707        long startTime = SystemClock.elapsedRealtime();
3708        ProcessRecord app;
3709        if (!isolated) {
3710            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3711            checkTime(startTime, "startProcess: after getProcessRecord");
3712
3713            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3714                // If we are in the background, then check to see if this process
3715                // is bad.  If so, we will just silently fail.
3716                if (mAppErrors.isBadProcessLocked(info)) {
3717                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3718                            + "/" + info.processName);
3719                    return null;
3720                }
3721            } else {
3722                // When the user is explicitly starting a process, then clear its
3723                // crash count so that we won't make it bad until they see at
3724                // least one crash dialog again, and make the process good again
3725                // if it had been bad.
3726                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3727                        + "/" + info.processName);
3728                mAppErrors.resetProcessCrashTimeLocked(info);
3729                if (mAppErrors.isBadProcessLocked(info)) {
3730                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3731                            UserHandle.getUserId(info.uid), info.uid,
3732                            info.processName);
3733                    mAppErrors.clearBadProcessLocked(info);
3734                    if (app != null) {
3735                        app.bad = false;
3736                    }
3737                }
3738            }
3739        } else {
3740            // If this is an isolated process, it can't re-use an existing process.
3741            app = null;
3742        }
3743
3744        // We don't have to do anything more if:
3745        // (1) There is an existing application record; and
3746        // (2) The caller doesn't think it is dead, OR there is no thread
3747        //     object attached to it so we know it couldn't have crashed; and
3748        // (3) There is a pid assigned to it, so it is either starting or
3749        //     already running.
3750        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3751                + " app=" + app + " knownToBeDead=" + knownToBeDead
3752                + " thread=" + (app != null ? app.thread : null)
3753                + " pid=" + (app != null ? app.pid : -1));
3754        if (app != null && app.pid > 0) {
3755            if ((!knownToBeDead && !app.killed) || app.thread == null) {
3756                // We already have the app running, or are waiting for it to
3757                // come up (we have a pid but not yet its thread), so keep it.
3758                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3759                // If this is a new package in the process, add the package to the list
3760                app.addPackage(info.packageName, info.versionCode, mProcessStats);
3761                checkTime(startTime, "startProcess: done, added package to proc");
3762                return app;
3763            }
3764
3765            // An application record is attached to a previous process,
3766            // clean it up now.
3767            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3768            checkTime(startTime, "startProcess: bad proc running, killing");
3769            killProcessGroup(app.uid, app.pid);
3770            handleAppDiedLocked(app, true, true);
3771            checkTime(startTime, "startProcess: done killing old proc");
3772        }
3773
3774        String hostingNameStr = hostingName != null
3775                ? hostingName.flattenToShortString() : null;
3776
3777        if (app == null) {
3778            checkTime(startTime, "startProcess: creating new process record");
3779            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3780            if (app == null) {
3781                Slog.w(TAG, "Failed making new process record for "
3782                        + processName + "/" + info.uid + " isolated=" + isolated);
3783                return null;
3784            }
3785            app.crashHandler = crashHandler;
3786            checkTime(startTime, "startProcess: done creating new process record");
3787        } else {
3788            // If this is a new package in the process, add the package to the list
3789            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3790            checkTime(startTime, "startProcess: added package to existing proc");
3791        }
3792
3793        // If the system is not ready yet, then hold off on starting this
3794        // process until it is.
3795        if (!mProcessesReady
3796                && !isAllowedWhileBooting(info)
3797                && !allowWhileBooting) {
3798            if (!mProcessesOnHold.contains(app)) {
3799                mProcessesOnHold.add(app);
3800            }
3801            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3802                    "System not ready, putting on hold: " + app);
3803            checkTime(startTime, "startProcess: returning with proc on hold");
3804            return app;
3805        }
3806
3807        checkTime(startTime, "startProcess: stepping in to startProcess");
3808        startProcessLocked(
3809                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3810        checkTime(startTime, "startProcess: done starting proc!");
3811        return (app.pid != 0) ? app : null;
3812    }
3813
3814    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3815        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3816    }
3817
3818    private final void startProcessLocked(ProcessRecord app,
3819            String hostingType, String hostingNameStr) {
3820        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3821                null /* entryPoint */, null /* entryPointArgs */);
3822    }
3823
3824    private final void startProcessLocked(ProcessRecord app, String hostingType,
3825            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3826        long startTime = SystemClock.elapsedRealtime();
3827        if (app.pid > 0 && app.pid != MY_PID) {
3828            checkTime(startTime, "startProcess: removing from pids map");
3829            synchronized (mPidsSelfLocked) {
3830                mPidsSelfLocked.remove(app.pid);
3831                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3832            }
3833            checkTime(startTime, "startProcess: done removing from pids map");
3834            app.setPid(0);
3835        }
3836
3837        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3838                "startProcessLocked removing on hold: " + app);
3839        mProcessesOnHold.remove(app);
3840
3841        checkTime(startTime, "startProcess: starting to update cpu stats");
3842        updateCpuStats();
3843        checkTime(startTime, "startProcess: done updating cpu stats");
3844
3845        try {
3846            try {
3847                final int userId = UserHandle.getUserId(app.uid);
3848                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3849            } catch (RemoteException e) {
3850                throw e.rethrowAsRuntimeException();
3851            }
3852
3853            int uid = app.uid;
3854            int[] gids = null;
3855            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3856            if (!app.isolated) {
3857                int[] permGids = null;
3858                try {
3859                    checkTime(startTime, "startProcess: getting gids from package manager");
3860                    final IPackageManager pm = AppGlobals.getPackageManager();
3861                    permGids = pm.getPackageGids(app.info.packageName,
3862                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3863                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
3864                            StorageManagerInternal.class);
3865                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3866                            app.info.packageName);
3867                } catch (RemoteException e) {
3868                    throw e.rethrowAsRuntimeException();
3869                }
3870
3871                /*
3872                 * Add shared application and profile GIDs so applications can share some
3873                 * resources like shared libraries and access user-wide resources
3874                 */
3875                if (ArrayUtils.isEmpty(permGids)) {
3876                    gids = new int[3];
3877                } else {
3878                    gids = new int[permGids.length + 3];
3879                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
3880                }
3881                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3882                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3883                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3884            }
3885            checkTime(startTime, "startProcess: building args");
3886            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3887                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3888                        && mTopComponent != null
3889                        && app.processName.equals(mTopComponent.getPackageName())) {
3890                    uid = 0;
3891                }
3892                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3893                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3894                    uid = 0;
3895                }
3896            }
3897            int debugFlags = 0;
3898            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3899                debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3900                debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3901                // Also turn on CheckJNI for debuggable apps. It's quite
3902                // awkward to turn on otherwise.
3903                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3904            }
3905            // Run the app in safe mode if its manifest requests so or the
3906            // system is booted in safe mode.
3907            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3908                mSafeMode == true) {
3909                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3910            }
3911            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3912                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3913            }
3914            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3915            if ("true".equals(genDebugInfoProperty)) {
3916                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3917            }
3918            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3919                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3920            }
3921            if ("1".equals(SystemProperties.get("debug.assert"))) {
3922                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3923            }
3924            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3925                // Enable all debug flags required by the native debugger.
3926                debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3927                debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3928                debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3929                mNativeDebuggingApp = null;
3930            }
3931
3932            String invokeWith = null;
3933            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3934                // Debuggable apps may include a wrapper script with their library directory.
3935                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3936                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3937                try {
3938                    if (new File(wrapperFileName).exists()) {
3939                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3940                    }
3941                } finally {
3942                    StrictMode.setThreadPolicy(oldPolicy);
3943                }
3944            }
3945
3946            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3947            if (requiredAbi == null) {
3948                requiredAbi = Build.SUPPORTED_ABIS[0];
3949            }
3950
3951            String instructionSet = null;
3952            if (app.info.primaryCpuAbi != null) {
3953                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3954            }
3955
3956            app.gids = gids;
3957            app.requiredAbi = requiredAbi;
3958            app.instructionSet = instructionSet;
3959
3960            // the per-user SELinux context must be set
3961            if (TextUtils.isEmpty(app.info.seInfoUser)) {
3962                Slog.wtf(TAG, "SELinux tag not defined",
3963                        new IllegalStateException("SELinux tag not defined"));
3964            }
3965            final String seInfo = app.info.seInfo
3966                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3967            // Start the process.  It will either succeed and return a result containing
3968            // the PID of the new process, or else throw a RuntimeException.
3969            boolean isActivityProcess = (entryPoint == null);
3970            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3971            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3972                    app.processName);
3973            checkTime(startTime, "startProcess: asking zygote to start proc");
3974            Process.ProcessStartResult startResult;
3975            if (hostingType.equals("webview_service")) {
3976                startResult = Process.startWebView(entryPoint,
3977                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3978                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3979                        app.info.dataDir, null, entryPointArgs);
3980            } else {
3981                startResult = Process.start(entryPoint,
3982                        app.processName, uid, uid, gids, debugFlags, mountExternal,
3983                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3984                        app.info.dataDir, invokeWith, entryPointArgs);
3985            }
3986            checkTime(startTime, "startProcess: returned from zygote!");
3987            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3988
3989            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3990            checkTime(startTime, "startProcess: done updating battery stats");
3991
3992            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3993                    UserHandle.getUserId(uid), startResult.pid, uid,
3994                    app.processName, hostingType,
3995                    hostingNameStr != null ? hostingNameStr : "");
3996
3997            try {
3998                AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3999                        seInfo, app.info.sourceDir, startResult.pid);
4000            } catch (RemoteException ex) {
4001                // Ignore
4002            }
4003
4004            if (app.persistent) {
4005                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
4006            }
4007
4008            checkTime(startTime, "startProcess: building log message");
4009            StringBuilder buf = mStringBuilder;
4010            buf.setLength(0);
4011            buf.append("Start proc ");
4012            buf.append(startResult.pid);
4013            buf.append(':');
4014            buf.append(app.processName);
4015            buf.append('/');
4016            UserHandle.formatUid(buf, uid);
4017            if (!isActivityProcess) {
4018                buf.append(" [");
4019                buf.append(entryPoint);
4020                buf.append("]");
4021            }
4022            buf.append(" for ");
4023            buf.append(hostingType);
4024            if (hostingNameStr != null) {
4025                buf.append(" ");
4026                buf.append(hostingNameStr);
4027            }
4028            Slog.i(TAG, buf.toString());
4029            app.setPid(startResult.pid);
4030            app.usingWrapper = startResult.usingWrapper;
4031            app.removed = false;
4032            app.killed = false;
4033            app.killedByAm = false;
4034            checkTime(startTime, "startProcess: starting to update pids map");
4035            ProcessRecord oldApp;
4036            synchronized (mPidsSelfLocked) {
4037                oldApp = mPidsSelfLocked.get(startResult.pid);
4038            }
4039            // If there is already an app occupying that pid that hasn't been cleaned up
4040            if (oldApp != null && !app.isolated) {
4041                // Clean up anything relating to this pid first
4042                Slog.w(TAG, "Reusing pid " + startResult.pid
4043                        + " while app is still mapped to it");
4044                cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4045                        true /*replacingPid*/);
4046            }
4047            synchronized (mPidsSelfLocked) {
4048                this.mPidsSelfLocked.put(startResult.pid, app);
4049                if (isActivityProcess) {
4050                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4051                    msg.obj = app;
4052                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4053                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4054                }
4055            }
4056            checkTime(startTime, "startProcess: done updating pids map");
4057        } catch (RuntimeException e) {
4058            Slog.e(TAG, "Failure starting process " + app.processName, e);
4059
4060            // Something went very wrong while trying to start this process; one
4061            // common case is when the package is frozen due to an active
4062            // upgrade. To recover, clean up any active bookkeeping related to
4063            // starting this process. (We already invoked this method once when
4064            // the package was initially frozen through KILL_APPLICATION_MSG, so
4065            // it doesn't hurt to use it again.)
4066            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4067                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4068        }
4069    }
4070
4071    void updateUsageStats(ActivityRecord component, boolean resumed) {
4072        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4073                "updateUsageStats: comp=" + component + "res=" + resumed);
4074        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4075        if (resumed) {
4076            if (mUsageStatsService != null) {
4077                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4078                        UsageEvents.Event.MOVE_TO_FOREGROUND);
4079            }
4080            synchronized (stats) {
4081                stats.noteActivityResumedLocked(component.app.uid);
4082            }
4083        } else {
4084            if (mUsageStatsService != null) {
4085                mUsageStatsService.reportEvent(component.realActivity, component.userId,
4086                        UsageEvents.Event.MOVE_TO_BACKGROUND);
4087            }
4088            synchronized (stats) {
4089                stats.noteActivityPausedLocked(component.app.uid);
4090            }
4091        }
4092    }
4093
4094    Intent getHomeIntent() {
4095        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4096        intent.setComponent(mTopComponent);
4097        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4098        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4099            intent.addCategory(Intent.CATEGORY_HOME);
4100        }
4101        return intent;
4102    }
4103
4104    boolean startHomeActivityLocked(int userId, String reason) {
4105        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4106                && mTopAction == null) {
4107            // We are running in factory test mode, but unable to find
4108            // the factory test app, so just sit around displaying the
4109            // error message and don't try to start anything.
4110            return false;
4111        }
4112        Intent intent = getHomeIntent();
4113        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4114        if (aInfo != null) {
4115            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4116            // Don't do this if the home app is currently being
4117            // instrumented.
4118            aInfo = new ActivityInfo(aInfo);
4119            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4120            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4121                    aInfo.applicationInfo.uid, true);
4122            if (app == null || app.instr == null) {
4123                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4124                mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
4125            }
4126        } else {
4127            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4128        }
4129
4130        return true;
4131    }
4132
4133    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4134        ActivityInfo ai = null;
4135        ComponentName comp = intent.getComponent();
4136        try {
4137            if (comp != null) {
4138                // Factory test.
4139                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4140            } else {
4141                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4142                        intent,
4143                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4144                        flags, userId);
4145
4146                if (info != null) {
4147                    ai = info.activityInfo;
4148                }
4149            }
4150        } catch (RemoteException e) {
4151            // ignore
4152        }
4153
4154        return ai;
4155    }
4156
4157    /**
4158     * Starts the "new version setup screen" if appropriate.
4159     */
4160    void startSetupActivityLocked() {
4161        // Only do this once per boot.
4162        if (mCheckedForSetup) {
4163            return;
4164        }
4165
4166        // We will show this screen if the current one is a different
4167        // version than the last one shown, and we are not running in
4168        // low-level factory test mode.
4169        final ContentResolver resolver = mContext.getContentResolver();
4170        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4171                Settings.Global.getInt(resolver,
4172                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4173            mCheckedForSetup = true;
4174
4175            // See if we should be showing the platform update setup UI.
4176            final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4177            final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4178                    PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4179            if (!ris.isEmpty()) {
4180                final ResolveInfo ri = ris.get(0);
4181                String vers = ri.activityInfo.metaData != null
4182                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4183                        : null;
4184                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4185                    vers = ri.activityInfo.applicationInfo.metaData.getString(
4186                            Intent.METADATA_SETUP_VERSION);
4187                }
4188                String lastVers = Settings.Secure.getString(
4189                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
4190                if (vers != null && !vers.equals(lastVers)) {
4191                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4192                    intent.setComponent(new ComponentName(
4193                            ri.activityInfo.packageName, ri.activityInfo.name));
4194                    mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4195                            null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4196                            null, 0, 0, 0, null, false, false, null, null, null);
4197                }
4198            }
4199        }
4200    }
4201
4202    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4203        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4204    }
4205
4206    void enforceNotIsolatedCaller(String caller) {
4207        if (UserHandle.isIsolated(Binder.getCallingUid())) {
4208            throw new SecurityException("Isolated process not allowed to call " + caller);
4209        }
4210    }
4211
4212    void enforceShellRestriction(String restriction, int userHandle) {
4213        if (Binder.getCallingUid() == Process.SHELL_UID) {
4214            if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4215                throw new SecurityException("Shell does not have permission to access user "
4216                        + userHandle);
4217            }
4218        }
4219    }
4220
4221    @Override
4222    public int getFrontActivityScreenCompatMode() {
4223        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4224        synchronized (this) {
4225            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4226        }
4227    }
4228
4229    @Override
4230    public void setFrontActivityScreenCompatMode(int mode) {
4231        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4232                "setFrontActivityScreenCompatMode");
4233        synchronized (this) {
4234            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4235        }
4236    }
4237
4238    @Override
4239    public int getPackageScreenCompatMode(String packageName) {
4240        enforceNotIsolatedCaller("getPackageScreenCompatMode");
4241        synchronized (this) {
4242            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4243        }
4244    }
4245
4246    @Override
4247    public void setPackageScreenCompatMode(String packageName, int mode) {
4248        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4249                "setPackageScreenCompatMode");
4250        synchronized (this) {
4251            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4252        }
4253    }
4254
4255    @Override
4256    public boolean getPackageAskScreenCompat(String packageName) {
4257        enforceNotIsolatedCaller("getPackageAskScreenCompat");
4258        synchronized (this) {
4259            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4260        }
4261    }
4262
4263    @Override
4264    public void setPackageAskScreenCompat(String packageName, boolean ask) {
4265        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4266                "setPackageAskScreenCompat");
4267        synchronized (this) {
4268            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4269        }
4270    }
4271
4272    private boolean hasUsageStatsPermission(String callingPackage) {
4273        final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4274                Binder.getCallingUid(), callingPackage);
4275        if (mode == AppOpsManager.MODE_DEFAULT) {
4276            return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4277                    == PackageManager.PERMISSION_GRANTED;
4278        }
4279        return mode == AppOpsManager.MODE_ALLOWED;
4280    }
4281
4282    @Override
4283    public int getPackageProcessState(String packageName, String callingPackage) {
4284        if (!hasUsageStatsPermission(callingPackage)) {
4285            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4286                    "getPackageProcessState");
4287        }
4288
4289        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4290        synchronized (this) {
4291            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4292                final ProcessRecord proc = mLruProcesses.get(i);
4293                if (procState > proc.setProcState) {
4294                    if (proc.pkgList.containsKey(packageName) ||
4295                            (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4296                        procState = proc.setProcState;
4297                    }
4298                }
4299            }
4300        }
4301        return procState;
4302    }
4303
4304    @Override
4305    public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4306            throws RemoteException {
4307        synchronized (this) {
4308            final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4309            if (app == null) {
4310                throw new IllegalArgumentException("Unknown process: " + process);
4311            }
4312            if (app.thread == null) {
4313                throw new IllegalArgumentException("Process has no app thread");
4314            }
4315            if (app.trimMemoryLevel >= level) {
4316                throw new IllegalArgumentException(
4317                        "Unable to set a higher trim level than current level");
4318            }
4319            if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4320                    app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4321                throw new IllegalArgumentException("Unable to set a background trim level "
4322                    + "on a foreground process");
4323            }
4324            app.thread.scheduleTrimMemory(level);
4325            app.trimMemoryLevel = level;
4326            return true;
4327        }
4328    }
4329
4330    private void dispatchProcessesChanged() {
4331        int N;
4332        synchronized (this) {
4333            N = mPendingProcessChanges.size();
4334            if (mActiveProcessChanges.length < N) {
4335                mActiveProcessChanges = new ProcessChangeItem[N];
4336            }
4337            mPendingProcessChanges.toArray(mActiveProcessChanges);
4338            mPendingProcessChanges.clear();
4339            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4340                    "*** Delivering " + N + " process changes");
4341        }
4342
4343        int i = mProcessObservers.beginBroadcast();
4344        while (i > 0) {
4345            i--;
4346            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4347            if (observer != null) {
4348                try {
4349                    for (int j=0; j<N; j++) {
4350                        ProcessChangeItem item = mActiveProcessChanges[j];
4351                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4352                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4353                                    "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4354                                    + item.uid + ": " + item.foregroundActivities);
4355                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
4356                                    item.foregroundActivities);
4357                        }
4358                    }
4359                } catch (RemoteException e) {
4360                }
4361            }
4362        }
4363        mProcessObservers.finishBroadcast();
4364
4365        synchronized (this) {
4366            for (int j=0; j<N; j++) {
4367                mAvailProcessChanges.add(mActiveProcessChanges[j]);
4368            }
4369        }
4370    }
4371
4372    private void dispatchProcessDied(int pid, int uid) {
4373        int i = mProcessObservers.beginBroadcast();
4374        while (i > 0) {
4375            i--;
4376            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4377            if (observer != null) {
4378                try {
4379                    observer.onProcessDied(pid, uid);
4380                } catch (RemoteException e) {
4381                }
4382            }
4383        }
4384        mProcessObservers.finishBroadcast();
4385    }
4386
4387    @VisibleForTesting
4388    void dispatchUidsChanged() {
4389        int N;
4390        synchronized (this) {
4391            N = mPendingUidChanges.size();
4392            if (mActiveUidChanges.length < N) {
4393                mActiveUidChanges = new UidRecord.ChangeItem[N];
4394            }
4395            for (int i=0; i<N; i++) {
4396                final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4397                mActiveUidChanges[i] = change;
4398                if (change.uidRecord != null) {
4399                    change.uidRecord.pendingChange = null;
4400                    change.uidRecord = null;
4401                }
4402            }
4403            mPendingUidChanges.clear();
4404            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4405                    "*** Delivering " + N + " uid changes");
4406        }
4407
4408        int i = mUidObservers.beginBroadcast();
4409        while (i > 0) {
4410            i--;
4411            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4412                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4413        }
4414        mUidObservers.finishBroadcast();
4415
4416        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4417            for (int j = 0; j < N; ++j) {
4418                final UidRecord.ChangeItem item = mActiveUidChanges[j];
4419                if (item.change == UidRecord.CHANGE_GONE
4420                        || item.change == UidRecord.CHANGE_GONE_IDLE) {
4421                    mValidateUids.remove(item.uid);
4422                } else {
4423                    UidRecord validateUid = mValidateUids.get(item.uid);
4424                    if (validateUid == null) {
4425                        validateUid = new UidRecord(item.uid);
4426                        mValidateUids.put(item.uid, validateUid);
4427                    }
4428                    if (item.change == UidRecord.CHANGE_IDLE) {
4429                        validateUid.idle = true;
4430                    } else if (item.change == UidRecord.CHANGE_ACTIVE) {
4431                        validateUid.idle = false;
4432                    }
4433                    validateUid.curProcState = validateUid.setProcState = item.processState;
4434                }
4435            }
4436        }
4437
4438        synchronized (this) {
4439            for (int j = 0; j < N; j++) {
4440                mAvailUidChanges.add(mActiveUidChanges[j]);
4441            }
4442        }
4443    }
4444
4445    private void dispatchUidsChangedForObserver(IUidObserver observer,
4446            UidObserverRegistration reg, int changesSize) {
4447        if (observer == null) {
4448            return;
4449        }
4450        try {
4451            for (int j = 0; j < changesSize; j++) {
4452                UidRecord.ChangeItem item = mActiveUidChanges[j];
4453                final int change = item.change;
4454                if (change == UidRecord.CHANGE_IDLE
4455                        || change == UidRecord.CHANGE_GONE_IDLE) {
4456                    if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4457                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4458                                "UID idle uid=" + item.uid);
4459                        observer.onUidIdle(item.uid, item.ephemeral);
4460                    }
4461                } else if (change == UidRecord.CHANGE_ACTIVE) {
4462                    if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4463                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4464                                "UID active uid=" + item.uid);
4465                        observer.onUidActive(item.uid);
4466                    }
4467                }
4468                if (change == UidRecord.CHANGE_GONE
4469                        || change == UidRecord.CHANGE_GONE_IDLE) {
4470                    if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4471                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4472                                "UID gone uid=" + item.uid);
4473                        observer.onUidGone(item.uid, item.ephemeral);
4474                    }
4475                    if (reg.lastProcStates != null) {
4476                        reg.lastProcStates.delete(item.uid);
4477                    }
4478                } else {
4479                    if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4480                        if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4481                                "UID CHANGED uid=" + item.uid
4482                                        + ": " + item.processState);
4483                        boolean doReport = true;
4484                        if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4485                            final int lastState = reg.lastProcStates.get(item.uid,
4486                                    ActivityManager.PROCESS_STATE_UNKNOWN);
4487                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4488                                final boolean lastAboveCut = lastState <= reg.cutpoint;
4489                                final boolean newAboveCut = item.processState <= reg.cutpoint;
4490                                doReport = lastAboveCut != newAboveCut;
4491                            } else {
4492                                doReport = item.processState
4493                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
4494                            }
4495                        }
4496                        if (doReport) {
4497                            if (reg.lastProcStates != null) {
4498                                reg.lastProcStates.put(item.uid, item.processState);
4499                            }
4500                            observer.onUidStateChanged(item.uid, item.processState,
4501                                    item.procStateSeq);
4502                        }
4503                    }
4504                }
4505            }
4506        } catch (RemoteException e) {
4507        }
4508    }
4509
4510    @Override
4511    public final int startActivity(IApplicationThread caller, String callingPackage,
4512            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4513            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4514        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4515                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4516                UserHandle.getCallingUserId());
4517    }
4518
4519    final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4520        enforceNotIsolatedCaller("ActivityContainer.startActivity");
4521        final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4522                Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4523                ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4524
4525        // TODO: Switch to user app stacks here.
4526        String mimeType = intent.getType();
4527        final Uri data = intent.getData();
4528        if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4529            mimeType = getProviderMimeType(data, userId);
4530        }
4531        container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4532
4533        intent.addFlags(FORCE_NEW_TASK_FLAGS);
4534        return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4535                null, 0, 0, null, null, null, null, false, userId, container, null);
4536    }
4537
4538    @Override
4539    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4540            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4541            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4542        enforceNotIsolatedCaller("startActivity");
4543        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4544                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4545        // TODO: Switch to user app stacks here.
4546        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4547                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4548                profilerInfo, null, null, bOptions, false, userId, null, null);
4549    }
4550
4551    @Override
4552    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4553            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4554            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4555            int userId) {
4556
4557        // This is very dangerous -- it allows you to perform a start activity (including
4558        // permission grants) as any app that may launch one of your own activities.  So
4559        // we will only allow this to be done from activities that are part of the core framework,
4560        // and then only when they are running as the system.
4561        final ActivityRecord sourceRecord;
4562        final int targetUid;
4563        final String targetPackage;
4564        synchronized (this) {
4565            if (resultTo == null) {
4566                throw new SecurityException("Must be called from an activity");
4567            }
4568            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4569            if (sourceRecord == null) {
4570                throw new SecurityException("Called with bad activity token: " + resultTo);
4571            }
4572            if (!sourceRecord.info.packageName.equals("android")) {
4573                throw new SecurityException(
4574                        "Must be called from an activity that is declared in the android package");
4575            }
4576            if (sourceRecord.app == null) {
4577                throw new SecurityException("Called without a process attached to activity");
4578            }
4579            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4580                // This is still okay, as long as this activity is running under the
4581                // uid of the original calling activity.
4582                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4583                    throw new SecurityException(
4584                            "Calling activity in uid " + sourceRecord.app.uid
4585                                    + " must be system uid or original calling uid "
4586                                    + sourceRecord.launchedFromUid);
4587                }
4588            }
4589            if (ignoreTargetSecurity) {
4590                if (intent.getComponent() == null) {
4591                    throw new SecurityException(
4592                            "Component must be specified with ignoreTargetSecurity");
4593                }
4594                if (intent.getSelector() != null) {
4595                    throw new SecurityException(
4596                            "Selector not allowed with ignoreTargetSecurity");
4597                }
4598            }
4599            targetUid = sourceRecord.launchedFromUid;
4600            targetPackage = sourceRecord.launchedFromPackage;
4601        }
4602
4603        if (userId == UserHandle.USER_NULL) {
4604            userId = UserHandle.getUserId(sourceRecord.app.uid);
4605        }
4606
4607        // TODO: Switch to user app stacks here.
4608        try {
4609            int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4610                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4611                    null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4612            return ret;
4613        } catch (SecurityException e) {
4614            // XXX need to figure out how to propagate to original app.
4615            // A SecurityException here is generally actually a fault of the original
4616            // calling activity (such as a fairly granting permissions), so propagate it
4617            // back to them.
4618            /*
4619            StringBuilder msg = new StringBuilder();
4620            msg.append("While launching");
4621            msg.append(intent.toString());
4622            msg.append(": ");
4623            msg.append(e.getMessage());
4624            */
4625            throw e;
4626        }
4627    }
4628
4629    @Override
4630    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4631            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4632            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4633        enforceNotIsolatedCaller("startActivityAndWait");
4634        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4635                userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4636        WaitResult res = new WaitResult();
4637        // TODO: Switch to user app stacks here.
4638        mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4639                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4640                bOptions, false, userId, null, null);
4641        return res;
4642    }
4643
4644    @Override
4645    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4646            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4647            int startFlags, Configuration config, Bundle bOptions, int userId) {
4648        enforceNotIsolatedCaller("startActivityWithConfig");
4649        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4650                userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4651        // TODO: Switch to user app stacks here.
4652        int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4653                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4654                null, null, config, bOptions, false, userId, null, null);
4655        return ret;
4656    }
4657
4658    @Override
4659    public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4660            Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4661            int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4662            throws TransactionTooLargeException {
4663        enforceNotIsolatedCaller("startActivityIntentSender");
4664        // Refuse possible leaked file descriptors
4665        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4666            throw new IllegalArgumentException("File descriptors passed in Intent");
4667        }
4668
4669        IIntentSender sender = intent.getTarget();
4670        if (!(sender instanceof PendingIntentRecord)) {
4671            throw new IllegalArgumentException("Bad PendingIntent object");
4672        }
4673
4674        PendingIntentRecord pir = (PendingIntentRecord)sender;
4675
4676        synchronized (this) {
4677            // If this is coming from the currently resumed activity, it is
4678            // effectively saying that app switches are allowed at this point.
4679            final ActivityStack stack = getFocusedStack();
4680            if (stack.mResumedActivity != null &&
4681                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4682                mAppSwitchesAllowedTime = 0;
4683            }
4684        }
4685        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4686                resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4687        return ret;
4688    }
4689
4690    @Override
4691    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4692            Intent intent, String resolvedType, IVoiceInteractionSession session,
4693            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4694            Bundle bOptions, int userId) {
4695        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4696                != PackageManager.PERMISSION_GRANTED) {
4697            String msg = "Permission Denial: startVoiceActivity() from pid="
4698                    + Binder.getCallingPid()
4699                    + ", uid=" + Binder.getCallingUid()
4700                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4701            Slog.w(TAG, msg);
4702            throw new SecurityException(msg);
4703        }
4704        if (session == null || interactor == null) {
4705            throw new NullPointerException("null session or interactor");
4706        }
4707        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4708                ALLOW_FULL_ONLY, "startVoiceActivity", null);
4709        // TODO: Switch to user app stacks here.
4710        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4711                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4712                null, bOptions, false, userId, null, null);
4713    }
4714
4715    @Override
4716    public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4717            Intent intent, String resolvedType, Bundle bOptions, int userId) {
4718        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4719                != PackageManager.PERMISSION_GRANTED) {
4720            final String msg = "Permission Denial: startAssistantActivity() from pid="
4721                    + Binder.getCallingPid()
4722                    + ", uid=" + Binder.getCallingUid()
4723                    + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4724            Slog.w(TAG, msg);
4725            throw new SecurityException(msg);
4726        }
4727        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4728                ALLOW_FULL_ONLY, "startAssistantActivity", null);
4729        return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4730                resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4731                userId, null, null);
4732    }
4733
4734    @Override
4735    public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4736            throws RemoteException {
4737        Slog.i(TAG, "Activity tried to startVoiceInteraction");
4738        synchronized (this) {
4739            ActivityRecord activity = getFocusedStack().topActivity();
4740            if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4741                throw new SecurityException("Only focused activity can call startVoiceInteraction");
4742            }
4743            if (mRunningVoice != null || activity.task.voiceSession != null
4744                    || activity.voiceSession != null) {
4745                Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4746                return;
4747            }
4748            if (activity.pendingVoiceInteractionStart) {
4749                Slog.w(TAG, "Pending start of voice interaction already.");
4750                return;
4751            }
4752            activity.pendingVoiceInteractionStart = true;
4753        }
4754        LocalServices.getService(VoiceInteractionManagerInternal.class)
4755                .startLocalVoiceInteraction(callingActivity, options);
4756    }
4757
4758    @Override
4759    public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4760        LocalServices.getService(VoiceInteractionManagerInternal.class)
4761                .stopLocalVoiceInteraction(callingActivity);
4762    }
4763
4764    @Override
4765    public boolean supportsLocalVoiceInteraction() throws RemoteException {
4766        return LocalServices.getService(VoiceInteractionManagerInternal.class)
4767                .supportsLocalVoiceInteraction();
4768    }
4769
4770    void onLocalVoiceInteractionStartedLocked(IBinder activity,
4771            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4772        ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4773        if (activityToCallback == null) return;
4774        activityToCallback.setVoiceSessionLocked(voiceSession);
4775
4776        // Inform the activity
4777        try {
4778            activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4779                    voiceInteractor);
4780            long token = Binder.clearCallingIdentity();
4781            try {
4782                startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4783            } finally {
4784                Binder.restoreCallingIdentity(token);
4785            }
4786            // TODO: VI Should we cache the activity so that it's easier to find later
4787            // rather than scan through all the stacks and activities?
4788        } catch (RemoteException re) {
4789            activityToCallback.clearVoiceSessionLocked();
4790            // TODO: VI Should this terminate the voice session?
4791        }
4792    }
4793
4794    @Override
4795    public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4796        synchronized (this) {
4797            if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4798                if (keepAwake) {
4799                    mVoiceWakeLock.acquire();
4800                } else {
4801                    mVoiceWakeLock.release();
4802                }
4803            }
4804        }
4805    }
4806
4807    @Override
4808    public boolean startNextMatchingActivity(IBinder callingActivity,
4809            Intent intent, Bundle bOptions) {
4810        // Refuse possible leaked file descriptors
4811        if (intent != null && intent.hasFileDescriptors() == true) {
4812            throw new IllegalArgumentException("File descriptors passed in Intent");
4813        }
4814        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4815
4816        synchronized (this) {
4817            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4818            if (r == null) {
4819                ActivityOptions.abort(options);
4820                return false;
4821            }
4822            if (r.app == null || r.app.thread == null) {
4823                // The caller is not running...  d'oh!
4824                ActivityOptions.abort(options);
4825                return false;
4826            }
4827            intent = new Intent(intent);
4828            // The caller is not allowed to change the data.
4829            intent.setDataAndType(r.intent.getData(), r.intent.getType());
4830            // And we are resetting to find the next component...
4831            intent.setComponent(null);
4832
4833            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4834
4835            ActivityInfo aInfo = null;
4836            try {
4837                List<ResolveInfo> resolves =
4838                    AppGlobals.getPackageManager().queryIntentActivities(
4839                            intent, r.resolvedType,
4840                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4841                            UserHandle.getCallingUserId()).getList();
4842
4843                // Look for the original activity in the list...
4844                final int N = resolves != null ? resolves.size() : 0;
4845                for (int i=0; i<N; i++) {
4846                    ResolveInfo rInfo = resolves.get(i);
4847                    if (rInfo.activityInfo.packageName.equals(r.packageName)
4848                            && rInfo.activityInfo.name.equals(r.info.name)) {
4849                        // We found the current one...  the next matching is
4850                        // after it.
4851                        i++;
4852                        if (i<N) {
4853                            aInfo = resolves.get(i).activityInfo;
4854                        }
4855                        if (debug) {
4856                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
4857                                    + "/" + r.info.name);
4858                            Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4859                                    ? "null" : aInfo.packageName + "/" + aInfo.name));
4860                        }
4861                        break;
4862                    }
4863                }
4864            } catch (RemoteException e) {
4865            }
4866
4867            if (aInfo == null) {
4868                // Nobody who is next!
4869                ActivityOptions.abort(options);
4870                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4871                return false;
4872            }
4873
4874            intent.setComponent(new ComponentName(
4875                    aInfo.applicationInfo.packageName, aInfo.name));
4876            intent.setFlags(intent.getFlags()&~(
4877                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4878                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
4879                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4880                    Intent.FLAG_ACTIVITY_NEW_TASK));
4881
4882            // Okay now we need to start the new activity, replacing the
4883            // currently running activity.  This is a little tricky because
4884            // we want to start the new one as if the current one is finished,
4885            // but not finish the current one first so that there is no flicker.
4886            // And thus...
4887            final boolean wasFinishing = r.finishing;
4888            r.finishing = true;
4889
4890            // Propagate reply information over to the new activity.
4891            final ActivityRecord resultTo = r.resultTo;
4892            final String resultWho = r.resultWho;
4893            final int requestCode = r.requestCode;
4894            r.resultTo = null;
4895            if (resultTo != null) {
4896                resultTo.removeResultsLocked(r, resultWho, requestCode);
4897            }
4898
4899            final long origId = Binder.clearCallingIdentity();
4900            int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4901                    null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4902                    null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4903                    r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4904                    false, false, null, null, null);
4905            Binder.restoreCallingIdentity(origId);
4906
4907            r.finishing = wasFinishing;
4908            if (res != ActivityManager.START_SUCCESS) {
4909                return false;
4910            }
4911            return true;
4912        }
4913    }
4914
4915    @Override
4916    public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4917        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4918            String msg = "Permission Denial: startActivityFromRecents called without " +
4919                    START_TASKS_FROM_RECENTS;
4920            Slog.w(TAG, msg);
4921            throw new SecurityException(msg);
4922        }
4923        final long origId = Binder.clearCallingIdentity();
4924        try {
4925            synchronized (this) {
4926                return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4927            }
4928        } finally {
4929            Binder.restoreCallingIdentity(origId);
4930        }
4931    }
4932
4933    final int startActivityInPackage(int uid, String callingPackage,
4934            Intent intent, String resolvedType, IBinder resultTo,
4935            String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4936            IActivityContainer container, TaskRecord inTask) {
4937
4938        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4939                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4940
4941        // TODO: Switch to user app stacks here.
4942        int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4943                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4944                null, null, null, bOptions, false, userId, container, inTask);
4945        return ret;
4946    }
4947
4948    @Override
4949    public final int startActivities(IApplicationThread caller, String callingPackage,
4950            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4951            int userId) {
4952        enforceNotIsolatedCaller("startActivities");
4953        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4954                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4955        // TODO: Switch to user app stacks here.
4956        int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4957                resolvedTypes, resultTo, bOptions, userId);
4958        return ret;
4959    }
4960
4961    final int startActivitiesInPackage(int uid, String callingPackage,
4962            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4963            Bundle bOptions, int userId) {
4964
4965        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4966                userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4967        // TODO: Switch to user app stacks here.
4968        int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4969                resultTo, bOptions, userId);
4970        return ret;
4971    }
4972
4973    @Override
4974    public void reportActivityFullyDrawn(IBinder token) {
4975        synchronized (this) {
4976            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4977            if (r == null) {
4978                return;
4979            }
4980            r.reportFullyDrawnLocked();
4981        }
4982    }
4983
4984    @Override
4985    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4986        synchronized (this) {
4987            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4988            if (r == null) {
4989                return;
4990            }
4991            final long origId = Binder.clearCallingIdentity();
4992            try {
4993                r.setRequestedOrientation(requestedOrientation);
4994            } finally {
4995                Binder.restoreCallingIdentity(origId);
4996            }
4997        }
4998    }
4999
5000    @Override
5001    public int getRequestedOrientation(IBinder token) {
5002        synchronized (this) {
5003            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5004            if (r == null) {
5005                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5006            }
5007            return r.getRequestedOrientation();
5008        }
5009    }
5010
5011    @Override
5012    public final void requestActivityRelaunch(IBinder token) {
5013        synchronized(this) {
5014            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5015            if (r == null) {
5016                return;
5017            }
5018            final long origId = Binder.clearCallingIdentity();
5019            try {
5020                r.forceNewConfig = true;
5021                r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5022                        false /* preserveWindow */);
5023            } finally {
5024                Binder.restoreCallingIdentity(origId);
5025            }
5026        }
5027    }
5028
5029    /**
5030     * This is the internal entry point for handling Activity.finish().
5031     *
5032     * @param token The Binder token referencing the Activity we want to finish.
5033     * @param resultCode Result code, if any, from this Activity.
5034     * @param resultData Result data (Intent), if any, from this Activity.
5035     * @param finishTask Whether to finish the task associated with this Activity.
5036     *
5037     * @return Returns true if the activity successfully finished, or false if it is still running.
5038     */
5039    @Override
5040    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5041            int finishTask) {
5042        // Refuse possible leaked file descriptors
5043        if (resultData != null && resultData.hasFileDescriptors() == true) {
5044            throw new IllegalArgumentException("File descriptors passed in Intent");
5045        }
5046
5047        synchronized(this) {
5048            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5049            if (r == null) {
5050                return true;
5051            }
5052            // Keep track of the root activity of the task before we finish it
5053            TaskRecord tr = r.task;
5054            ActivityRecord rootR = tr.getRootActivity();
5055            if (rootR == null) {
5056                Slog.w(TAG, "Finishing task with all activities already finished");
5057            }
5058            // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5059            // finish.
5060            if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5061                    mStackSupervisor.isLastLockedTask(tr)) {
5062                Slog.i(TAG, "Not finishing task in lock task mode");
5063                mStackSupervisor.showLockTaskToast();
5064                return false;
5065            }
5066            if (mController != null) {
5067                // Find the first activity that is not finishing.
5068                ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5069                if (next != null) {
5070                    // ask watcher if this is allowed
5071                    boolean resumeOK = true;
5072                    try {
5073                        resumeOK = mController.activityResuming(next.packageName);
5074                    } catch (RemoteException e) {
5075                        mController = null;
5076                        Watchdog.getInstance().setActivityController(null);
5077                    }
5078
5079                    if (!resumeOK) {
5080                        Slog.i(TAG, "Not finishing activity because controller resumed");
5081                        return false;
5082                    }
5083                }
5084            }
5085            final long origId = Binder.clearCallingIdentity();
5086            try {
5087                boolean res;
5088                final boolean finishWithRootActivity =
5089                        finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5090                if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5091                        || (finishWithRootActivity && r == rootR)) {
5092                    // If requested, remove the task that is associated to this activity only if it
5093                    // was the root activity in the task. The result code and data is ignored
5094                    // because we don't support returning them across task boundaries. Also, to
5095                    // keep backwards compatibility we remove the task from recents when finishing
5096                    // task with root activity.
5097                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5098                    if (!res) {
5099                        Slog.i(TAG, "Removing task failed to finish activity");
5100                    }
5101                } else {
5102                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5103                            resultData, "app-request", true);
5104                    if (!res) {
5105                        Slog.i(TAG, "Failed to finish by app-request");
5106                    }
5107                }
5108                return res;
5109            } finally {
5110                Binder.restoreCallingIdentity(origId);
5111            }
5112        }
5113    }
5114
5115    @Override
5116    public final void finishHeavyWeightApp() {
5117        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5118                != PackageManager.PERMISSION_GRANTED) {
5119            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5120                    + Binder.getCallingPid()
5121                    + ", uid=" + Binder.getCallingUid()
5122                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5123            Slog.w(TAG, msg);
5124            throw new SecurityException(msg);
5125        }
5126
5127        synchronized(this) {
5128            if (mHeavyWeightProcess == null) {
5129                return;
5130            }
5131
5132            ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5133            for (int i = 0; i < activities.size(); i++) {
5134                ActivityRecord r = activities.get(i);
5135                if (!r.finishing && r.isInStackLocked()) {
5136                    r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5137                            null, "finish-heavy", true);
5138                }
5139            }
5140
5141            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5142                    mHeavyWeightProcess.userId, 0));
5143            mHeavyWeightProcess = null;
5144        }
5145    }
5146
5147    @Override
5148    public void crashApplication(int uid, int initialPid, String packageName, int userId,
5149            String message) {
5150        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5151                != PackageManager.PERMISSION_GRANTED) {
5152            String msg = "Permission Denial: crashApplication() from pid="
5153                    + Binder.getCallingPid()
5154                    + ", uid=" + Binder.getCallingUid()
5155                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5156            Slog.w(TAG, msg);
5157            throw new SecurityException(msg);
5158        }
5159
5160        synchronized(this) {
5161            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5162        }
5163    }
5164
5165    @Override
5166    public final void finishSubActivity(IBinder token, String resultWho,
5167            int requestCode) {
5168        synchronized(this) {
5169            final long origId = Binder.clearCallingIdentity();
5170            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5171            if (r != null) {
5172                r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5173            }
5174            Binder.restoreCallingIdentity(origId);
5175        }
5176    }
5177
5178    @Override
5179    public boolean finishActivityAffinity(IBinder token) {
5180        synchronized(this) {
5181            final long origId = Binder.clearCallingIdentity();
5182            try {
5183                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5184                if (r == null) {
5185                    return false;
5186                }
5187
5188                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5189                // can finish.
5190                final TaskRecord task = r.task;
5191                if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5192                        mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5193                    mStackSupervisor.showLockTaskToast();
5194                    return false;
5195                }
5196                return task.getStack().finishActivityAffinityLocked(r);
5197            } finally {
5198                Binder.restoreCallingIdentity(origId);
5199            }
5200        }
5201    }
5202
5203    @Override
5204    public void finishVoiceTask(IVoiceInteractionSession session) {
5205        synchronized (this) {
5206            final long origId = Binder.clearCallingIdentity();
5207            try {
5208                // TODO: VI Consider treating local voice interactions and voice tasks
5209                // differently here
5210                mStackSupervisor.finishVoiceTask(session);
5211            } finally {
5212                Binder.restoreCallingIdentity(origId);
5213            }
5214        }
5215
5216    }
5217
5218    @Override
5219    public boolean releaseActivityInstance(IBinder token) {
5220        synchronized(this) {
5221            final long origId = Binder.clearCallingIdentity();
5222            try {
5223                ActivityRecord r = ActivityRecord.isInStackLocked(token);
5224                if (r == null) {
5225                    return false;
5226                }
5227                return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5228            } finally {
5229                Binder.restoreCallingIdentity(origId);
5230            }
5231        }
5232    }
5233
5234    @Override
5235    public void releaseSomeActivities(IApplicationThread appInt) {
5236        synchronized(this) {
5237            final long origId = Binder.clearCallingIdentity();
5238            try {
5239                ProcessRecord app = getRecordForAppLocked(appInt);
5240                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5241            } finally {
5242                Binder.restoreCallingIdentity(origId);
5243            }
5244        }
5245    }
5246
5247    @Override
5248    public boolean willActivityBeVisible(IBinder token) {
5249        synchronized(this) {
5250            ActivityStack stack = ActivityRecord.getStackLocked(token);
5251            if (stack != null) {
5252                return stack.willActivityBeVisibleLocked(token);
5253            }
5254            return false;
5255        }
5256    }
5257
5258    @Override
5259    public void overridePendingTransition(IBinder token, String packageName,
5260            int enterAnim, int exitAnim) {
5261        synchronized(this) {
5262            ActivityRecord self = ActivityRecord.isInStackLocked(token);
5263            if (self == null) {
5264                return;
5265            }
5266
5267            final long origId = Binder.clearCallingIdentity();
5268
5269            if (self.state == ActivityState.RESUMED
5270                    || self.state == ActivityState.PAUSING) {
5271                mWindowManager.overridePendingAppTransition(packageName,
5272                        enterAnim, exitAnim, null);
5273            }
5274
5275            Binder.restoreCallingIdentity(origId);
5276        }
5277    }
5278
5279    /**
5280     * Main function for removing an existing process from the activity manager
5281     * as a result of that process going away.  Clears out all connections
5282     * to the process.
5283     */
5284    private final void handleAppDiedLocked(ProcessRecord app,
5285            boolean restarting, boolean allowRestart) {
5286        int pid = app.pid;
5287        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5288                false /*replacingPid*/);
5289        if (!kept && !restarting) {
5290            removeLruProcessLocked(app);
5291            if (pid > 0) {
5292                ProcessList.remove(pid);
5293            }
5294        }
5295
5296        if (mProfileProc == app) {
5297            clearProfilerLocked();
5298        }
5299
5300        // Remove this application's activities from active lists.
5301        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5302
5303        app.activities.clear();
5304
5305        if (app.instr != null) {
5306            Slog.w(TAG, "Crash of app " + app.processName
5307                  + " running instrumentation " + app.instr.mClass);
5308            Bundle info = new Bundle();
5309            info.putString("shortMsg", "Process crashed.");
5310            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5311        }
5312
5313        mWindowManager.deferSurfaceLayout();
5314        try {
5315            if (!restarting && hasVisibleActivities
5316                    && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5317                // If there was nothing to resume, and we are not already restarting this process, but
5318                // there is a visible activity that is hosted by the process...  then make sure all
5319                // visible activities are running, taking care of restarting this process.
5320                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5321            }
5322        } finally {
5323            mWindowManager.continueSurfaceLayout();
5324        }
5325    }
5326
5327    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5328        IBinder threadBinder = thread.asBinder();
5329        // Find the application record.
5330        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5331            ProcessRecord rec = mLruProcesses.get(i);
5332            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5333                return i;
5334            }
5335        }
5336        return -1;
5337    }
5338
5339    final ProcessRecord getRecordForAppLocked(
5340            IApplicationThread thread) {
5341        if (thread == null) {
5342            return null;
5343        }
5344
5345        int appIndex = getLRURecordIndexForAppLocked(thread);
5346        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5347    }
5348
5349    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5350        // If there are no longer any background processes running,
5351        // and the app that died was not running instrumentation,
5352        // then tell everyone we are now low on memory.
5353        boolean haveBg = false;
5354        for (int i=mLruProcesses.size()-1; i>=0; i--) {
5355            ProcessRecord rec = mLruProcesses.get(i);
5356            if (rec.thread != null
5357                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5358                haveBg = true;
5359                break;
5360            }
5361        }
5362
5363        if (!haveBg) {
5364            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5365            if (doReport) {
5366                long now = SystemClock.uptimeMillis();
5367                if (now < (mLastMemUsageReportTime+5*60*1000)) {
5368                    doReport = false;
5369                } else {
5370                    mLastMemUsageReportTime = now;
5371                }
5372            }
5373            final ArrayList<ProcessMemInfo> memInfos
5374                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5375            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5376            long now = SystemClock.uptimeMillis();
5377            for (int i=mLruProcesses.size()-1; i>=0; i--) {
5378                ProcessRecord rec = mLruProcesses.get(i);
5379                if (rec == dyingProc || rec.thread == null) {
5380                    continue;
5381                }
5382                if (doReport) {
5383                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5384                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
5385                }
5386                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5387                    // The low memory report is overriding any current
5388                    // state for a GC request.  Make sure to do
5389                    // heavy/important/visible/foreground processes first.
5390                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5391                        rec.lastRequestedGc = 0;
5392                    } else {
5393                        rec.lastRequestedGc = rec.lastLowMemory;
5394                    }
5395                    rec.reportLowMemory = true;
5396                    rec.lastLowMemory = now;
5397                    mProcessesToGc.remove(rec);
5398                    addProcessToGcListLocked(rec);
5399                }
5400            }
5401            if (doReport) {
5402                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5403                mHandler.sendMessage(msg);
5404            }
5405            scheduleAppGcsLocked();
5406        }
5407    }
5408
5409    final void appDiedLocked(ProcessRecord app) {
5410       appDiedLocked(app, app.pid, app.thread, false);
5411    }
5412
5413    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5414            boolean fromBinderDied) {
5415        // First check if this ProcessRecord is actually active for the pid.
5416        synchronized (mPidsSelfLocked) {
5417            ProcessRecord curProc = mPidsSelfLocked.get(pid);
5418            if (curProc != app) {
5419                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5420                return;
5421            }
5422        }
5423
5424        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5425        synchronized (stats) {
5426            stats.noteProcessDiedLocked(app.info.uid, pid);
5427        }
5428
5429        if (!app.killed) {
5430            if (!fromBinderDied) {
5431                Process.killProcessQuiet(pid);
5432            }
5433            killProcessGroup(app.uid, pid);
5434            app.killed = true;
5435        }
5436
5437        // Clean up already done if the process has been re-started.
5438        if (app.pid == pid && app.thread != null &&
5439                app.thread.asBinder() == thread.asBinder()) {
5440            boolean doLowMem = app.instr == null;
5441            boolean doOomAdj = doLowMem;
5442            if (!app.killedByAm) {
5443                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5444                        + ") has died");
5445                mAllowLowerMemLevel = true;
5446            } else {
5447                // Note that we always want to do oom adj to update our state with the
5448                // new number of procs.
5449                mAllowLowerMemLevel = false;
5450                doLowMem = false;
5451            }
5452            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5453            if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5454                "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5455            handleAppDiedLocked(app, false, true);
5456
5457            if (doOomAdj) {
5458                updateOomAdjLocked();
5459            }
5460            if (doLowMem) {
5461                doLowMemReportIfNeededLocked(app);
5462            }
5463        } else if (app.pid != pid) {
5464            // A new process has already been started.
5465            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5466                    + ") has died and restarted (pid " + app.pid + ").");
5467            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5468        } else if (DEBUG_PROCESSES) {
5469            Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5470                    + thread.asBinder());
5471        }
5472    }
5473
5474    /**
5475     * If a stack trace dump file is configured, dump process stack traces.
5476     * @param clearTraces causes the dump file to be erased prior to the new
5477     *    traces being written, if true; when false, the new traces will be
5478     *    appended to any existing file content.
5479     * @param firstPids of dalvik VM processes to dump stack traces for first
5480     * @param lastPids of dalvik VM processes to dump stack traces for last
5481     * @param nativePids optional list of native pids to dump stack crawls
5482     * @return file containing stack traces, or null if no dump file is configured
5483     */
5484    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5485            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5486            ArrayList<Integer> nativePids) {
5487        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5488        if (tracesPath == null || tracesPath.length() == 0) {
5489            return null;
5490        }
5491
5492        File tracesFile = new File(tracesPath);
5493        try {
5494            if (clearTraces && tracesFile.exists()) tracesFile.delete();
5495            tracesFile.createNewFile();
5496            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5497        } catch (IOException e) {
5498            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5499            return null;
5500        }
5501
5502        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativePids);
5503        return tracesFile;
5504    }
5505
5506    public static class DumpStackFileObserver extends FileObserver {
5507        // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5508        private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5509        static final int TRACE_DUMP_TIMEOUT_SECONDS = TRACE_DUMP_TIMEOUT_MS / 1000;
5510
5511        private final String mTracesPath;
5512        private boolean mClosed;
5513
5514        public DumpStackFileObserver(String tracesPath) {
5515            super(tracesPath, FileObserver.CLOSE_WRITE);
5516            mTracesPath = tracesPath;
5517        }
5518
5519        @Override
5520        public synchronized void onEvent(int event, String path) {
5521            mClosed = true;
5522            notify();
5523        }
5524
5525        public void dumpWithTimeout(int pid) {
5526            Process.sendSignal(pid, Process.SIGNAL_QUIT);
5527            synchronized (this) {
5528                try {
5529                    wait(TRACE_DUMP_TIMEOUT_MS); // Wait for traces file to be closed.
5530                } catch (InterruptedException e) {
5531                    Slog.wtf(TAG, e);
5532                }
5533            }
5534            if (!mClosed) {
5535                Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5536                       ". Attempting native stack collection.");
5537                Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath, TRACE_DUMP_TIMEOUT_SECONDS);
5538            }
5539            mClosed = false;
5540        }
5541    }
5542
5543    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5544            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5545            ArrayList<Integer> nativePids) {
5546        // Use a FileObserver to detect when traces finish writing.
5547        // The order of traces is considered important to maintain for legibility.
5548        DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
5549        try {
5550            observer.startWatching();
5551
5552            // First collect all of the stacks of the most important pids.
5553            if (firstPids != null) {
5554                int num = firstPids.size();
5555                for (int i = 0; i < num; i++) {
5556                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5557                            + firstPids.get(i));
5558                    final long sime = SystemClock.elapsedRealtime();
5559                    observer.dumpWithTimeout(firstPids.get(i));
5560                    if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5561                            + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5562                }
5563            }
5564
5565            // Next collect the stacks of the native pids
5566            if (nativePids != null) {
5567                for (int pid : nativePids) {
5568                    if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5569                    final long sime = SystemClock.elapsedRealtime();
5570
5571                    Debug.dumpNativeBacktraceToFileTimeout(
5572                            pid, tracesPath, DumpStackFileObserver.TRACE_DUMP_TIMEOUT_SECONDS);
5573                    if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5574                            + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5575                }
5576            }
5577
5578            // Lastly, measure CPU usage.
5579            if (processCpuTracker != null) {
5580                processCpuTracker.init();
5581                System.gc();
5582                processCpuTracker.update();
5583                try {
5584                    synchronized (processCpuTracker) {
5585                        processCpuTracker.wait(500); // measure over 1/2 second.
5586                    }
5587                } catch (InterruptedException e) {
5588                }
5589                processCpuTracker.update();
5590
5591                // We'll take the stack crawls of just the top apps using CPU.
5592                final int N = processCpuTracker.countWorkingStats();
5593                int numProcs = 0;
5594                for (int i=0; i<N && numProcs<5; i++) {
5595                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5596                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5597                        numProcs++;
5598                        if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5599                                + stats.pid);
5600                        final long stime = SystemClock.elapsedRealtime();
5601                        observer.dumpWithTimeout(stats.pid);
5602                        if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5603                                + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5604                    } else if (DEBUG_ANR) {
5605                        Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5606                                + stats.pid);
5607                    }
5608                }
5609            }
5610        } finally {
5611            observer.stopWatching();
5612        }
5613    }
5614
5615    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5616        if (true || IS_USER_BUILD) {
5617            return;
5618        }
5619        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5620        if (tracesPath == null || tracesPath.length() == 0) {
5621            return;
5622        }
5623
5624        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5625        StrictMode.allowThreadDiskWrites();
5626        try {
5627            final File tracesFile = new File(tracesPath);
5628            final File tracesDir = tracesFile.getParentFile();
5629            final File tracesTmp = new File(tracesDir, "__tmp__");
5630            try {
5631                if (tracesFile.exists()) {
5632                    tracesTmp.delete();
5633                    tracesFile.renameTo(tracesTmp);
5634                }
5635                StringBuilder sb = new StringBuilder();
5636                Time tobj = new Time();
5637                tobj.set(System.currentTimeMillis());
5638                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5639                sb.append(": ");
5640                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5641                sb.append(" since ");
5642                sb.append(msg);
5643                FileOutputStream fos = new FileOutputStream(tracesFile);
5644                fos.write(sb.toString().getBytes());
5645                if (app == null) {
5646                    fos.write("\n*** No application process!".getBytes());
5647                }
5648                fos.close();
5649                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5650            } catch (IOException e) {
5651                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5652                return;
5653            }
5654
5655            if (app != null) {
5656                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5657                firstPids.add(app.pid);
5658                dumpStackTraces(tracesPath, firstPids, null, null, null);
5659            }
5660
5661            File lastTracesFile = null;
5662            File curTracesFile = null;
5663            for (int i=9; i>=0; i--) {
5664                String name = String.format(Locale.US, "slow%02d.txt", i);
5665                curTracesFile = new File(tracesDir, name);
5666                if (curTracesFile.exists()) {
5667                    if (lastTracesFile != null) {
5668                        curTracesFile.renameTo(lastTracesFile);
5669                    } else {
5670                        curTracesFile.delete();
5671                    }
5672                }
5673                lastTracesFile = curTracesFile;
5674            }
5675            tracesFile.renameTo(curTracesFile);
5676            if (tracesTmp.exists()) {
5677                tracesTmp.renameTo(tracesFile);
5678            }
5679        } finally {
5680            StrictMode.setThreadPolicy(oldPolicy);
5681        }
5682    }
5683
5684    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5685        if (!mLaunchWarningShown) {
5686            mLaunchWarningShown = true;
5687            mUiHandler.post(new Runnable() {
5688                @Override
5689                public void run() {
5690                    synchronized (ActivityManagerService.this) {
5691                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5692                        d.show();
5693                        mUiHandler.postDelayed(new Runnable() {
5694                            @Override
5695                            public void run() {
5696                                synchronized (ActivityManagerService.this) {
5697                                    d.dismiss();
5698                                    mLaunchWarningShown = false;
5699                                }
5700                            }
5701                        }, 4000);
5702                    }
5703                }
5704            });
5705        }
5706    }
5707
5708    @Override
5709    public boolean clearApplicationUserData(final String packageName,
5710            final IPackageDataObserver observer, int userId) {
5711        enforceNotIsolatedCaller("clearApplicationUserData");
5712        int uid = Binder.getCallingUid();
5713        int pid = Binder.getCallingPid();
5714        userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5715                ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5716
5717
5718        long callingId = Binder.clearCallingIdentity();
5719        try {
5720            IPackageManager pm = AppGlobals.getPackageManager();
5721            int pkgUid = -1;
5722            synchronized(this) {
5723                if (getPackageManagerInternalLocked().isPackageDataProtected(
5724                        userId, packageName)) {
5725                    throw new SecurityException(
5726                            "Cannot clear data for a protected package: " + packageName);
5727                }
5728
5729                try {
5730                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5731                } catch (RemoteException e) {
5732                }
5733                if (pkgUid == -1) {
5734                    Slog.w(TAG, "Invalid packageName: " + packageName);
5735                    if (observer != null) {
5736                        try {
5737                            observer.onRemoveCompleted(packageName, false);
5738                        } catch (RemoteException e) {
5739                            Slog.i(TAG, "Observer no longer exists.");
5740                        }
5741                    }
5742                    return false;
5743                }
5744                if (uid == pkgUid || checkComponentPermission(
5745                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5746                        pid, uid, -1, true)
5747                        == PackageManager.PERMISSION_GRANTED) {
5748                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5749                } else {
5750                    throw new SecurityException("PID " + pid + " does not have permission "
5751                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5752                                    + " of package " + packageName);
5753                }
5754
5755                // Remove all tasks match the cleared application package and user
5756                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5757                    final TaskRecord tr = mRecentTasks.get(i);
5758                    final String taskPackageName =
5759                            tr.getBaseIntent().getComponent().getPackageName();
5760                    if (tr.userId != userId) continue;
5761                    if (!taskPackageName.equals(packageName)) continue;
5762                    mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5763                }
5764            }
5765
5766            final int pkgUidF = pkgUid;
5767            final int userIdF = userId;
5768            final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5769                @Override
5770                public void onRemoveCompleted(String packageName, boolean succeeded)
5771                        throws RemoteException {
5772                    synchronized (ActivityManagerService.this) {
5773                        finishForceStopPackageLocked(packageName, pkgUidF);
5774                    }
5775
5776                    final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5777                            Uri.fromParts("package", packageName, null));
5778                    intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5779                    intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5780                    intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5781                    broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5782                            null, null, 0, null, null, null, null, false, false, userIdF);
5783
5784                    if (observer != null) {
5785                        observer.onRemoveCompleted(packageName, succeeded);
5786                    }
5787                }
5788            };
5789
5790            try {
5791                // Clear application user data
5792                pm.clearApplicationUserData(packageName, localObserver, userId);
5793
5794                synchronized(this) {
5795                    // Remove all permissions granted from/to this package
5796                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5797                }
5798
5799                // Reset notification settings.
5800                INotificationManager inm = NotificationManager.getService();
5801                inm.clearData(packageName, pkgUidF, uid == pkgUidF);
5802            } catch (RemoteException e) {
5803            }
5804        } finally {
5805            Binder.restoreCallingIdentity(callingId);
5806        }
5807        return true;
5808    }
5809
5810    @Override
5811    public void killBackgroundProcesses(final String packageName, int userId) {
5812        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5813                != PackageManager.PERMISSION_GRANTED &&
5814                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5815                        != PackageManager.PERMISSION_GRANTED) {
5816            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5817                    + Binder.getCallingPid()
5818                    + ", uid=" + Binder.getCallingUid()
5819                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5820            Slog.w(TAG, msg);
5821            throw new SecurityException(msg);
5822        }
5823
5824        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5825                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5826        long callingId = Binder.clearCallingIdentity();
5827        try {
5828            IPackageManager pm = AppGlobals.getPackageManager();
5829            synchronized(this) {
5830                int appId = -1;
5831                try {
5832                    appId = UserHandle.getAppId(
5833                            pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5834                } catch (RemoteException e) {
5835                }
5836                if (appId == -1) {
5837                    Slog.w(TAG, "Invalid packageName: " + packageName);
5838                    return;
5839                }
5840                killPackageProcessesLocked(packageName, appId, userId,
5841                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5842            }
5843        } finally {
5844            Binder.restoreCallingIdentity(callingId);
5845        }
5846    }
5847
5848    @Override
5849    public void killAllBackgroundProcesses() {
5850        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5851                != PackageManager.PERMISSION_GRANTED) {
5852            final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5853                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5854                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5855            Slog.w(TAG, msg);
5856            throw new SecurityException(msg);
5857        }
5858
5859        final long callingId = Binder.clearCallingIdentity();
5860        try {
5861            synchronized (this) {
5862                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5863                final int NP = mProcessNames.getMap().size();
5864                for (int ip = 0; ip < NP; ip++) {
5865                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5866                    final int NA = apps.size();
5867                    for (int ia = 0; ia < NA; ia++) {
5868                        final ProcessRecord app = apps.valueAt(ia);
5869                        if (app.persistent) {
5870                            // We don't kill persistent processes.
5871                            continue;
5872                        }
5873                        if (app.removed) {
5874                            procs.add(app);
5875                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5876                            app.removed = true;
5877                            procs.add(app);
5878                        }
5879                    }
5880                }
5881
5882                final int N = procs.size();
5883                for (int i = 0; i < N; i++) {
5884                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5885                }
5886
5887                mAllowLowerMemLevel = true;
5888
5889                updateOomAdjLocked();
5890                doLowMemReportIfNeededLocked(null);
5891            }
5892        } finally {
5893            Binder.restoreCallingIdentity(callingId);
5894        }
5895    }
5896
5897    /**
5898     * Kills all background processes, except those matching any of the
5899     * specified properties.
5900     *
5901     * @param minTargetSdk the target SDK version at or above which to preserve
5902     *                     processes, or {@code -1} to ignore the target SDK
5903     * @param maxProcState the process state at or below which to preserve
5904     *                     processes, or {@code -1} to ignore the process state
5905     */
5906    private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5907        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5908                != PackageManager.PERMISSION_GRANTED) {
5909            final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5910                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5911                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5912            Slog.w(TAG, msg);
5913            throw new SecurityException(msg);
5914        }
5915
5916        final long callingId = Binder.clearCallingIdentity();
5917        try {
5918            synchronized (this) {
5919                final ArrayList<ProcessRecord> procs = new ArrayList<>();
5920                final int NP = mProcessNames.getMap().size();
5921                for (int ip = 0; ip < NP; ip++) {
5922                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5923                    final int NA = apps.size();
5924                    for (int ia = 0; ia < NA; ia++) {
5925                        final ProcessRecord app = apps.valueAt(ia);
5926                        if (app.removed) {
5927                            procs.add(app);
5928                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5929                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
5930                            app.removed = true;
5931                            procs.add(app);
5932                        }
5933                    }
5934                }
5935
5936                final int N = procs.size();
5937                for (int i = 0; i < N; i++) {
5938                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
5939                }
5940            }
5941        } finally {
5942            Binder.restoreCallingIdentity(callingId);
5943        }
5944    }
5945
5946    @Override
5947    public void forceStopPackage(final String packageName, int userId) {
5948        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5949                != PackageManager.PERMISSION_GRANTED) {
5950            String msg = "Permission Denial: forceStopPackage() from pid="
5951                    + Binder.getCallingPid()
5952                    + ", uid=" + Binder.getCallingUid()
5953                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5954            Slog.w(TAG, msg);
5955            throw new SecurityException(msg);
5956        }
5957        final int callingPid = Binder.getCallingPid();
5958        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5959                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5960        long callingId = Binder.clearCallingIdentity();
5961        try {
5962            IPackageManager pm = AppGlobals.getPackageManager();
5963            synchronized(this) {
5964                int[] users = userId == UserHandle.USER_ALL
5965                        ? mUserController.getUsers() : new int[] { userId };
5966                for (int user : users) {
5967                    int pkgUid = -1;
5968                    try {
5969                        pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5970                                user);
5971                    } catch (RemoteException e) {
5972                    }
5973                    if (pkgUid == -1) {
5974                        Slog.w(TAG, "Invalid packageName: " + packageName);
5975                        continue;
5976                    }
5977                    try {
5978                        pm.setPackageStoppedState(packageName, true, user);
5979                    } catch (RemoteException e) {
5980                    } catch (IllegalArgumentException e) {
5981                        Slog.w(TAG, "Failed trying to unstop package "
5982                                + packageName + ": " + e);
5983                    }
5984                    if (mUserController.isUserRunningLocked(user, 0)) {
5985                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5986                        finishForceStopPackageLocked(packageName, pkgUid);
5987                    }
5988                }
5989            }
5990        } finally {
5991            Binder.restoreCallingIdentity(callingId);
5992        }
5993    }
5994
5995    @Override
5996    public void addPackageDependency(String packageName) {
5997        synchronized (this) {
5998            int callingPid = Binder.getCallingPid();
5999            if (callingPid == Process.myPid()) {
6000                //  Yeah, um, no.
6001                return;
6002            }
6003            ProcessRecord proc;
6004            synchronized (mPidsSelfLocked) {
6005                proc = mPidsSelfLocked.get(Binder.getCallingPid());
6006            }
6007            if (proc != null) {
6008                if (proc.pkgDeps == null) {
6009                    proc.pkgDeps = new ArraySet<String>(1);
6010                }
6011                proc.pkgDeps.add(packageName);
6012            }
6013        }
6014    }
6015
6016    /*
6017     * The pkg name and app id have to be specified.
6018     */
6019    @Override
6020    public void killApplication(String pkg, int appId, int userId, String reason) {
6021        if (pkg == null) {
6022            return;
6023        }
6024        // Make sure the uid is valid.
6025        if (appId < 0) {
6026            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6027            return;
6028        }
6029        int callerUid = Binder.getCallingUid();
6030        // Only the system server can kill an application
6031        if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
6032            // Post an aysnc message to kill the application
6033            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6034            msg.arg1 = appId;
6035            msg.arg2 = userId;
6036            Bundle bundle = new Bundle();
6037            bundle.putString("pkg", pkg);
6038            bundle.putString("reason", reason);
6039            msg.obj = bundle;
6040            mHandler.sendMessage(msg);
6041        } else {
6042            throw new SecurityException(callerUid + " cannot kill pkg: " +
6043                    pkg);
6044        }
6045    }
6046
6047    @Override
6048    public void closeSystemDialogs(String reason) {
6049        enforceNotIsolatedCaller("closeSystemDialogs");
6050
6051        final int pid = Binder.getCallingPid();
6052        final int uid = Binder.getCallingUid();
6053        final long origId = Binder.clearCallingIdentity();
6054        try {
6055            synchronized (this) {
6056                // Only allow this from foreground processes, so that background
6057                // applications can't abuse it to prevent system UI from being shown.
6058                if (uid >= Process.FIRST_APPLICATION_UID) {
6059                    ProcessRecord proc;
6060                    synchronized (mPidsSelfLocked) {
6061                        proc = mPidsSelfLocked.get(pid);
6062                    }
6063                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6064                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6065                                + " from background process " + proc);
6066                        return;
6067                    }
6068                }
6069                closeSystemDialogsLocked(reason);
6070            }
6071        } finally {
6072            Binder.restoreCallingIdentity(origId);
6073        }
6074    }
6075
6076    void closeSystemDialogsLocked(String reason) {
6077        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6078        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6079                | Intent.FLAG_RECEIVER_FOREGROUND);
6080        if (reason != null) {
6081            intent.putExtra("reason", reason);
6082        }
6083        mWindowManager.closeSystemDialogs(reason);
6084
6085        mStackSupervisor.closeSystemDialogsLocked();
6086
6087        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6088                AppOpsManager.OP_NONE, null, false, false,
6089                -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
6090    }
6091
6092    @Override
6093    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6094        enforceNotIsolatedCaller("getProcessMemoryInfo");
6095        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6096        for (int i=pids.length-1; i>=0; i--) {
6097            ProcessRecord proc;
6098            int oomAdj;
6099            synchronized (this) {
6100                synchronized (mPidsSelfLocked) {
6101                    proc = mPidsSelfLocked.get(pids[i]);
6102                    oomAdj = proc != null ? proc.setAdj : 0;
6103                }
6104            }
6105            infos[i] = new Debug.MemoryInfo();
6106            Debug.getMemoryInfo(pids[i], infos[i]);
6107            if (proc != null) {
6108                synchronized (this) {
6109                    if (proc.thread != null && proc.setAdj == oomAdj) {
6110                        // Record this for posterity if the process has been stable.
6111                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6112                                infos[i].getTotalUss(), false, proc.pkgList);
6113                    }
6114                }
6115            }
6116        }
6117        return infos;
6118    }
6119
6120    @Override
6121    public long[] getProcessPss(int[] pids) {
6122        enforceNotIsolatedCaller("getProcessPss");
6123        long[] pss = new long[pids.length];
6124        for (int i=pids.length-1; i>=0; i--) {
6125            ProcessRecord proc;
6126            int oomAdj;
6127            synchronized (this) {
6128                synchronized (mPidsSelfLocked) {
6129                    proc = mPidsSelfLocked.get(pids[i]);
6130                    oomAdj = proc != null ? proc.setAdj : 0;
6131                }
6132            }
6133            long[] tmpUss = new long[1];
6134            pss[i] = Debug.getPss(pids[i], tmpUss, null);
6135            if (proc != null) {
6136                synchronized (this) {
6137                    if (proc.thread != null && proc.setAdj == oomAdj) {
6138                        // Record this for posterity if the process has been stable.
6139                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6140                    }
6141                }
6142            }
6143        }
6144        return pss;
6145    }
6146
6147    @Override
6148    public void killApplicationProcess(String processName, int uid) {
6149        if (processName == null) {
6150            return;
6151        }
6152
6153        int callerUid = Binder.getCallingUid();
6154        // Only the system server can kill an application
6155        if (callerUid == Process.SYSTEM_UID) {
6156            synchronized (this) {
6157                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6158                if (app != null && app.thread != null) {
6159                    try {
6160                        app.thread.scheduleSuicide();
6161                    } catch (RemoteException e) {
6162                        // If the other end already died, then our work here is done.
6163                    }
6164                } else {
6165                    Slog.w(TAG, "Process/uid not found attempting kill of "
6166                            + processName + " / " + uid);
6167                }
6168            }
6169        } else {
6170            throw new SecurityException(callerUid + " cannot kill app process: " +
6171                    processName);
6172        }
6173    }
6174
6175    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6176        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6177                false, true, false, false, UserHandle.getUserId(uid), reason);
6178    }
6179
6180    private void finishForceStopPackageLocked(final String packageName, int uid) {
6181        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6182                Uri.fromParts("package", packageName, null));
6183        if (!mProcessesReady) {
6184            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6185                    | Intent.FLAG_RECEIVER_FOREGROUND);
6186        }
6187        intent.putExtra(Intent.EXTRA_UID, uid);
6188        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6189        broadcastIntentLocked(null, null, intent,
6190                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6191                null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
6192    }
6193
6194
6195    private final boolean killPackageProcessesLocked(String packageName, int appId,
6196            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6197            boolean doit, boolean evenPersistent, String reason) {
6198        ArrayList<ProcessRecord> procs = new ArrayList<>();
6199
6200        // Remove all processes this package may have touched: all with the
6201        // same UID (except for the system or root user), and all whose name
6202        // matches the package name.
6203        final int NP = mProcessNames.getMap().size();
6204        for (int ip=0; ip<NP; ip++) {
6205            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6206            final int NA = apps.size();
6207            for (int ia=0; ia<NA; ia++) {
6208                ProcessRecord app = apps.valueAt(ia);
6209                if (app.persistent && !evenPersistent) {
6210                    // we don't kill persistent processes
6211                    continue;
6212                }
6213                if (app.removed) {
6214                    if (doit) {
6215                        procs.add(app);
6216                    }
6217                    continue;
6218                }
6219
6220                // Skip process if it doesn't meet our oom adj requirement.
6221                if (app.setAdj < minOomAdj) {
6222                    continue;
6223                }
6224
6225                // If no package is specified, we call all processes under the
6226                // give user id.
6227                if (packageName == null) {
6228                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6229                        continue;
6230                    }
6231                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6232                        continue;
6233                    }
6234                // Package has been specified, we want to hit all processes
6235                // that match it.  We need to qualify this by the processes
6236                // that are running under the specified app and user ID.
6237                } else {
6238                    final boolean isDep = app.pkgDeps != null
6239                            && app.pkgDeps.contains(packageName);
6240                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6241                        continue;
6242                    }
6243                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
6244                        continue;
6245                    }
6246                    if (!app.pkgList.containsKey(packageName) && !isDep) {
6247                        continue;
6248                    }
6249                }
6250
6251                // Process has passed all conditions, kill it!
6252                if (!doit) {
6253                    return true;
6254                }
6255                app.removed = true;
6256                procs.add(app);
6257            }
6258        }
6259
6260        int N = procs.size();
6261        for (int i=0; i<N; i++) {
6262            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6263        }
6264        updateOomAdjLocked();
6265        return N > 0;
6266    }
6267
6268    private void cleanupDisabledPackageComponentsLocked(
6269            String packageName, int userId, boolean killProcess, String[] changedClasses) {
6270
6271        Set<String> disabledClasses = null;
6272        boolean packageDisabled = false;
6273        IPackageManager pm = AppGlobals.getPackageManager();
6274
6275        if (changedClasses == null) {
6276            // Nothing changed...
6277            return;
6278        }
6279
6280        // Determine enable/disable state of the package and its components.
6281        int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6282        for (int i = changedClasses.length - 1; i >= 0; i--) {
6283            final String changedClass = changedClasses[i];
6284
6285            if (changedClass.equals(packageName)) {
6286                try {
6287                    // Entire package setting changed
6288                    enabled = pm.getApplicationEnabledSetting(packageName,
6289                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6290                } catch (Exception e) {
6291                    // No such package/component; probably racing with uninstall.  In any
6292                    // event it means we have nothing further to do here.
6293                    return;
6294                }
6295                packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6296                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6297                if (packageDisabled) {
6298                    // Entire package is disabled.
6299                    // No need to continue to check component states.
6300                    disabledClasses = null;
6301                    break;
6302                }
6303            } else {
6304                try {
6305                    enabled = pm.getComponentEnabledSetting(
6306                            new ComponentName(packageName, changedClass),
6307                            (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6308                } catch (Exception e) {
6309                    // As above, probably racing with uninstall.
6310                    return;
6311                }
6312                if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6313                        && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6314                    if (disabledClasses == null) {
6315                        disabledClasses = new ArraySet<>(changedClasses.length);
6316                    }
6317                    disabledClasses.add(changedClass);
6318                }
6319            }
6320        }
6321
6322        if (!packageDisabled && disabledClasses == null) {
6323            // Nothing to do here...
6324            return;
6325        }
6326
6327        // Clean-up disabled activities.
6328        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6329                packageName, disabledClasses, true, false, userId) && mBooted) {
6330            mStackSupervisor.resumeFocusedStackTopActivityLocked();
6331            mStackSupervisor.scheduleIdleLocked();
6332        }
6333
6334        // Clean-up disabled tasks
6335        cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6336
6337        // Clean-up disabled services.
6338        mServices.bringDownDisabledPackageServicesLocked(
6339                packageName, disabledClasses, userId, false, killProcess, true);
6340
6341        // Clean-up disabled providers.
6342        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6343        mProviderMap.collectPackageProvidersLocked(
6344                packageName, disabledClasses, true, false, userId, providers);
6345        for (int i = providers.size() - 1; i >= 0; i--) {
6346            removeDyingProviderLocked(null, providers.get(i), true);
6347        }
6348
6349        // Clean-up disabled broadcast receivers.
6350        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6351            mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6352                    packageName, disabledClasses, userId, true);
6353        }
6354
6355    }
6356
6357    final boolean clearBroadcastQueueForUserLocked(int userId) {
6358        boolean didSomething = false;
6359        for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6360            didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6361                    null, null, userId, true);
6362        }
6363        return didSomething;
6364    }
6365
6366    final boolean forceStopPackageLocked(String packageName, int appId,
6367            boolean callerWillRestart, boolean purgeCache, boolean doit,
6368            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6369        int i;
6370
6371        if (userId == UserHandle.USER_ALL && packageName == null) {
6372            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6373        }
6374
6375        if (appId < 0 && packageName != null) {
6376            try {
6377                appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6378                        .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6379            } catch (RemoteException e) {
6380            }
6381        }
6382
6383        if (doit) {
6384            if (packageName != null) {
6385                Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6386                        + " user=" + userId + ": " + reason);
6387            } else {
6388                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6389            }
6390
6391            mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6392        }
6393
6394        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6395                ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6396                packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6397
6398        didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6399
6400        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6401                packageName, null, doit, evenPersistent, userId)) {
6402            if (!doit) {
6403                return true;
6404            }
6405            didSomething = true;
6406        }
6407
6408        if (mServices.bringDownDisabledPackageServicesLocked(
6409                packageName, null, userId, evenPersistent, true, doit)) {
6410            if (!doit) {
6411                return true;
6412            }
6413            didSomething = true;
6414        }
6415
6416        if (packageName == null) {
6417            // Remove all sticky broadcasts from this user.
6418            mStickyBroadcasts.remove(userId);
6419        }
6420
6421        ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6422        if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6423                userId, providers)) {
6424            if (!doit) {
6425                return true;
6426            }
6427            didSomething = true;
6428        }
6429        for (i = providers.size() - 1; i >= 0; i--) {
6430            removeDyingProviderLocked(null, providers.get(i), true);
6431        }
6432
6433        // Remove transient permissions granted from/to this package/user
6434        removeUriPermissionsForPackageLocked(packageName, userId, false);
6435
6436        if (doit) {
6437            for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6438                didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6439                        packageName, null, userId, doit);
6440            }
6441        }
6442
6443        if (packageName == null || uninstalling) {
6444            // Remove pending intents.  For now we only do this when force
6445            // stopping users, because we have some problems when doing this
6446            // for packages -- app widgets are not currently cleaned up for
6447            // such packages, so they can be left with bad pending intents.
6448            if (mIntentSenderRecords.size() > 0) {
6449                Iterator<WeakReference<PendingIntentRecord>> it
6450                        = mIntentSenderRecords.values().iterator();
6451                while (it.hasNext()) {
6452                    WeakReference<PendingIntentRecord> wpir = it.next();
6453                    if (wpir == null) {
6454                        it.remove();
6455                        continue;
6456                    }
6457                    PendingIntentRecord pir = wpir.get();
6458                    if (pir == null) {
6459                        it.remove();
6460                        continue;
6461                    }
6462                    if (packageName == null) {
6463                        // Stopping user, remove all objects for the user.
6464                        if (pir.key.userId != userId) {
6465                            // Not the same user, skip it.
6466                            continue;
6467                        }
6468                    } else {
6469                        if (UserHandle.getAppId(pir.uid) != appId) {
6470                            // Different app id, skip it.
6471                            continue;
6472                        }
6473                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6474                            // Different user, skip it.
6475                            continue;
6476                        }
6477                        if (!pir.key.packageName.equals(packageName)) {
6478                            // Different package, skip it.
6479                            continue;
6480                        }
6481                    }
6482                    if (!doit) {
6483                        return true;
6484                    }
6485                    didSomething = true;
6486                    it.remove();
6487                    pir.canceled = true;
6488                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6489                        pir.key.activity.pendingResults.remove(pir.ref);
6490                    }
6491                }
6492            }
6493        }
6494
6495        if (doit) {
6496            if (purgeCache && packageName != null) {
6497                AttributeCache ac = AttributeCache.instance();
6498                if (ac != null) {
6499                    ac.removePackage(packageName);
6500                }
6501            }
6502            if (mBooted) {
6503                mStackSupervisor.resumeFocusedStackTopActivityLocked();
6504                mStackSupervisor.scheduleIdleLocked();
6505            }
6506        }
6507
6508        return didSomething;
6509    }
6510
6511    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6512        return removeProcessNameLocked(name, uid, null);
6513    }
6514
6515    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6516            final ProcessRecord expecting) {
6517        ProcessRecord old = mProcessNames.get(name, uid);
6518        // Only actually remove when the currently recorded value matches the
6519        // record that we expected; if it doesn't match then we raced with a
6520        // newly created process and we don't want to destroy the new one.
6521        if ((expecting == null) || (old == expecting)) {
6522            mProcessNames.remove(name, uid);
6523        }
6524        if (old != null && old.uidRecord != null) {
6525            old.uidRecord.numProcs--;
6526            if (old.uidRecord.numProcs == 0) {
6527                // No more processes using this uid, tell clients it is gone.
6528                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6529                        "No more processes in " + old.uidRecord);
6530                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6531                mActiveUids.remove(uid);
6532                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6533            }
6534            old.uidRecord = null;
6535        }
6536        mIsolatedProcesses.remove(uid);
6537        return old;
6538    }
6539
6540    private final void addProcessNameLocked(ProcessRecord proc) {
6541        // We shouldn't already have a process under this name, but just in case we
6542        // need to clean up whatever may be there now.
6543        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6544        if (old == proc && proc.persistent) {
6545            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6546            Slog.w(TAG, "Re-adding persistent process " + proc);
6547        } else if (old != null) {
6548            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6549        }
6550        UidRecord uidRec = mActiveUids.get(proc.uid);
6551        if (uidRec == null) {
6552            uidRec = new UidRecord(proc.uid);
6553            // This is the first appearance of the uid, report it now!
6554            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6555                    "Creating new process uid: " + uidRec);
6556            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0) {
6557                uidRec.setWhitelist = uidRec.curWhitelist = true;
6558            }
6559            mActiveUids.put(proc.uid, uidRec);
6560            noteUidProcessState(uidRec.uid, uidRec.curProcState);
6561            enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6562        }
6563        proc.uidRecord = uidRec;
6564
6565        // Reset render thread tid if it was already set, so new process can set it again.
6566        proc.renderThreadTid = 0;
6567        uidRec.numProcs++;
6568        mProcessNames.put(proc.processName, proc.uid, proc);
6569        if (proc.isolated) {
6570            mIsolatedProcesses.put(proc.uid, proc);
6571        }
6572    }
6573
6574    boolean removeProcessLocked(ProcessRecord app,
6575            boolean callerWillRestart, boolean allowRestart, String reason) {
6576        final String name = app.processName;
6577        final int uid = app.uid;
6578        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6579            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6580
6581        ProcessRecord old = mProcessNames.get(name, uid);
6582        if (old != app) {
6583            // This process is no longer active, so nothing to do.
6584            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6585            return false;
6586        }
6587        removeProcessNameLocked(name, uid);
6588        if (mHeavyWeightProcess == app) {
6589            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6590                    mHeavyWeightProcess.userId, 0));
6591            mHeavyWeightProcess = null;
6592        }
6593        boolean needRestart = false;
6594        if (app.pid > 0 && app.pid != MY_PID) {
6595            int pid = app.pid;
6596            synchronized (mPidsSelfLocked) {
6597                mPidsSelfLocked.remove(pid);
6598                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6599            }
6600            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6601            if (app.isolated) {
6602                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6603            }
6604            boolean willRestart = false;
6605            if (app.persistent && !app.isolated) {
6606                if (!callerWillRestart) {
6607                    willRestart = true;
6608                } else {
6609                    needRestart = true;
6610                }
6611            }
6612            app.kill(reason, true);
6613            handleAppDiedLocked(app, willRestart, allowRestart);
6614            if (willRestart) {
6615                removeLruProcessLocked(app);
6616                addAppLocked(app.info, null, false, null /* ABI override */);
6617            }
6618        } else {
6619            mRemovedProcesses.add(app);
6620        }
6621
6622        return needRestart;
6623    }
6624
6625    private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6626        cleanupAppInLaunchingProvidersLocked(app, true);
6627        removeProcessLocked(app, false, true, "timeout publishing content providers");
6628    }
6629
6630    private final void processStartTimedOutLocked(ProcessRecord app) {
6631        final int pid = app.pid;
6632        boolean gone = false;
6633        synchronized (mPidsSelfLocked) {
6634            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6635            if (knownApp != null && knownApp.thread == null) {
6636                mPidsSelfLocked.remove(pid);
6637                gone = true;
6638            }
6639        }
6640
6641        if (gone) {
6642            Slog.w(TAG, "Process " + app + " failed to attach");
6643            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6644                    pid, app.uid, app.processName);
6645            removeProcessNameLocked(app.processName, app.uid);
6646            if (mHeavyWeightProcess == app) {
6647                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6648                        mHeavyWeightProcess.userId, 0));
6649                mHeavyWeightProcess = null;
6650            }
6651            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6652            if (app.isolated) {
6653                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6654            }
6655            // Take care of any launching providers waiting for this process.
6656            cleanupAppInLaunchingProvidersLocked(app, true);
6657            // Take care of any services that are waiting for the process.
6658            mServices.processStartTimedOutLocked(app);
6659            app.kill("start timeout", true);
6660            removeLruProcessLocked(app);
6661            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6662                Slog.w(TAG, "Unattached app died before backup, skipping");
6663                mHandler.post(new Runnable() {
6664                @Override
6665                    public void run(){
6666                        try {
6667                            IBackupManager bm = IBackupManager.Stub.asInterface(
6668                                    ServiceManager.getService(Context.BACKUP_SERVICE));
6669                            bm.agentDisconnected(app.info.packageName);
6670                        } catch (RemoteException e) {
6671                            // Can't happen; the backup manager is local
6672                        }
6673                    }
6674                });
6675            }
6676            if (isPendingBroadcastProcessLocked(pid)) {
6677                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6678                skipPendingBroadcastLocked(pid);
6679            }
6680        } else {
6681            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6682        }
6683    }
6684
6685    private final boolean attachApplicationLocked(IApplicationThread thread,
6686            int pid) {
6687
6688        // Find the application record that is being attached...  either via
6689        // the pid if we are running in multiple processes, or just pull the
6690        // next app record if we are emulating process with anonymous threads.
6691        ProcessRecord app;
6692        long startTime = SystemClock.uptimeMillis();
6693        if (pid != MY_PID && pid >= 0) {
6694            synchronized (mPidsSelfLocked) {
6695                app = mPidsSelfLocked.get(pid);
6696            }
6697        } else {
6698            app = null;
6699        }
6700
6701        if (app == null) {
6702            Slog.w(TAG, "No pending application record for pid " + pid
6703                    + " (IApplicationThread " + thread + "); dropping process");
6704            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6705            if (pid > 0 && pid != MY_PID) {
6706                Process.killProcessQuiet(pid);
6707                //TODO: killProcessGroup(app.info.uid, pid);
6708            } else {
6709                try {
6710                    thread.scheduleExit();
6711                } catch (Exception e) {
6712                    // Ignore exceptions.
6713                }
6714            }
6715            return false;
6716        }
6717
6718        // If this application record is still attached to a previous
6719        // process, clean it up now.
6720        if (app.thread != null) {
6721            handleAppDiedLocked(app, true, true);
6722        }
6723
6724        // Tell the process all about itself.
6725
6726        if (DEBUG_ALL) Slog.v(
6727                TAG, "Binding process pid " + pid + " to record " + app);
6728
6729        final String processName = app.processName;
6730        try {
6731            AppDeathRecipient adr = new AppDeathRecipient(
6732                    app, pid, thread);
6733            thread.asBinder().linkToDeath(adr, 0);
6734            app.deathRecipient = adr;
6735        } catch (RemoteException e) {
6736            app.resetPackageList(mProcessStats);
6737            startProcessLocked(app, "link fail", processName);
6738            return false;
6739        }
6740
6741        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6742
6743        app.makeActive(thread, mProcessStats);
6744        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6745        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6746        app.forcingToForeground = null;
6747        updateProcessForegroundLocked(app, false, false);
6748        app.hasShownUi = false;
6749        app.debugging = false;
6750        app.cached = false;
6751        app.killedByAm = false;
6752        app.killed = false;
6753
6754
6755        // We carefully use the same state that PackageManager uses for
6756        // filtering, since we use this flag to decide if we need to install
6757        // providers when user is unlocked later
6758        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6759
6760        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6761
6762        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6763        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6764
6765        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6766            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6767            msg.obj = app;
6768            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6769        }
6770
6771        checkTime(startTime, "attachApplicationLocked: before bindApplication");
6772
6773        if (!normalMode) {
6774            Slog.i(TAG, "Launching preboot mode app: " + app);
6775        }
6776
6777        if (DEBUG_ALL) Slog.v(
6778            TAG, "New app record " + app
6779            + " thread=" + thread.asBinder() + " pid=" + pid);
6780        try {
6781            int testMode = ApplicationThreadConstants.DEBUG_OFF;
6782            if (mDebugApp != null && mDebugApp.equals(processName)) {
6783                testMode = mWaitForDebugger
6784                    ? ApplicationThreadConstants.DEBUG_WAIT
6785                    : ApplicationThreadConstants.DEBUG_ON;
6786                app.debugging = true;
6787                if (mDebugTransient) {
6788                    mDebugApp = mOrigDebugApp;
6789                    mWaitForDebugger = mOrigWaitForDebugger;
6790                }
6791            }
6792            String profileFile = app.instr != null ? app.instr.mProfileFile : null;
6793            ParcelFileDescriptor profileFd = null;
6794            int samplingInterval = 0;
6795            boolean profileAutoStop = false;
6796            boolean profileStreamingOutput = false;
6797            if (mProfileApp != null && mProfileApp.equals(processName)) {
6798                mProfileProc = app;
6799                profileFile = mProfileFile;
6800                profileFd = mProfileFd;
6801                samplingInterval = mSamplingInterval;
6802                profileAutoStop = mAutoStopProfiler;
6803                profileStreamingOutput = mStreamingOutput;
6804            }
6805            boolean enableTrackAllocation = false;
6806            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6807                enableTrackAllocation = true;
6808                mTrackAllocationApp = null;
6809            }
6810
6811            // If the app is being launched for restore or full backup, set it up specially
6812            boolean isRestrictedBackupMode = false;
6813            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6814                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6815                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6816                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6817                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6818            }
6819
6820            if (app.instr != null) {
6821                notifyPackageUse(app.instr.mClass.getPackageName(),
6822                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6823            }
6824            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6825                    + processName + " with config " + getGlobalConfiguration());
6826            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
6827            app.compat = compatibilityInfoForPackageLocked(appInfo);
6828            if (profileFd != null) {
6829                profileFd = profileFd.dup();
6830            }
6831            ProfilerInfo profilerInfo = profileFile == null ? null
6832                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop,
6833                                       profileStreamingOutput);
6834
6835            // We deprecated Build.SERIAL and it is not accessible to
6836            // apps that target the v2 security sandbox. Since access to
6837            // the serial is now behind a permission we push down the value.
6838            String buildSerial = Build.UNKNOWN;
6839            if (appInfo.targetSandboxVersion != 2) {
6840                buildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
6841                        ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
6842                        .getSerial();
6843            }
6844
6845            // Check if this is a secondary process that should be incorporated into some
6846            // currently active instrumentation.  (Note we do this AFTER all of the profiling
6847            // stuff above because profiling can currently happen only in the primary
6848            // instrumentation process.)
6849            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
6850                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
6851                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
6852                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
6853                        if (aInstr.mTargetProcesses.length == 0) {
6854                            // This is the wildcard mode, where every process brought up for
6855                            // the target instrumentation should be included.
6856                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
6857                                app.instr = aInstr;
6858                                aInstr.mRunningProcesses.add(app);
6859                            }
6860                        } else {
6861                            for (String proc : aInstr.mTargetProcesses) {
6862                                if (proc.equals(app.processName)) {
6863                                    app.instr = aInstr;
6864                                    aInstr.mRunningProcesses.add(app);
6865                                    break;
6866                                }
6867                            }
6868                        }
6869                    }
6870                }
6871            }
6872
6873            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6874            if (app.instr != null) {
6875                thread.bindApplication(processName, appInfo, providers,
6876                        app.instr.mClass,
6877                        profilerInfo, app.instr.mArguments,
6878                        app.instr.mWatcher,
6879                        app.instr.mUiAutomationConnection, testMode,
6880                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6881                        isRestrictedBackupMode || !normalMode, app.persistent,
6882                        new Configuration(getGlobalConfiguration()), app.compat,
6883                        getCommonServicesLocked(app.isolated),
6884                        mCoreSettingsObserver.getCoreSettingsLocked(),
6885                        buildSerial);
6886            } else {
6887                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
6888                        null, null, null, testMode,
6889                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
6890                        isRestrictedBackupMode || !normalMode, app.persistent,
6891                        new Configuration(getGlobalConfiguration()), app.compat,
6892                        getCommonServicesLocked(app.isolated),
6893                        mCoreSettingsObserver.getCoreSettingsLocked(),
6894                        buildSerial);
6895            }
6896
6897            checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6898            updateLruProcessLocked(app, false, null);
6899            checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6900            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6901        } catch (Exception e) {
6902            // todo: Yikes!  What should we do?  For now we will try to
6903            // start another process, but that could easily get us in
6904            // an infinite loop of restarting processes...
6905            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6906
6907            app.resetPackageList(mProcessStats);
6908            app.unlinkDeathRecipient();
6909            startProcessLocked(app, "bind fail", processName);
6910            return false;
6911        }
6912
6913        // Remove this record from the list of starting applications.
6914        mPersistentStartingProcesses.remove(app);
6915        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6916                "Attach application locked removing on hold: " + app);
6917        mProcessesOnHold.remove(app);
6918
6919        boolean badApp = false;
6920        boolean didSomething = false;
6921
6922        // See if the top visible activity is waiting to run in this process...
6923        if (normalMode) {
6924            try {
6925                if (mStackSupervisor.attachApplicationLocked(app)) {
6926                    didSomething = true;
6927                }
6928            } catch (Exception e) {
6929                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6930                badApp = true;
6931            }
6932        }
6933
6934        // Find any services that should be running in this process...
6935        if (!badApp) {
6936            try {
6937                didSomething |= mServices.attachApplicationLocked(app, processName);
6938                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6939            } catch (Exception e) {
6940                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6941                badApp = true;
6942            }
6943        }
6944
6945        // Check if a next-broadcast receiver is in this process...
6946        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6947            try {
6948                didSomething |= sendPendingBroadcastsLocked(app);
6949                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6950            } catch (Exception e) {
6951                // If the app died trying to launch the receiver we declare it 'bad'
6952                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6953                badApp = true;
6954            }
6955        }
6956
6957        // Check whether the next backup agent is in this process...
6958        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6959            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6960                    "New app is backup target, launching agent for " + app);
6961            notifyPackageUse(mBackupTarget.appInfo.packageName,
6962                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6963            try {
6964                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6965                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6966                        mBackupTarget.backupMode);
6967            } catch (Exception e) {
6968                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6969                badApp = true;
6970            }
6971        }
6972
6973        if (badApp) {
6974            app.kill("error during init", true);
6975            handleAppDiedLocked(app, false, true);
6976            return false;
6977        }
6978
6979        if (!didSomething) {
6980            updateOomAdjLocked();
6981            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6982        }
6983
6984        return true;
6985    }
6986
6987    @Override
6988    public final void attachApplication(IApplicationThread thread) {
6989        synchronized (this) {
6990            int callingPid = Binder.getCallingPid();
6991            final long origId = Binder.clearCallingIdentity();
6992            attachApplicationLocked(thread, callingPid);
6993            Binder.restoreCallingIdentity(origId);
6994        }
6995    }
6996
6997    @Override
6998    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6999        final long origId = Binder.clearCallingIdentity();
7000        synchronized (this) {
7001            ActivityStack stack = ActivityRecord.getStackLocked(token);
7002            if (stack != null) {
7003                ActivityRecord r =
7004                        mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7005                                false /* processPausingActivities */, config);
7006                if (stopProfiling) {
7007                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
7008                        try {
7009                            mProfileFd.close();
7010                        } catch (IOException e) {
7011                        }
7012                        clearProfilerLocked();
7013                    }
7014                }
7015            }
7016        }
7017        Binder.restoreCallingIdentity(origId);
7018    }
7019
7020    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7021        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7022                finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7023    }
7024
7025    void enableScreenAfterBoot() {
7026        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7027                SystemClock.uptimeMillis());
7028        mWindowManager.enableScreenAfterBoot();
7029
7030        synchronized (this) {
7031            updateEventDispatchingLocked();
7032        }
7033    }
7034
7035    @Override
7036    public void showBootMessage(final CharSequence msg, final boolean always) {
7037        if (Binder.getCallingUid() != Process.myUid()) {
7038            throw new SecurityException();
7039        }
7040        mWindowManager.showBootMessage(msg, always);
7041    }
7042
7043    @Override
7044    public void keyguardGoingAway(int flags) {
7045        enforceNotIsolatedCaller("keyguardGoingAway");
7046        final long token = Binder.clearCallingIdentity();
7047        try {
7048            synchronized (this) {
7049                mKeyguardController.keyguardGoingAway(flags);
7050            }
7051        } finally {
7052            Binder.restoreCallingIdentity(token);
7053        }
7054    }
7055
7056    /**
7057     * @return whther the keyguard is currently locked.
7058     */
7059    boolean isKeyguardLocked() {
7060        return mKeyguardController.isKeyguardLocked();
7061    }
7062
7063    final void finishBooting() {
7064        synchronized (this) {
7065            if (!mBootAnimationComplete) {
7066                mCallFinishBooting = true;
7067                return;
7068            }
7069            mCallFinishBooting = false;
7070        }
7071
7072        ArraySet<String> completedIsas = new ArraySet<String>();
7073        for (String abi : Build.SUPPORTED_ABIS) {
7074            Process.zygoteProcess.establishZygoteConnectionForAbi(abi);
7075            final String instructionSet = VMRuntime.getInstructionSet(abi);
7076            if (!completedIsas.contains(instructionSet)) {
7077                try {
7078                    mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7079                } catch (InstallerException e) {
7080                    Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7081                            e.getMessage() +")");
7082                }
7083                completedIsas.add(instructionSet);
7084            }
7085        }
7086
7087        IntentFilter pkgFilter = new IntentFilter();
7088        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7089        pkgFilter.addDataScheme("package");
7090        mContext.registerReceiver(new BroadcastReceiver() {
7091            @Override
7092            public void onReceive(Context context, Intent intent) {
7093                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7094                if (pkgs != null) {
7095                    for (String pkg : pkgs) {
7096                        synchronized (ActivityManagerService.this) {
7097                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7098                                    0, "query restart")) {
7099                                setResultCode(Activity.RESULT_OK);
7100                                return;
7101                            }
7102                        }
7103                    }
7104                }
7105            }
7106        }, pkgFilter);
7107
7108        IntentFilter dumpheapFilter = new IntentFilter();
7109        dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7110        mContext.registerReceiver(new BroadcastReceiver() {
7111            @Override
7112            public void onReceive(Context context, Intent intent) {
7113                if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7114                    mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7115                } else {
7116                    mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7117                }
7118            }
7119        }, dumpheapFilter);
7120
7121        // Let system services know.
7122        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7123
7124        synchronized (this) {
7125            // Ensure that any processes we had put on hold are now started
7126            // up.
7127            final int NP = mProcessesOnHold.size();
7128            if (NP > 0) {
7129                ArrayList<ProcessRecord> procs =
7130                    new ArrayList<ProcessRecord>(mProcessesOnHold);
7131                for (int ip=0; ip<NP; ip++) {
7132                    if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7133                            + procs.get(ip));
7134                    startProcessLocked(procs.get(ip), "on-hold", null);
7135                }
7136            }
7137
7138            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7139                // Start looking for apps that are abusing wake locks.
7140                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7141                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7142                // Tell anyone interested that we are done booting!
7143                SystemProperties.set("sys.boot_completed", "1");
7144
7145                // And trigger dev.bootcomplete if we are not showing encryption progress
7146                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7147                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7148                    SystemProperties.set("dev.bootcomplete", "1");
7149                }
7150                mUserController.sendBootCompletedLocked(
7151                        new IIntentReceiver.Stub() {
7152                            @Override
7153                            public void performReceive(Intent intent, int resultCode,
7154                                    String data, Bundle extras, boolean ordered,
7155                                    boolean sticky, int sendingUser) {
7156                                synchronized (ActivityManagerService.this) {
7157                                    requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7158                                            true, false);
7159                                }
7160                            }
7161                        });
7162                scheduleStartProfilesLocked();
7163            }
7164        }
7165    }
7166
7167    @Override
7168    public void bootAnimationComplete() {
7169        final boolean callFinishBooting;
7170        synchronized (this) {
7171            callFinishBooting = mCallFinishBooting;
7172            mBootAnimationComplete = true;
7173        }
7174        if (callFinishBooting) {
7175            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7176            finishBooting();
7177            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7178        }
7179    }
7180
7181    final void ensureBootCompleted() {
7182        boolean booting;
7183        boolean enableScreen;
7184        synchronized (this) {
7185            booting = mBooting;
7186            mBooting = false;
7187            enableScreen = !mBooted;
7188            mBooted = true;
7189        }
7190
7191        if (booting) {
7192            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7193            finishBooting();
7194            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7195        }
7196
7197        if (enableScreen) {
7198            enableScreenAfterBoot();
7199        }
7200    }
7201
7202    @Override
7203    public final void activityResumed(IBinder token) {
7204        final long origId = Binder.clearCallingIdentity();
7205        synchronized(this) {
7206            ActivityRecord.activityResumedLocked(token);
7207            mWindowManager.notifyAppResumedFinished(token);
7208        }
7209        Binder.restoreCallingIdentity(origId);
7210    }
7211
7212    @Override
7213    public final void activityPaused(IBinder token) {
7214        final long origId = Binder.clearCallingIdentity();
7215        synchronized(this) {
7216            ActivityStack stack = ActivityRecord.getStackLocked(token);
7217            if (stack != null) {
7218                stack.activityPausedLocked(token, false);
7219            }
7220        }
7221        Binder.restoreCallingIdentity(origId);
7222    }
7223
7224    @Override
7225    public final void activityStopped(IBinder token, Bundle icicle,
7226            PersistableBundle persistentState, CharSequence description) {
7227        if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7228
7229        // Refuse possible leaked file descriptors
7230        if (icicle != null && icicle.hasFileDescriptors()) {
7231            throw new IllegalArgumentException("File descriptors passed in Bundle");
7232        }
7233
7234        final long origId = Binder.clearCallingIdentity();
7235
7236        synchronized (this) {
7237            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7238            if (r != null) {
7239                r.activityStoppedLocked(icicle, persistentState, description);
7240            }
7241        }
7242
7243        trimApplications();
7244
7245        Binder.restoreCallingIdentity(origId);
7246    }
7247
7248    @Override
7249    public final void activityDestroyed(IBinder token) {
7250        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7251        synchronized (this) {
7252            ActivityStack stack = ActivityRecord.getStackLocked(token);
7253            if (stack != null) {
7254                stack.activityDestroyedLocked(token, "activityDestroyed");
7255            }
7256        }
7257    }
7258
7259    @Override
7260    public final void activityRelaunched(IBinder token) {
7261        final long origId = Binder.clearCallingIdentity();
7262        synchronized (this) {
7263            mStackSupervisor.activityRelaunchedLocked(token);
7264        }
7265        Binder.restoreCallingIdentity(origId);
7266    }
7267
7268    @Override
7269    public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7270            int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7271        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7272                + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7273        synchronized (this) {
7274            ActivityRecord record = ActivityRecord.isInStackLocked(token);
7275            if (record == null) {
7276                throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7277                        + "found for: " + token);
7278            }
7279            record.setSizeConfigurations(horizontalSizeConfiguration,
7280                    verticalSizeConfigurations, smallestSizeConfigurations);
7281        }
7282    }
7283
7284    @Override
7285    public final void backgroundResourcesReleased(IBinder token) {
7286        final long origId = Binder.clearCallingIdentity();
7287        try {
7288            synchronized (this) {
7289                ActivityStack stack = ActivityRecord.getStackLocked(token);
7290                if (stack != null) {
7291                    stack.backgroundResourcesReleased();
7292                }
7293            }
7294        } finally {
7295            Binder.restoreCallingIdentity(origId);
7296        }
7297    }
7298
7299    @Override
7300    public final void notifyLaunchTaskBehindComplete(IBinder token) {
7301        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7302    }
7303
7304    @Override
7305    public final void notifyEnterAnimationComplete(IBinder token) {
7306        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7307    }
7308
7309    @Override
7310    public String getCallingPackage(IBinder token) {
7311        synchronized (this) {
7312            ActivityRecord r = getCallingRecordLocked(token);
7313            return r != null ? r.info.packageName : null;
7314        }
7315    }
7316
7317    @Override
7318    public ComponentName getCallingActivity(IBinder token) {
7319        synchronized (this) {
7320            ActivityRecord r = getCallingRecordLocked(token);
7321            return r != null ? r.intent.getComponent() : null;
7322        }
7323    }
7324
7325    private ActivityRecord getCallingRecordLocked(IBinder token) {
7326        ActivityRecord r = ActivityRecord.isInStackLocked(token);
7327        if (r == null) {
7328            return null;
7329        }
7330        return r.resultTo;
7331    }
7332
7333    @Override
7334    public ComponentName getActivityClassForToken(IBinder token) {
7335        synchronized(this) {
7336            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7337            if (r == null) {
7338                return null;
7339            }
7340            return r.intent.getComponent();
7341        }
7342    }
7343
7344    @Override
7345    public String getPackageForToken(IBinder token) {
7346        synchronized(this) {
7347            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7348            if (r == null) {
7349                return null;
7350            }
7351            return r.packageName;
7352        }
7353    }
7354
7355    @Override
7356    public boolean isRootVoiceInteraction(IBinder token) {
7357        synchronized(this) {
7358            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7359            if (r == null) {
7360                return false;
7361            }
7362            return r.rootVoiceInteraction;
7363        }
7364    }
7365
7366    @Override
7367    public IIntentSender getIntentSender(int type,
7368            String packageName, IBinder token, String resultWho,
7369            int requestCode, Intent[] intents, String[] resolvedTypes,
7370            int flags, Bundle bOptions, int userId) {
7371        enforceNotIsolatedCaller("getIntentSender");
7372        // Refuse possible leaked file descriptors
7373        if (intents != null) {
7374            if (intents.length < 1) {
7375                throw new IllegalArgumentException("Intents array length must be >= 1");
7376            }
7377            for (int i=0; i<intents.length; i++) {
7378                Intent intent = intents[i];
7379                if (intent != null) {
7380                    if (intent.hasFileDescriptors()) {
7381                        throw new IllegalArgumentException("File descriptors passed in Intent");
7382                    }
7383                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7384                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7385                        throw new IllegalArgumentException(
7386                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7387                    }
7388                    intents[i] = new Intent(intent);
7389                }
7390            }
7391            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7392                throw new IllegalArgumentException(
7393                        "Intent array length does not match resolvedTypes length");
7394            }
7395        }
7396        if (bOptions != null) {
7397            if (bOptions.hasFileDescriptors()) {
7398                throw new IllegalArgumentException("File descriptors passed in options");
7399            }
7400        }
7401
7402        synchronized(this) {
7403            int callingUid = Binder.getCallingUid();
7404            int origUserId = userId;
7405            userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7406                    type == ActivityManager.INTENT_SENDER_BROADCAST,
7407                    ALLOW_NON_FULL, "getIntentSender", null);
7408            if (origUserId == UserHandle.USER_CURRENT) {
7409                // We don't want to evaluate this until the pending intent is
7410                // actually executed.  However, we do want to always do the
7411                // security checking for it above.
7412                userId = UserHandle.USER_CURRENT;
7413            }
7414            try {
7415                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7416                    final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7417                            MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7418                    if (!UserHandle.isSameApp(callingUid, uid)) {
7419                        String msg = "Permission Denial: getIntentSender() from pid="
7420                            + Binder.getCallingPid()
7421                            + ", uid=" + Binder.getCallingUid()
7422                            + ", (need uid=" + uid + ")"
7423                            + " is not allowed to send as package " + packageName;
7424                        Slog.w(TAG, msg);
7425                        throw new SecurityException(msg);
7426                    }
7427                }
7428
7429                return getIntentSenderLocked(type, packageName, callingUid, userId,
7430                        token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7431
7432            } catch (RemoteException e) {
7433                throw new SecurityException(e);
7434            }
7435        }
7436    }
7437
7438    IIntentSender getIntentSenderLocked(int type, String packageName,
7439            int callingUid, int userId, IBinder token, String resultWho,
7440            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7441            Bundle bOptions) {
7442        if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7443        ActivityRecord activity = null;
7444        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7445            activity = ActivityRecord.isInStackLocked(token);
7446            if (activity == null) {
7447                Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7448                return null;
7449            }
7450            if (activity.finishing) {
7451                Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7452                return null;
7453            }
7454        }
7455
7456        // We're going to be splicing together extras before sending, so we're
7457        // okay poking into any contained extras.
7458        if (intents != null) {
7459            for (int i = 0; i < intents.length; i++) {
7460                intents[i].setDefusable(true);
7461            }
7462        }
7463        Bundle.setDefusable(bOptions, true);
7464
7465        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7466        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7467        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7468        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7469                |PendingIntent.FLAG_UPDATE_CURRENT);
7470
7471        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7472                type, packageName, activity, resultWho,
7473                requestCode, intents, resolvedTypes, flags, bOptions, userId);
7474        WeakReference<PendingIntentRecord> ref;
7475        ref = mIntentSenderRecords.get(key);
7476        PendingIntentRecord rec = ref != null ? ref.get() : null;
7477        if (rec != null) {
7478            if (!cancelCurrent) {
7479                if (updateCurrent) {
7480                    if (rec.key.requestIntent != null) {
7481                        rec.key.requestIntent.replaceExtras(intents != null ?
7482                                intents[intents.length - 1] : null);
7483                    }
7484                    if (intents != null) {
7485                        intents[intents.length-1] = rec.key.requestIntent;
7486                        rec.key.allIntents = intents;
7487                        rec.key.allResolvedTypes = resolvedTypes;
7488                    } else {
7489                        rec.key.allIntents = null;
7490                        rec.key.allResolvedTypes = null;
7491                    }
7492                }
7493                return rec;
7494            }
7495            rec.canceled = true;
7496            mIntentSenderRecords.remove(key);
7497        }
7498        if (noCreate) {
7499            return rec;
7500        }
7501        rec = new PendingIntentRecord(this, key, callingUid);
7502        mIntentSenderRecords.put(key, rec.ref);
7503        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7504            if (activity.pendingResults == null) {
7505                activity.pendingResults
7506                        = new HashSet<WeakReference<PendingIntentRecord>>();
7507            }
7508            activity.pendingResults.add(rec.ref);
7509        }
7510        return rec;
7511    }
7512
7513    @Override
7514    public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7515            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7516        if (target instanceof PendingIntentRecord) {
7517            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7518                    finishedReceiver, requiredPermission, options);
7519        } else {
7520            if (intent == null) {
7521                // Weird case: someone has given us their own custom IIntentSender, and now
7522                // they have someone else trying to send to it but of course this isn't
7523                // really a PendingIntent, so there is no base Intent, and the caller isn't
7524                // supplying an Intent... but we never want to dispatch a null Intent to
7525                // a receiver, so um...  let's make something up.
7526                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7527                intent = new Intent(Intent.ACTION_MAIN);
7528            }
7529            try {
7530                target.send(code, intent, resolvedType, null, requiredPermission, options);
7531            } catch (RemoteException e) {
7532            }
7533            // Platform code can rely on getting a result back when the send is done, but if
7534            // this intent sender is from outside of the system we can't rely on it doing that.
7535            // So instead we don't give it the result receiver, and instead just directly
7536            // report the finish immediately.
7537            if (finishedReceiver != null) {
7538                try {
7539                    finishedReceiver.performReceive(intent, 0,
7540                            null, null, false, false, UserHandle.getCallingUserId());
7541                } catch (RemoteException e) {
7542                }
7543            }
7544            return 0;
7545        }
7546    }
7547
7548    /**
7549     * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7550     */
7551    void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7552        if (DEBUG_WHITELISTS) {
7553            Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7554                    + targetUid + ", " + duration + ")");
7555        }
7556
7557        if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
7558                != PackageManager.PERMISSION_GRANTED) {
7559            synchronized (mPidsSelfLocked) {
7560                final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7561                if (pr == null) {
7562                    Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid "
7563                            + callerPid);
7564                    return;
7565                }
7566                if (!pr.whitelistManager) {
7567                    if (DEBUG_WHITELISTS) {
7568                        Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid
7569                                + ": pid " + callerPid + " is not allowed");
7570                    }
7571                    return;
7572                }
7573            }
7574        }
7575
7576        final long token = Binder.clearCallingIdentity();
7577        try {
7578            mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7579                    true, "pe from uid:" + callerUid);
7580        } finally {
7581            Binder.restoreCallingIdentity(token);
7582        }
7583    }
7584
7585    @Override
7586    public void cancelIntentSender(IIntentSender sender) {
7587        if (!(sender instanceof PendingIntentRecord)) {
7588            return;
7589        }
7590        synchronized(this) {
7591            PendingIntentRecord rec = (PendingIntentRecord)sender;
7592            try {
7593                final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7594                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7595                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7596                    String msg = "Permission Denial: cancelIntentSender() from pid="
7597                        + Binder.getCallingPid()
7598                        + ", uid=" + Binder.getCallingUid()
7599                        + " is not allowed to cancel packges "
7600                        + rec.key.packageName;
7601                    Slog.w(TAG, msg);
7602                    throw new SecurityException(msg);
7603                }
7604            } catch (RemoteException e) {
7605                throw new SecurityException(e);
7606            }
7607            cancelIntentSenderLocked(rec, true);
7608        }
7609    }
7610
7611    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7612        rec.canceled = true;
7613        mIntentSenderRecords.remove(rec.key);
7614        if (cleanActivity && rec.key.activity != null) {
7615            rec.key.activity.pendingResults.remove(rec.ref);
7616        }
7617    }
7618
7619    @Override
7620    public String getPackageForIntentSender(IIntentSender pendingResult) {
7621        if (!(pendingResult instanceof PendingIntentRecord)) {
7622            return null;
7623        }
7624        try {
7625            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7626            return res.key.packageName;
7627        } catch (ClassCastException e) {
7628        }
7629        return null;
7630    }
7631
7632    @Override
7633    public int getUidForIntentSender(IIntentSender sender) {
7634        if (sender instanceof PendingIntentRecord) {
7635            try {
7636                PendingIntentRecord res = (PendingIntentRecord)sender;
7637                return res.uid;
7638            } catch (ClassCastException e) {
7639            }
7640        }
7641        return -1;
7642    }
7643
7644    @Override
7645    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7646        if (!(pendingResult instanceof PendingIntentRecord)) {
7647            return false;
7648        }
7649        try {
7650            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7651            if (res.key.allIntents == null) {
7652                return false;
7653            }
7654            for (int i=0; i<res.key.allIntents.length; i++) {
7655                Intent intent = res.key.allIntents[i];
7656                if (intent.getPackage() != null && intent.getComponent() != null) {
7657                    return false;
7658                }
7659            }
7660            return true;
7661        } catch (ClassCastException e) {
7662        }
7663        return false;
7664    }
7665
7666    @Override
7667    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7668        if (!(pendingResult instanceof PendingIntentRecord)) {
7669            return false;
7670        }
7671        try {
7672            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7673            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7674                return true;
7675            }
7676            return false;
7677        } catch (ClassCastException e) {
7678        }
7679        return false;
7680    }
7681
7682    @Override
7683    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7684        enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7685                "getIntentForIntentSender()");
7686        if (!(pendingResult instanceof PendingIntentRecord)) {
7687            return null;
7688        }
7689        try {
7690            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7691            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7692        } catch (ClassCastException e) {
7693        }
7694        return null;
7695    }
7696
7697    @Override
7698    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7699        if (!(pendingResult instanceof PendingIntentRecord)) {
7700            return null;
7701        }
7702        try {
7703            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7704            synchronized (this) {
7705                return getTagForIntentSenderLocked(res, prefix);
7706            }
7707        } catch (ClassCastException e) {
7708        }
7709        return null;
7710    }
7711
7712    String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7713        final Intent intent = res.key.requestIntent;
7714        if (intent != null) {
7715            if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7716                    || res.lastTagPrefix.equals(prefix))) {
7717                return res.lastTag;
7718            }
7719            res.lastTagPrefix = prefix;
7720            final StringBuilder sb = new StringBuilder(128);
7721            if (prefix != null) {
7722                sb.append(prefix);
7723            }
7724            if (intent.getAction() != null) {
7725                sb.append(intent.getAction());
7726            } else if (intent.getComponent() != null) {
7727                intent.getComponent().appendShortString(sb);
7728            } else {
7729                sb.append("?");
7730            }
7731            return res.lastTag = sb.toString();
7732        }
7733        return null;
7734    }
7735
7736    @Override
7737    public void setProcessLimit(int max) {
7738        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7739                "setProcessLimit()");
7740        synchronized (this) {
7741            mConstants.setOverrideMaxCachedProcesses(max);
7742        }
7743        trimApplications();
7744    }
7745
7746    @Override
7747    public int getProcessLimit() {
7748        synchronized (this) {
7749            return mConstants.getOverrideMaxCachedProcesses();
7750        }
7751    }
7752
7753    void foregroundTokenDied(ForegroundToken token) {
7754        synchronized (ActivityManagerService.this) {
7755            synchronized (mPidsSelfLocked) {
7756                ForegroundToken cur
7757                    = mForegroundProcesses.get(token.pid);
7758                if (cur != token) {
7759                    return;
7760                }
7761                mForegroundProcesses.remove(token.pid);
7762                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7763                if (pr == null) {
7764                    return;
7765                }
7766                pr.forcingToForeground = null;
7767                updateProcessForegroundLocked(pr, false, false);
7768            }
7769            updateOomAdjLocked();
7770        }
7771    }
7772
7773    @Override
7774    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7775        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7776                "setProcessForeground()");
7777        synchronized(this) {
7778            boolean changed = false;
7779
7780            synchronized (mPidsSelfLocked) {
7781                ProcessRecord pr = mPidsSelfLocked.get(pid);
7782                if (pr == null && isForeground) {
7783                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7784                    return;
7785                }
7786                ForegroundToken oldToken = mForegroundProcesses.get(pid);
7787                if (oldToken != null) {
7788                    oldToken.token.unlinkToDeath(oldToken, 0);
7789                    mForegroundProcesses.remove(pid);
7790                    if (pr != null) {
7791                        pr.forcingToForeground = null;
7792                    }
7793                    changed = true;
7794                }
7795                if (isForeground && token != null) {
7796                    ForegroundToken newToken = new ForegroundToken() {
7797                        @Override
7798                        public void binderDied() {
7799                            foregroundTokenDied(this);
7800                        }
7801                    };
7802                    newToken.pid = pid;
7803                    newToken.token = token;
7804                    try {
7805                        token.linkToDeath(newToken, 0);
7806                        mForegroundProcesses.put(pid, newToken);
7807                        pr.forcingToForeground = token;
7808                        changed = true;
7809                    } catch (RemoteException e) {
7810                        // If the process died while doing this, we will later
7811                        // do the cleanup with the process death link.
7812                    }
7813                }
7814            }
7815
7816            if (changed) {
7817                updateOomAdjLocked();
7818            }
7819        }
7820    }
7821
7822    @Override
7823    public boolean isAppForeground(int uid) throws RemoteException {
7824        synchronized (this) {
7825            UidRecord uidRec = mActiveUids.get(uid);
7826            if (uidRec == null || uidRec.idle) {
7827                return false;
7828            }
7829            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7830        }
7831    }
7832
7833    // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7834    // be guarded by permission checking.
7835    int getUidState(int uid) {
7836        synchronized (this) {
7837            UidRecord uidRec = mActiveUids.get(uid);
7838            return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7839        }
7840    }
7841
7842    @Override
7843    public boolean isInMultiWindowMode(IBinder token) {
7844        final long origId = Binder.clearCallingIdentity();
7845        try {
7846            synchronized(this) {
7847                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7848                if (r == null) {
7849                    return false;
7850                }
7851                // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7852                return !r.task.mFullscreen;
7853            }
7854        } finally {
7855            Binder.restoreCallingIdentity(origId);
7856        }
7857    }
7858
7859    @Override
7860    public boolean isInPictureInPictureMode(IBinder token) {
7861        final long origId = Binder.clearCallingIdentity();
7862        try {
7863            synchronized(this) {
7864                final ActivityStack stack = ActivityRecord.getStackLocked(token);
7865                if (stack == null) {
7866                    return false;
7867                }
7868                return stack.mStackId == PINNED_STACK_ID;
7869            }
7870        } finally {
7871            Binder.restoreCallingIdentity(origId);
7872        }
7873    }
7874
7875    @Override
7876    public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureArgs args) {
7877        final long origId = Binder.clearCallingIdentity();
7878        try {
7879            synchronized(this) {
7880                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7881                        "enterPictureInPictureMode", token, args);
7882
7883                // Activity supports picture-in-picture, now check that we can enter PiP at this
7884                // point, if it is
7885                if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
7886                        false /* noThrow */)) {
7887                    return false;
7888                }
7889
7890                final Runnable enterPipRunnable = () -> {
7891                    // Only update the saved args from the args that are set
7892                    r.pictureInPictureArgs.copyOnlySet(args);
7893                    final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
7894                    final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
7895                    final Rect sourceBounds = r.pictureInPictureArgs.getSourceRectHint();
7896                    final Rect destBounds = mWindowManager.getPictureInPictureBounds(DEFAULT_DISPLAY,
7897                            aspectRatio);
7898                    mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, destBounds,
7899                            true /* moveHomeStackToFront */, "enterPictureInPictureMode");
7900                    final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
7901                    stack.setPictureInPictureAspectRatio(aspectRatio);
7902                    stack.setPictureInPictureActions(actions);
7903
7904                    MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
7905                            r.supportsPictureInPictureWhilePausing);
7906                    logPictureInPictureArgs(args);
7907                };
7908
7909                if (isKeyguardLocked()) {
7910                    // If the keyguard is showing or occluded, then try and dismiss it before
7911                    // entering picture-in-picture (this will prompt the user to authenticate if the
7912                    // device is currently locked).
7913                    try {
7914                        dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
7915                            @Override
7916                            public void onDismissError() throws RemoteException {
7917                                // Do nothing
7918                            }
7919
7920                            @Override
7921                            public void onDismissSucceeded() throws RemoteException {
7922                                mHandler.post(enterPipRunnable);
7923                            }
7924
7925                            @Override
7926                            public void onDismissCancelled() throws RemoteException {
7927                                // Do nothing
7928                            }
7929                        });
7930                    } catch (RemoteException e) {
7931                        // Local call
7932                    }
7933                } else {
7934                    // Enter picture in picture immediately otherwise
7935                    enterPipRunnable.run();
7936                }
7937                return true;
7938            }
7939        } finally {
7940            Binder.restoreCallingIdentity(origId);
7941        }
7942    }
7943
7944    @Override
7945    public void setPictureInPictureArgs(IBinder token, final PictureInPictureArgs args) {
7946        final long origId = Binder.clearCallingIdentity();
7947        try {
7948            synchronized(this) {
7949                final ActivityRecord r = ensureValidPictureInPictureActivityArgsLocked(
7950                        "setPictureInPictureArgs", token, args);
7951
7952                // Only update the saved args from the args that are set
7953                r.pictureInPictureArgs.copyOnlySet(args);
7954                if (r.getStack().getStackId() == PINNED_STACK_ID) {
7955                    // If the activity is already in picture-in-picture, update the pinned stack now
7956                    // if it is not already expanding to fullscreen. Otherwise, the arguments will
7957                    // be used the next time the activity enters PiP
7958                    final PinnedActivityStack stack = r.getStack();
7959                    if (!stack.isBoundsAnimatingToFullscreen()) {
7960                        stack.setPictureInPictureAspectRatio(
7961                                r.pictureInPictureArgs.getAspectRatio());
7962                        stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
7963                    }
7964                }
7965                logPictureInPictureArgs(args);
7966            }
7967        } finally {
7968            Binder.restoreCallingIdentity(origId);
7969        }
7970    }
7971
7972    private void logPictureInPictureArgs(PictureInPictureArgs args) {
7973        if (args.hasSetActions()) {
7974            MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
7975                    args.getActions().size());
7976        }
7977        if (args.hasSetAspectRatio()) {
7978            LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
7979            lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, args.getAspectRatio());
7980            MetricsLogger.action(lm);
7981        }
7982    }
7983
7984    /**
7985     * Checks the state of the system and the activity associated with the given {@param token} to
7986     * verify that picture-in-picture is supported for that activity.
7987     *
7988     * @return the activity record for the given {@param token} if all the checks pass.
7989     */
7990    private ActivityRecord ensureValidPictureInPictureActivityArgsLocked(String caller,
7991            IBinder token, PictureInPictureArgs args) {
7992        if (!mSupportsPictureInPicture) {
7993            throw new IllegalStateException(caller
7994                    + ": Device doesn't support picture-in-picture mode.");
7995        }
7996
7997        final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7998        if (r == null) {
7999            throw new IllegalStateException(caller
8000                    + ": Can't find activity for token=" + token);
8001        }
8002
8003        if (!r.supportsPictureInPicture()) {
8004            throw new IllegalStateException(caller
8005                    + ": Current activity does not support picture-in-picture.");
8006        }
8007
8008        if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8009            throw new IllegalStateException(caller
8010                    + ": Activities on the home, assistant, or recents stack not supported");
8011        }
8012
8013        if (args.hasSetAspectRatio()
8014                && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8015                        args.getAspectRatio())) {
8016            final float minAspectRatio = mContext.getResources().getFloat(
8017                    com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8018            final float maxAspectRatio = mContext.getResources().getFloat(
8019                    com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8020            throw new IllegalArgumentException(String.format(caller
8021                    + ": Aspect ratio is too extreme (must be between %f and %f).",
8022                            minAspectRatio, maxAspectRatio));
8023        }
8024
8025        if (args.hasSetActions()
8026                && args.getActions().size() > ActivityManager.getMaxNumPictureInPictureActions()) {
8027            throw new IllegalArgumentException(String.format(caller + ": Invalid number of"
8028                    + "picture-in-picture actions.  Only a maximum of %d actions allowed",
8029                            ActivityManager.getMaxNumPictureInPictureActions()));
8030        }
8031
8032        return r;
8033    }
8034
8035    // =========================================================
8036    // PROCESS INFO
8037    // =========================================================
8038
8039    static class ProcessInfoService extends IProcessInfoService.Stub {
8040        final ActivityManagerService mActivityManagerService;
8041        ProcessInfoService(ActivityManagerService activityManagerService) {
8042            mActivityManagerService = activityManagerService;
8043        }
8044
8045        @Override
8046        public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8047            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8048                    /*in*/ pids, /*out*/ states, null);
8049        }
8050
8051        @Override
8052        public void getProcessStatesAndOomScoresFromPids(
8053                /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8054            mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8055                    /*in*/ pids, /*out*/ states, /*out*/ scores);
8056        }
8057    }
8058
8059    /**
8060     * For each PID in the given input array, write the current process state
8061     * for that process into the states array, or -1 to indicate that no
8062     * process with the given PID exists. If scores array is provided, write
8063     * the oom score for the process into the scores array, with INVALID_ADJ
8064     * indicating the PID doesn't exist.
8065     */
8066    public void getProcessStatesAndOomScoresForPIDs(
8067            /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8068        if (scores != null) {
8069            enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8070                    "getProcessStatesAndOomScoresForPIDs()");
8071        }
8072
8073        if (pids == null) {
8074            throw new NullPointerException("pids");
8075        } else if (states == null) {
8076            throw new NullPointerException("states");
8077        } else if (pids.length != states.length) {
8078            throw new IllegalArgumentException("pids and states arrays have different lengths!");
8079        } else if (scores != null && pids.length != scores.length) {
8080            throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8081        }
8082
8083        synchronized (mPidsSelfLocked) {
8084            for (int i = 0; i < pids.length; i++) {
8085                ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8086                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8087                        pr.curProcState;
8088                if (scores != null) {
8089                    scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8090                }
8091            }
8092        }
8093    }
8094
8095    // =========================================================
8096    // PERMISSIONS
8097    // =========================================================
8098
8099    static class PermissionController extends IPermissionController.Stub {
8100        ActivityManagerService mActivityManagerService;
8101        PermissionController(ActivityManagerService activityManagerService) {
8102            mActivityManagerService = activityManagerService;
8103        }
8104
8105        @Override
8106        public boolean checkPermission(String permission, int pid, int uid) {
8107            return mActivityManagerService.checkPermission(permission, pid,
8108                    uid) == PackageManager.PERMISSION_GRANTED;
8109        }
8110
8111        @Override
8112        public String[] getPackagesForUid(int uid) {
8113            return mActivityManagerService.mContext.getPackageManager()
8114                    .getPackagesForUid(uid);
8115        }
8116
8117        @Override
8118        public boolean isRuntimePermission(String permission) {
8119            try {
8120                PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8121                        .getPermissionInfo(permission, 0);
8122                return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8123                        == PermissionInfo.PROTECTION_DANGEROUS;
8124            } catch (NameNotFoundException nnfe) {
8125                Slog.e(TAG, "No such permission: "+ permission, nnfe);
8126            }
8127            return false;
8128        }
8129    }
8130
8131    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8132        @Override
8133        public int checkComponentPermission(String permission, int pid, int uid,
8134                int owningUid, boolean exported) {
8135            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8136                    owningUid, exported);
8137        }
8138
8139        @Override
8140        public Object getAMSLock() {
8141            return ActivityManagerService.this;
8142        }
8143    }
8144
8145    /**
8146     * This can be called with or without the global lock held.
8147     */
8148    int checkComponentPermission(String permission, int pid, int uid,
8149            int owningUid, boolean exported) {
8150        if (pid == MY_PID) {
8151            return PackageManager.PERMISSION_GRANTED;
8152        }
8153        return ActivityManager.checkComponentPermission(permission, uid,
8154                owningUid, exported);
8155    }
8156
8157    /**
8158     * As the only public entry point for permissions checking, this method
8159     * can enforce the semantic that requesting a check on a null global
8160     * permission is automatically denied.  (Internally a null permission
8161     * string is used when calling {@link #checkComponentPermission} in cases
8162     * when only uid-based security is needed.)
8163     *
8164     * This can be called with or without the global lock held.
8165     */
8166    @Override
8167    public int checkPermission(String permission, int pid, int uid) {
8168        if (permission == null) {
8169            return PackageManager.PERMISSION_DENIED;
8170        }
8171        return checkComponentPermission(permission, pid, uid, -1, true);
8172    }
8173
8174    @Override
8175    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8176        if (permission == null) {
8177            return PackageManager.PERMISSION_DENIED;
8178        }
8179
8180        // We might be performing an operation on behalf of an indirect binder
8181        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8182        // client identity accordingly before proceeding.
8183        Identity tlsIdentity = sCallerIdentity.get();
8184        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8185            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8186                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8187            uid = tlsIdentity.uid;
8188            pid = tlsIdentity.pid;
8189        }
8190
8191        return checkComponentPermission(permission, pid, uid, -1, true);
8192    }
8193
8194    /**
8195     * Binder IPC calls go through the public entry point.
8196     * This can be called with or without the global lock held.
8197     */
8198    int checkCallingPermission(String permission) {
8199        return checkPermission(permission,
8200                Binder.getCallingPid(),
8201                UserHandle.getAppId(Binder.getCallingUid()));
8202    }
8203
8204    /**
8205     * This can be called with or without the global lock held.
8206     */
8207    void enforceCallingPermission(String permission, String func) {
8208        if (checkCallingPermission(permission)
8209                == PackageManager.PERMISSION_GRANTED) {
8210            return;
8211        }
8212
8213        String msg = "Permission Denial: " + func + " from pid="
8214                + Binder.getCallingPid()
8215                + ", uid=" + Binder.getCallingUid()
8216                + " requires " + permission;
8217        Slog.w(TAG, msg);
8218        throw new SecurityException(msg);
8219    }
8220
8221    /**
8222     * Determine if UID is holding permissions required to access {@link Uri} in
8223     * the given {@link ProviderInfo}. Final permission checking is always done
8224     * in {@link ContentProvider}.
8225     */
8226    private final boolean checkHoldingPermissionsLocked(
8227            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8228        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8229                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8230        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8231            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8232                    != PERMISSION_GRANTED) {
8233                return false;
8234            }
8235        }
8236        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8237    }
8238
8239    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8240            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8241        if (pi.applicationInfo.uid == uid) {
8242            return true;
8243        } else if (!pi.exported) {
8244            return false;
8245        }
8246
8247        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8248        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8249        try {
8250            // check if target holds top-level <provider> permissions
8251            if (!readMet && pi.readPermission != null && considerUidPermissions
8252                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8253                readMet = true;
8254            }
8255            if (!writeMet && pi.writePermission != null && considerUidPermissions
8256                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8257                writeMet = true;
8258            }
8259
8260            // track if unprotected read/write is allowed; any denied
8261            // <path-permission> below removes this ability
8262            boolean allowDefaultRead = pi.readPermission == null;
8263            boolean allowDefaultWrite = pi.writePermission == null;
8264
8265            // check if target holds any <path-permission> that match uri
8266            final PathPermission[] pps = pi.pathPermissions;
8267            if (pps != null) {
8268                final String path = grantUri.uri.getPath();
8269                int i = pps.length;
8270                while (i > 0 && (!readMet || !writeMet)) {
8271                    i--;
8272                    PathPermission pp = pps[i];
8273                    if (pp.match(path)) {
8274                        if (!readMet) {
8275                            final String pprperm = pp.getReadPermission();
8276                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8277                                    "Checking read perm for " + pprperm + " for " + pp.getPath()
8278                                    + ": match=" + pp.match(path)
8279                                    + " check=" + pm.checkUidPermission(pprperm, uid));
8280                            if (pprperm != null) {
8281                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8282                                        == PERMISSION_GRANTED) {
8283                                    readMet = true;
8284                                } else {
8285                                    allowDefaultRead = false;
8286                                }
8287                            }
8288                        }
8289                        if (!writeMet) {
8290                            final String ppwperm = pp.getWritePermission();
8291                            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8292                                    "Checking write perm " + ppwperm + " for " + pp.getPath()
8293                                    + ": match=" + pp.match(path)
8294                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
8295                            if (ppwperm != null) {
8296                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8297                                        == PERMISSION_GRANTED) {
8298                                    writeMet = true;
8299                                } else {
8300                                    allowDefaultWrite = false;
8301                                }
8302                            }
8303                        }
8304                    }
8305                }
8306            }
8307
8308            // grant unprotected <provider> read/write, if not blocked by
8309            // <path-permission> above
8310            if (allowDefaultRead) readMet = true;
8311            if (allowDefaultWrite) writeMet = true;
8312
8313        } catch (RemoteException e) {
8314            return false;
8315        }
8316
8317        return readMet && writeMet;
8318    }
8319
8320    public boolean isAppStartModeDisabled(int uid, String packageName) {
8321        synchronized (this) {
8322            return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8323                    == ActivityManager.APP_START_MODE_DISABLED;
8324        }
8325    }
8326
8327    // Unified app-op and target sdk check
8328    int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8329        // Apps that target O+ are always subject to background check
8330        if (mConstants.ENFORCE_BG_CHECK && packageTargetSdk >= Build.VERSION_CODES.O) {
8331            if (DEBUG_BACKGROUND_CHECK) {
8332                Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8333            }
8334            return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8335        }
8336        // ...and legacy apps get an AppOp check
8337        int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8338                uid, packageName);
8339        if (DEBUG_BACKGROUND_CHECK) {
8340            Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8341        }
8342        switch (appop) {
8343            case AppOpsManager.MODE_ALLOWED:
8344                return ActivityManager.APP_START_MODE_NORMAL;
8345            case AppOpsManager.MODE_IGNORED:
8346                return ActivityManager.APP_START_MODE_DELAYED;
8347            default:
8348                return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8349        }
8350    }
8351
8352    // Service launch is available to apps with run-in-background exemptions but
8353    // some other background operations are not.  If we're doing a check
8354    // of service-launch policy, allow those callers to proceed unrestricted.
8355    int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8356        // Persistent app?
8357        if (mPackageManagerInt.isPackagePersistent(packageName)) {
8358            if (DEBUG_BACKGROUND_CHECK) {
8359                Slog.i(TAG, "App " + uid + "/" + packageName
8360                        + " is persistent; not restricted in background");
8361            }
8362            return ActivityManager.APP_START_MODE_NORMAL;
8363        }
8364
8365        // Non-persistent but background whitelisted?
8366        if (uidOnBackgroundWhitelist(uid)) {
8367            if (DEBUG_BACKGROUND_CHECK) {
8368                Slog.i(TAG, "App " + uid + "/" + packageName
8369                        + " on background whitelist; not restricted in background");
8370            }
8371            return ActivityManager.APP_START_MODE_NORMAL;
8372        }
8373
8374        // Is this app on the battery whitelist?
8375        if (isOnDeviceIdleWhitelistLocked(uid)) {
8376            if (DEBUG_BACKGROUND_CHECK) {
8377                Slog.i(TAG, "App " + uid + "/" + packageName
8378                        + " on idle whitelist; not restricted in background");
8379            }
8380            return ActivityManager.APP_START_MODE_NORMAL;
8381        }
8382
8383        // None of the service-policy criteria apply, so we apply the common criteria
8384        return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8385    }
8386
8387    int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8388            int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8389        UidRecord uidRec = mActiveUids.get(uid);
8390        if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8391                + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8392                + (uidRec != null ? uidRec.idle : false));
8393        if (uidRec == null || alwaysRestrict || uidRec.idle) {
8394            boolean ephemeral;
8395            if (uidRec == null) {
8396                ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8397                        UserHandle.getUserId(uid), packageName);
8398            } else {
8399                ephemeral = uidRec.ephemeral;
8400            }
8401
8402            if (ephemeral) {
8403                // We are hard-core about ephemeral apps not running in the background.
8404                return ActivityManager.APP_START_MODE_DISABLED;
8405            } else {
8406                if (disabledOnly) {
8407                    // The caller is only interested in whether app starts are completely
8408                    // disabled for the given package (that is, it is an instant app).  So
8409                    // we don't need to go further, which is all just seeing if we should
8410                    // apply a "delayed" mode for a regular app.
8411                    return ActivityManager.APP_START_MODE_NORMAL;
8412                }
8413                final int startMode = (alwaysRestrict)
8414                        ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8415                        : appServicesRestrictedInBackgroundLocked(uid, packageName,
8416                                packageTargetSdk);
8417                if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8418                        + " pkg=" + packageName + " startMode=" + startMode
8419                        + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8420                if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8421                    // This is an old app that has been forced into a "compatible as possible"
8422                    // mode of background check.  To increase compatibility, we will allow other
8423                    // foreground apps to cause its services to start.
8424                    if (callingPid >= 0) {
8425                        ProcessRecord proc;
8426                        synchronized (mPidsSelfLocked) {
8427                            proc = mPidsSelfLocked.get(callingPid);
8428                        }
8429                        if (proc != null && proc.curProcState
8430                                < ActivityManager.PROCESS_STATE_RECEIVER) {
8431                            // Whoever is instigating this is in the foreground, so we will allow it
8432                            // to go through.
8433                            return ActivityManager.APP_START_MODE_NORMAL;
8434                        }
8435                    }
8436                }
8437                return startMode;
8438            }
8439        }
8440        return ActivityManager.APP_START_MODE_NORMAL;
8441    }
8442
8443    boolean isOnDeviceIdleWhitelistLocked(int uid) {
8444        final int appId = UserHandle.getAppId(uid);
8445        return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8446                || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0;
8447    }
8448
8449    private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8450        ProviderInfo pi = null;
8451        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8452        if (cpr != null) {
8453            pi = cpr.info;
8454        } else {
8455            try {
8456                pi = AppGlobals.getPackageManager().resolveContentProvider(
8457                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8458                        userHandle);
8459            } catch (RemoteException ex) {
8460            }
8461        }
8462        return pi;
8463    }
8464
8465    void grantEphemeralAccessLocked(int userId, Intent intent,
8466            int targetAppId, int ephemeralAppId) {
8467        getPackageManagerInternalLocked().
8468                grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8469    }
8470
8471    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8472        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8473        if (targetUris != null) {
8474            return targetUris.get(grantUri);
8475        }
8476        return null;
8477    }
8478
8479    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8480            String targetPkg, int targetUid, GrantUri grantUri) {
8481        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8482        if (targetUris == null) {
8483            targetUris = Maps.newArrayMap();
8484            mGrantedUriPermissions.put(targetUid, targetUris);
8485        }
8486
8487        UriPermission perm = targetUris.get(grantUri);
8488        if (perm == null) {
8489            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8490            targetUris.put(grantUri, perm);
8491        }
8492
8493        return perm;
8494    }
8495
8496    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8497            final int modeFlags) {
8498        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8499        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8500                : UriPermission.STRENGTH_OWNED;
8501
8502        // Root gets to do everything.
8503        if (uid == 0) {
8504            return true;
8505        }
8506
8507        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8508        if (perms == null) return false;
8509
8510        // First look for exact match
8511        final UriPermission exactPerm = perms.get(grantUri);
8512        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8513            return true;
8514        }
8515
8516        // No exact match, look for prefixes
8517        final int N = perms.size();
8518        for (int i = 0; i < N; i++) {
8519            final UriPermission perm = perms.valueAt(i);
8520            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8521                    && perm.getStrength(modeFlags) >= minStrength) {
8522                return true;
8523            }
8524        }
8525
8526        return false;
8527    }
8528
8529    /**
8530     * @param uri This uri must NOT contain an embedded userId.
8531     * @param userId The userId in which the uri is to be resolved.
8532     */
8533    @Override
8534    public int checkUriPermission(Uri uri, int pid, int uid,
8535            final int modeFlags, int userId, IBinder callerToken) {
8536        enforceNotIsolatedCaller("checkUriPermission");
8537
8538        // Another redirected-binder-call permissions check as in
8539        // {@link checkPermissionWithToken}.
8540        Identity tlsIdentity = sCallerIdentity.get();
8541        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8542            uid = tlsIdentity.uid;
8543            pid = tlsIdentity.pid;
8544        }
8545
8546        // Our own process gets to do everything.
8547        if (pid == MY_PID) {
8548            return PackageManager.PERMISSION_GRANTED;
8549        }
8550        synchronized (this) {
8551            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8552                    ? PackageManager.PERMISSION_GRANTED
8553                    : PackageManager.PERMISSION_DENIED;
8554        }
8555    }
8556
8557    /**
8558     * Check if the targetPkg can be granted permission to access uri by
8559     * the callingUid using the given modeFlags.  Throws a security exception
8560     * if callingUid is not allowed to do this.  Returns the uid of the target
8561     * if the URI permission grant should be performed; returns -1 if it is not
8562     * needed (for example targetPkg already has permission to access the URI).
8563     * If you already know the uid of the target, you can supply it in
8564     * lastTargetUid else set that to -1.
8565     */
8566    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8567            final int modeFlags, int lastTargetUid) {
8568        if (!Intent.isAccessUriMode(modeFlags)) {
8569            return -1;
8570        }
8571
8572        if (targetPkg != null) {
8573            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8574                    "Checking grant " + targetPkg + " permission to " + grantUri);
8575        }
8576
8577        final IPackageManager pm = AppGlobals.getPackageManager();
8578
8579        // If this is not a content: uri, we can't do anything with it.
8580        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8581            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8582                    "Can't grant URI permission for non-content URI: " + grantUri);
8583            return -1;
8584        }
8585
8586        final String authority = grantUri.uri.getAuthority();
8587        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8588                MATCH_DEBUG_TRIAGED_MISSING);
8589        if (pi == null) {
8590            Slog.w(TAG, "No content provider found for permission check: " +
8591                    grantUri.uri.toSafeString());
8592            return -1;
8593        }
8594
8595        int targetUid = lastTargetUid;
8596        if (targetUid < 0 && targetPkg != null) {
8597            try {
8598                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8599                        UserHandle.getUserId(callingUid));
8600                if (targetUid < 0) {
8601                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8602                            "Can't grant URI permission no uid for: " + targetPkg);
8603                    return -1;
8604                }
8605            } catch (RemoteException ex) {
8606                return -1;
8607            }
8608        }
8609
8610        // If we're extending a persistable grant, then we always need to create
8611        // the grant data structure so that take/release APIs work
8612        if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8613            return targetUid;
8614        }
8615
8616        if (targetUid >= 0) {
8617            // First...  does the target actually need this permission?
8618            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8619                // No need to grant the target this permission.
8620                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8621                        "Target " + targetPkg + " already has full permission to " + grantUri);
8622                return -1;
8623            }
8624        } else {
8625            // First...  there is no target package, so can anyone access it?
8626            boolean allowed = pi.exported;
8627            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8628                if (pi.readPermission != null) {
8629                    allowed = false;
8630                }
8631            }
8632            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8633                if (pi.writePermission != null) {
8634                    allowed = false;
8635                }
8636            }
8637            if (allowed) {
8638                return -1;
8639            }
8640        }
8641
8642        /* There is a special cross user grant if:
8643         * - The target is on another user.
8644         * - Apps on the current user can access the uri without any uid permissions.
8645         * In this case, we grant a uri permission, even if the ContentProvider does not normally
8646         * grant uri permissions.
8647         */
8648        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8649                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8650                modeFlags, false /*without considering the uid permissions*/);
8651
8652        // Second...  is the provider allowing granting of URI permissions?
8653        if (!specialCrossUserGrant) {
8654            if (!pi.grantUriPermissions) {
8655                throw new SecurityException("Provider " + pi.packageName
8656                        + "/" + pi.name
8657                        + " does not allow granting of Uri permissions (uri "
8658                        + grantUri + ")");
8659            }
8660            if (pi.uriPermissionPatterns != null) {
8661                final int N = pi.uriPermissionPatterns.length;
8662                boolean allowed = false;
8663                for (int i=0; i<N; i++) {
8664                    if (pi.uriPermissionPatterns[i] != null
8665                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8666                        allowed = true;
8667                        break;
8668                    }
8669                }
8670                if (!allowed) {
8671                    throw new SecurityException("Provider " + pi.packageName
8672                            + "/" + pi.name
8673                            + " does not allow granting of permission to path of Uri "
8674                            + grantUri);
8675                }
8676            }
8677        }
8678
8679        // Third...  does the caller itself have permission to access
8680        // this uri?
8681        final int callingAppId = UserHandle.getAppId(callingUid);
8682        if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8683            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8684                // Exempted authority for cropping user photos in Settings app
8685            } else {
8686                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8687                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8688                return -1;
8689            }
8690        }
8691        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8692            // Require they hold a strong enough Uri permission
8693            if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8694                if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8695                    throw new SecurityException(
8696                            "UID " + callingUid + " does not have permission to " + grantUri
8697                                    + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8698                                    + "or related APIs");
8699                } else {
8700                    throw new SecurityException(
8701                            "UID " + callingUid + " does not have permission to " + grantUri);
8702                }
8703            }
8704        }
8705        return targetUid;
8706    }
8707
8708    /**
8709     * @param uri This uri must NOT contain an embedded userId.
8710     * @param userId The userId in which the uri is to be resolved.
8711     */
8712    @Override
8713    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8714            final int modeFlags, int userId) {
8715        enforceNotIsolatedCaller("checkGrantUriPermission");
8716        synchronized(this) {
8717            return checkGrantUriPermissionLocked(callingUid, targetPkg,
8718                    new GrantUri(userId, uri, false), modeFlags, -1);
8719        }
8720    }
8721
8722    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8723            final int modeFlags, UriPermissionOwner owner) {
8724        if (!Intent.isAccessUriMode(modeFlags)) {
8725            return;
8726        }
8727
8728        // So here we are: the caller has the assumed permission
8729        // to the uri, and the target doesn't.  Let's now give this to
8730        // the target.
8731
8732        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8733                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8734
8735        final String authority = grantUri.uri.getAuthority();
8736        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8737                MATCH_DEBUG_TRIAGED_MISSING);
8738        if (pi == null) {
8739            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8740            return;
8741        }
8742
8743        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8744            grantUri.prefix = true;
8745        }
8746        final UriPermission perm = findOrCreateUriPermissionLocked(
8747                pi.packageName, targetPkg, targetUid, grantUri);
8748        perm.grantModes(modeFlags, owner);
8749    }
8750
8751    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8752            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8753        if (targetPkg == null) {
8754            throw new NullPointerException("targetPkg");
8755        }
8756        int targetUid;
8757        final IPackageManager pm = AppGlobals.getPackageManager();
8758        try {
8759            targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8760        } catch (RemoteException ex) {
8761            return;
8762        }
8763
8764        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8765                targetUid);
8766        if (targetUid < 0) {
8767            return;
8768        }
8769
8770        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8771                owner);
8772    }
8773
8774    static class NeededUriGrants extends ArrayList<GrantUri> {
8775        final String targetPkg;
8776        final int targetUid;
8777        final int flags;
8778
8779        NeededUriGrants(String targetPkg, int targetUid, int flags) {
8780            this.targetPkg = targetPkg;
8781            this.targetUid = targetUid;
8782            this.flags = flags;
8783        }
8784    }
8785
8786    /**
8787     * Like checkGrantUriPermissionLocked, but takes an Intent.
8788     */
8789    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8790            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8791        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8792                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8793                + " clip=" + (intent != null ? intent.getClipData() : null)
8794                + " from " + intent + "; flags=0x"
8795                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8796
8797        if (targetPkg == null) {
8798            throw new NullPointerException("targetPkg");
8799        }
8800
8801        if (intent == null) {
8802            return null;
8803        }
8804        Uri data = intent.getData();
8805        ClipData clip = intent.getClipData();
8806        if (data == null && clip == null) {
8807            return null;
8808        }
8809        // Default userId for uris in the intent (if they don't specify it themselves)
8810        int contentUserHint = intent.getContentUserHint();
8811        if (contentUserHint == UserHandle.USER_CURRENT) {
8812            contentUserHint = UserHandle.getUserId(callingUid);
8813        }
8814        final IPackageManager pm = AppGlobals.getPackageManager();
8815        int targetUid;
8816        if (needed != null) {
8817            targetUid = needed.targetUid;
8818        } else {
8819            try {
8820                targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8821                        targetUserId);
8822            } catch (RemoteException ex) {
8823                return null;
8824            }
8825            if (targetUid < 0) {
8826                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8827                        "Can't grant URI permission no uid for: " + targetPkg
8828                        + " on user " + targetUserId);
8829                return null;
8830            }
8831        }
8832        if (data != null) {
8833            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8834            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8835                    targetUid);
8836            if (targetUid > 0) {
8837                if (needed == null) {
8838                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
8839                }
8840                needed.add(grantUri);
8841            }
8842        }
8843        if (clip != null) {
8844            for (int i=0; i<clip.getItemCount(); i++) {
8845                Uri uri = clip.getItemAt(i).getUri();
8846                if (uri != null) {
8847                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8848                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8849                            targetUid);
8850                    if (targetUid > 0) {
8851                        if (needed == null) {
8852                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
8853                        }
8854                        needed.add(grantUri);
8855                    }
8856                } else {
8857                    Intent clipIntent = clip.getItemAt(i).getIntent();
8858                    if (clipIntent != null) {
8859                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8860                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8861                        if (newNeeded != null) {
8862                            needed = newNeeded;
8863                        }
8864                    }
8865                }
8866            }
8867        }
8868
8869        return needed;
8870    }
8871
8872    /**
8873     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8874     */
8875    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8876            UriPermissionOwner owner) {
8877        if (needed != null) {
8878            for (int i=0; i<needed.size(); i++) {
8879                GrantUri grantUri = needed.get(i);
8880                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8881                        grantUri, needed.flags, owner);
8882            }
8883        }
8884    }
8885
8886    void grantUriPermissionFromIntentLocked(int callingUid,
8887            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8888        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8889                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8890        if (needed == null) {
8891            return;
8892        }
8893
8894        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8895    }
8896
8897    /**
8898     * @param uri This uri must NOT contain an embedded userId.
8899     * @param userId The userId in which the uri is to be resolved.
8900     */
8901    @Override
8902    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8903            final int modeFlags, int userId) {
8904        enforceNotIsolatedCaller("grantUriPermission");
8905        GrantUri grantUri = new GrantUri(userId, uri, false);
8906        synchronized(this) {
8907            final ProcessRecord r = getRecordForAppLocked(caller);
8908            if (r == null) {
8909                throw new SecurityException("Unable to find app for caller "
8910                        + caller
8911                        + " when granting permission to uri " + grantUri);
8912            }
8913            if (targetPkg == null) {
8914                throw new IllegalArgumentException("null target");
8915            }
8916            if (grantUri == null) {
8917                throw new IllegalArgumentException("null uri");
8918            }
8919
8920            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8921                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8922                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8923                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8924
8925            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8926                    UserHandle.getUserId(r.uid));
8927        }
8928    }
8929
8930    void removeUriPermissionIfNeededLocked(UriPermission perm) {
8931        if (perm.modeFlags == 0) {
8932            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8933                    perm.targetUid);
8934            if (perms != null) {
8935                if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8936                        "Removing " + perm.targetUid + " permission to " + perm.uri);
8937
8938                perms.remove(perm.uri);
8939                if (perms.isEmpty()) {
8940                    mGrantedUriPermissions.remove(perm.targetUid);
8941                }
8942            }
8943        }
8944    }
8945
8946    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8947        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8948                "Revoking all granted permissions to " + grantUri);
8949
8950        final IPackageManager pm = AppGlobals.getPackageManager();
8951        final String authority = grantUri.uri.getAuthority();
8952        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8953                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8954        if (pi == null) {
8955            Slog.w(TAG, "No content provider found for permission revoke: "
8956                    + grantUri.toSafeString());
8957            return;
8958        }
8959
8960        // Does the caller have this permission on the URI?
8961        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8962            // If they don't have direct access to the URI, then revoke any
8963            // ownerless URI permissions that have been granted to them.
8964            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8965            if (perms != null) {
8966                boolean persistChanged = false;
8967                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8968                    final UriPermission perm = it.next();
8969                    if (perm.uri.sourceUserId == grantUri.sourceUserId
8970                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8971                        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8972                                "Revoking non-owned " + perm.targetUid
8973                                + " permission to " + perm.uri);
8974                        persistChanged |= perm.revokeModes(
8975                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8976                        if (perm.modeFlags == 0) {
8977                            it.remove();
8978                        }
8979                    }
8980                }
8981                if (perms.isEmpty()) {
8982                    mGrantedUriPermissions.remove(callingUid);
8983                }
8984                if (persistChanged) {
8985                    schedulePersistUriGrants();
8986                }
8987            }
8988            return;
8989        }
8990
8991        boolean persistChanged = false;
8992
8993        // Go through all of the permissions and remove any that match.
8994        int N = mGrantedUriPermissions.size();
8995        for (int i = 0; i < N; i++) {
8996            final int targetUid = mGrantedUriPermissions.keyAt(i);
8997            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8998
8999            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9000                final UriPermission perm = it.next();
9001                if (perm.uri.sourceUserId == grantUri.sourceUserId
9002                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9003                    if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9004                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
9005                    persistChanged |= perm.revokeModes(
9006                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9007                    if (perm.modeFlags == 0) {
9008                        it.remove();
9009                    }
9010                }
9011            }
9012
9013            if (perms.isEmpty()) {
9014                mGrantedUriPermissions.remove(targetUid);
9015                N--;
9016                i--;
9017            }
9018        }
9019
9020        if (persistChanged) {
9021            schedulePersistUriGrants();
9022        }
9023    }
9024
9025    /**
9026     * @param uri This uri must NOT contain an embedded userId.
9027     * @param userId The userId in which the uri is to be resolved.
9028     */
9029    @Override
9030    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
9031            int userId) {
9032        enforceNotIsolatedCaller("revokeUriPermission");
9033        synchronized(this) {
9034            final ProcessRecord r = getRecordForAppLocked(caller);
9035            if (r == null) {
9036                throw new SecurityException("Unable to find app for caller "
9037                        + caller
9038                        + " when revoking permission to uri " + uri);
9039            }
9040            if (uri == null) {
9041                Slog.w(TAG, "revokeUriPermission: null uri");
9042                return;
9043            }
9044
9045            if (!Intent.isAccessUriMode(modeFlags)) {
9046                return;
9047            }
9048
9049            final String authority = uri.getAuthority();
9050            final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9051                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9052            if (pi == null) {
9053                Slog.w(TAG, "No content provider found for permission revoke: "
9054                        + uri.toSafeString());
9055                return;
9056            }
9057
9058            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
9059        }
9060    }
9061
9062    /**
9063     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9064     * given package.
9065     *
9066     * @param packageName Package name to match, or {@code null} to apply to all
9067     *            packages.
9068     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9069     *            to all users.
9070     * @param persistable If persistable grants should be removed.
9071     */
9072    private void removeUriPermissionsForPackageLocked(
9073            String packageName, int userHandle, boolean persistable) {
9074        if (userHandle == UserHandle.USER_ALL && packageName == null) {
9075            throw new IllegalArgumentException("Must narrow by either package or user");
9076        }
9077
9078        boolean persistChanged = false;
9079
9080        int N = mGrantedUriPermissions.size();
9081        for (int i = 0; i < N; i++) {
9082            final int targetUid = mGrantedUriPermissions.keyAt(i);
9083            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9084
9085            // Only inspect grants matching user
9086            if (userHandle == UserHandle.USER_ALL
9087                    || userHandle == UserHandle.getUserId(targetUid)) {
9088                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9089                    final UriPermission perm = it.next();
9090
9091                    // Only inspect grants matching package
9092                    if (packageName == null || perm.sourcePkg.equals(packageName)
9093                            || perm.targetPkg.equals(packageName)) {
9094                        // Hacky solution as part of fixing a security bug; ignore
9095                        // grants associated with DownloadManager so we don't have
9096                        // to immediately launch it to regrant the permissions
9097                        if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9098                                && !persistable) continue;
9099
9100                        persistChanged |= perm.revokeModes(persistable
9101                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9102
9103                        // Only remove when no modes remain; any persisted grants
9104                        // will keep this alive.
9105                        if (perm.modeFlags == 0) {
9106                            it.remove();
9107                        }
9108                    }
9109                }
9110
9111                if (perms.isEmpty()) {
9112                    mGrantedUriPermissions.remove(targetUid);
9113                    N--;
9114                    i--;
9115                }
9116            }
9117        }
9118
9119        if (persistChanged) {
9120            schedulePersistUriGrants();
9121        }
9122    }
9123
9124    @Override
9125    public IBinder newUriPermissionOwner(String name) {
9126        enforceNotIsolatedCaller("newUriPermissionOwner");
9127        synchronized(this) {
9128            UriPermissionOwner owner = new UriPermissionOwner(this, name);
9129            return owner.getExternalTokenLocked();
9130        }
9131    }
9132
9133    @Override
9134    public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9135        enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9136        synchronized(this) {
9137            ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9138            if (r == null) {
9139                throw new IllegalArgumentException("Activity does not exist; token="
9140                        + activityToken);
9141            }
9142            return r.getUriPermissionsLocked().getExternalTokenLocked();
9143        }
9144    }
9145    /**
9146     * @param uri This uri must NOT contain an embedded userId.
9147     * @param sourceUserId The userId in which the uri is to be resolved.
9148     * @param targetUserId The userId of the app that receives the grant.
9149     */
9150    @Override
9151    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9152            final int modeFlags, int sourceUserId, int targetUserId) {
9153        targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9154                Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9155                "grantUriPermissionFromOwner", null);
9156        synchronized(this) {
9157            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9158            if (owner == null) {
9159                throw new IllegalArgumentException("Unknown owner: " + token);
9160            }
9161            if (fromUid != Binder.getCallingUid()) {
9162                if (Binder.getCallingUid() != Process.myUid()) {
9163                    // Only system code can grant URI permissions on behalf
9164                    // of other users.
9165                    throw new SecurityException("nice try");
9166                }
9167            }
9168            if (targetPkg == null) {
9169                throw new IllegalArgumentException("null target");
9170            }
9171            if (uri == null) {
9172                throw new IllegalArgumentException("null uri");
9173            }
9174
9175            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9176                    modeFlags, owner, targetUserId);
9177        }
9178    }
9179
9180    /**
9181     * @param uri This uri must NOT contain an embedded userId.
9182     * @param userId The userId in which the uri is to be resolved.
9183     */
9184    @Override
9185    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9186        synchronized(this) {
9187            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9188            if (owner == null) {
9189                throw new IllegalArgumentException("Unknown owner: " + token);
9190            }
9191
9192            if (uri == null) {
9193                owner.removeUriPermissionsLocked(mode);
9194            } else {
9195                final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9196                owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9197            }
9198        }
9199    }
9200
9201    private void schedulePersistUriGrants() {
9202        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9203            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9204                    10 * DateUtils.SECOND_IN_MILLIS);
9205        }
9206    }
9207
9208    private void writeGrantedUriPermissions() {
9209        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9210
9211        // Snapshot permissions so we can persist without lock
9212        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9213        synchronized (this) {
9214            final int size = mGrantedUriPermissions.size();
9215            for (int i = 0; i < size; i++) {
9216                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9217                for (UriPermission perm : perms.values()) {
9218                    if (perm.persistedModeFlags != 0) {
9219                        persist.add(perm.snapshot());
9220                    }
9221                }
9222            }
9223        }
9224
9225        FileOutputStream fos = null;
9226        try {
9227            fos = mGrantFile.startWrite();
9228
9229            XmlSerializer out = new FastXmlSerializer();
9230            out.setOutput(fos, StandardCharsets.UTF_8.name());
9231            out.startDocument(null, true);
9232            out.startTag(null, TAG_URI_GRANTS);
9233            for (UriPermission.Snapshot perm : persist) {
9234                out.startTag(null, TAG_URI_GRANT);
9235                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9236                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9237                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9238                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9239                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9240                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9241                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9242                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9243                out.endTag(null, TAG_URI_GRANT);
9244            }
9245            out.endTag(null, TAG_URI_GRANTS);
9246            out.endDocument();
9247
9248            mGrantFile.finishWrite(fos);
9249        } catch (IOException e) {
9250            if (fos != null) {
9251                mGrantFile.failWrite(fos);
9252            }
9253        }
9254    }
9255
9256    private void readGrantedUriPermissionsLocked() {
9257        if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9258
9259        final long now = System.currentTimeMillis();
9260
9261        FileInputStream fis = null;
9262        try {
9263            fis = mGrantFile.openRead();
9264            final XmlPullParser in = Xml.newPullParser();
9265            in.setInput(fis, StandardCharsets.UTF_8.name());
9266
9267            int type;
9268            while ((type = in.next()) != END_DOCUMENT) {
9269                final String tag = in.getName();
9270                if (type == START_TAG) {
9271                    if (TAG_URI_GRANT.equals(tag)) {
9272                        final int sourceUserId;
9273                        final int targetUserId;
9274                        final int userHandle = readIntAttribute(in,
9275                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
9276                        if (userHandle != UserHandle.USER_NULL) {
9277                            // For backwards compatibility.
9278                            sourceUserId = userHandle;
9279                            targetUserId = userHandle;
9280                        } else {
9281                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9282                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9283                        }
9284                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9285                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9286                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9287                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9288                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9289                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9290
9291                        // Sanity check that provider still belongs to source package
9292                        // Both direct boot aware and unaware packages are fine as we
9293                        // will do filtering at query time to avoid multiple parsing.
9294                        final ProviderInfo pi = getProviderInfoLocked(
9295                                uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9296                                        | MATCH_DIRECT_BOOT_UNAWARE);
9297                        if (pi != null && sourcePkg.equals(pi.packageName)) {
9298                            int targetUid = -1;
9299                            try {
9300                                targetUid = AppGlobals.getPackageManager().getPackageUid(
9301                                        targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9302                            } catch (RemoteException e) {
9303                            }
9304                            if (targetUid != -1) {
9305                                final UriPermission perm = findOrCreateUriPermissionLocked(
9306                                        sourcePkg, targetPkg, targetUid,
9307                                        new GrantUri(sourceUserId, uri, prefix));
9308                                perm.initPersistedModes(modeFlags, createdTime);
9309                            }
9310                        } else {
9311                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9312                                    + " but instead found " + pi);
9313                        }
9314                    }
9315                }
9316            }
9317        } catch (FileNotFoundException e) {
9318            // Missing grants is okay
9319        } catch (IOException e) {
9320            Slog.wtf(TAG, "Failed reading Uri grants", e);
9321        } catch (XmlPullParserException e) {
9322            Slog.wtf(TAG, "Failed reading Uri grants", e);
9323        } finally {
9324            IoUtils.closeQuietly(fis);
9325        }
9326    }
9327
9328    /**
9329     * @param uri This uri must NOT contain an embedded userId.
9330     * @param userId The userId in which the uri is to be resolved.
9331     */
9332    @Override
9333    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9334        enforceNotIsolatedCaller("takePersistableUriPermission");
9335
9336        Preconditions.checkFlagsArgument(modeFlags,
9337                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9338
9339        synchronized (this) {
9340            final int callingUid = Binder.getCallingUid();
9341            boolean persistChanged = false;
9342            GrantUri grantUri = new GrantUri(userId, uri, false);
9343
9344            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9345                    new GrantUri(userId, uri, false));
9346            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9347                    new GrantUri(userId, uri, true));
9348
9349            final boolean exactValid = (exactPerm != null)
9350                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9351            final boolean prefixValid = (prefixPerm != null)
9352                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9353
9354            if (!(exactValid || prefixValid)) {
9355                throw new SecurityException("No persistable permission grants found for UID "
9356                        + callingUid + " and Uri " + grantUri.toSafeString());
9357            }
9358
9359            if (exactValid) {
9360                persistChanged |= exactPerm.takePersistableModes(modeFlags);
9361            }
9362            if (prefixValid) {
9363                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9364            }
9365
9366            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9367
9368            if (persistChanged) {
9369                schedulePersistUriGrants();
9370            }
9371        }
9372    }
9373
9374    /**
9375     * @param uri This uri must NOT contain an embedded userId.
9376     * @param userId The userId in which the uri is to be resolved.
9377     */
9378    @Override
9379    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9380        enforceNotIsolatedCaller("releasePersistableUriPermission");
9381
9382        Preconditions.checkFlagsArgument(modeFlags,
9383                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9384
9385        synchronized (this) {
9386            final int callingUid = Binder.getCallingUid();
9387            boolean persistChanged = false;
9388
9389            UriPermission exactPerm = findUriPermissionLocked(callingUid,
9390                    new GrantUri(userId, uri, false));
9391            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9392                    new GrantUri(userId, uri, true));
9393            if (exactPerm == null && prefixPerm == null) {
9394                throw new SecurityException("No permission grants found for UID " + callingUid
9395                        + " and Uri " + uri.toSafeString());
9396            }
9397
9398            if (exactPerm != null) {
9399                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9400                removeUriPermissionIfNeededLocked(exactPerm);
9401            }
9402            if (prefixPerm != null) {
9403                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9404                removeUriPermissionIfNeededLocked(prefixPerm);
9405            }
9406
9407            if (persistChanged) {
9408                schedulePersistUriGrants();
9409            }
9410        }
9411    }
9412
9413    /**
9414     * Prune any older {@link UriPermission} for the given UID until outstanding
9415     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9416     *
9417     * @return if any mutations occured that require persisting.
9418     */
9419    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9420        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9421        if (perms == null) return false;
9422        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9423
9424        final ArrayList<UriPermission> persisted = Lists.newArrayList();
9425        for (UriPermission perm : perms.values()) {
9426            if (perm.persistedModeFlags != 0) {
9427                persisted.add(perm);
9428            }
9429        }
9430
9431        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9432        if (trimCount <= 0) return false;
9433
9434        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9435        for (int i = 0; i < trimCount; i++) {
9436            final UriPermission perm = persisted.get(i);
9437
9438            if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9439                    "Trimming grant created at " + perm.persistedCreateTime);
9440
9441            perm.releasePersistableModes(~0);
9442            removeUriPermissionIfNeededLocked(perm);
9443        }
9444
9445        return true;
9446    }
9447
9448    @Override
9449    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9450            String packageName, boolean incoming) {
9451        enforceNotIsolatedCaller("getPersistedUriPermissions");
9452        Preconditions.checkNotNull(packageName, "packageName");
9453
9454        final int callingUid = Binder.getCallingUid();
9455        final int callingUserId = UserHandle.getUserId(callingUid);
9456        final IPackageManager pm = AppGlobals.getPackageManager();
9457        try {
9458            final int packageUid = pm.getPackageUid(packageName,
9459                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9460            if (packageUid != callingUid) {
9461                throw new SecurityException(
9462                        "Package " + packageName + " does not belong to calling UID " + callingUid);
9463            }
9464        } catch (RemoteException e) {
9465            throw new SecurityException("Failed to verify package name ownership");
9466        }
9467
9468        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9469        synchronized (this) {
9470            if (incoming) {
9471                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9472                        callingUid);
9473                if (perms == null) {
9474                    Slog.w(TAG, "No permission grants found for " + packageName);
9475                } else {
9476                    for (UriPermission perm : perms.values()) {
9477                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9478                            result.add(perm.buildPersistedPublicApiObject());
9479                        }
9480                    }
9481                }
9482            } else {
9483                final int size = mGrantedUriPermissions.size();
9484                for (int i = 0; i < size; i++) {
9485                    final ArrayMap<GrantUri, UriPermission> perms =
9486                            mGrantedUriPermissions.valueAt(i);
9487                    for (UriPermission perm : perms.values()) {
9488                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9489                            result.add(perm.buildPersistedPublicApiObject());
9490                        }
9491                    }
9492                }
9493            }
9494        }
9495        return new ParceledListSlice<android.content.UriPermission>(result);
9496    }
9497
9498    @Override
9499    public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9500            String packageName, int userId) {
9501        enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9502                "getGrantedUriPermissions");
9503
9504        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9505        synchronized (this) {
9506            final int size = mGrantedUriPermissions.size();
9507            for (int i = 0; i < size; i++) {
9508                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9509                for (UriPermission perm : perms.values()) {
9510                    if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9511                            && perm.persistedModeFlags != 0) {
9512                        result.add(perm.buildPersistedPublicApiObject());
9513                    }
9514                }
9515            }
9516        }
9517        return new ParceledListSlice<android.content.UriPermission>(result);
9518    }
9519
9520    @Override
9521    public void clearGrantedUriPermissions(String packageName, int userId) {
9522        enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9523                "clearGrantedUriPermissions");
9524        removeUriPermissionsForPackageLocked(packageName, userId, true);
9525    }
9526
9527    @Override
9528    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9529        synchronized (this) {
9530            ProcessRecord app =
9531                who != null ? getRecordForAppLocked(who) : null;
9532            if (app == null) return;
9533
9534            Message msg = Message.obtain();
9535            msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9536            msg.obj = app;
9537            msg.arg1 = waiting ? 1 : 0;
9538            mUiHandler.sendMessage(msg);
9539        }
9540    }
9541
9542    @Override
9543    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9544        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9545        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9546        outInfo.availMem = Process.getFreeMemory();
9547        outInfo.totalMem = Process.getTotalMemory();
9548        outInfo.threshold = homeAppMem;
9549        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9550        outInfo.hiddenAppThreshold = cachedAppMem;
9551        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9552                ProcessList.SERVICE_ADJ);
9553        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9554                ProcessList.VISIBLE_APP_ADJ);
9555        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9556                ProcessList.FOREGROUND_APP_ADJ);
9557    }
9558
9559    // =========================================================
9560    // TASK MANAGEMENT
9561    // =========================================================
9562
9563    @Override
9564    public List<IBinder> getAppTasks(String callingPackage) {
9565        int callingUid = Binder.getCallingUid();
9566        long ident = Binder.clearCallingIdentity();
9567
9568        synchronized(this) {
9569            ArrayList<IBinder> list = new ArrayList<IBinder>();
9570            try {
9571                if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9572
9573                final int N = mRecentTasks.size();
9574                for (int i = 0; i < N; i++) {
9575                    TaskRecord tr = mRecentTasks.get(i);
9576                    // Skip tasks that do not match the caller.  We don't need to verify
9577                    // callingPackage, because we are also limiting to callingUid and know
9578                    // that will limit to the correct security sandbox.
9579                    if (tr.effectiveUid != callingUid) {
9580                        continue;
9581                    }
9582                    Intent intent = tr.getBaseIntent();
9583                    if (intent == null ||
9584                            !callingPackage.equals(intent.getComponent().getPackageName())) {
9585                        continue;
9586                    }
9587                    ActivityManager.RecentTaskInfo taskInfo =
9588                            createRecentTaskInfoFromTaskRecord(tr);
9589                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9590                    list.add(taskImpl.asBinder());
9591                }
9592            } finally {
9593                Binder.restoreCallingIdentity(ident);
9594            }
9595            return list;
9596        }
9597    }
9598
9599    @Override
9600    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9601        final int callingUid = Binder.getCallingUid();
9602        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9603
9604        synchronized(this) {
9605            if (DEBUG_ALL) Slog.v(
9606                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9607
9608            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9609                    callingUid);
9610
9611            // TODO: Improve with MRU list from all ActivityStacks.
9612            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9613        }
9614
9615        return list;
9616    }
9617
9618    /**
9619     * Creates a new RecentTaskInfo from a TaskRecord.
9620     */
9621    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9622        // Update the task description to reflect any changes in the task stack
9623        tr.updateTaskDescription();
9624
9625        // Compose the recent task info
9626        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9627        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9628        rti.persistentId = tr.taskId;
9629        rti.baseIntent = new Intent(tr.getBaseIntent());
9630        rti.origActivity = tr.origActivity;
9631        rti.realActivity = tr.realActivity;
9632        rti.description = tr.lastDescription;
9633        rti.stackId = tr.getStackId();
9634        rti.userId = tr.userId;
9635        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9636        rti.firstActiveTime = tr.firstActiveTime;
9637        rti.lastActiveTime = tr.lastActiveTime;
9638        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9639        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9640        rti.numActivities = 0;
9641        if (tr.mBounds != null) {
9642            rti.bounds = new Rect(tr.mBounds);
9643        }
9644        rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9645        rti.resizeMode = tr.mResizeMode;
9646
9647        ActivityRecord base = null;
9648        ActivityRecord top = null;
9649        ActivityRecord tmp;
9650
9651        for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9652            tmp = tr.mActivities.get(i);
9653            if (tmp.finishing) {
9654                continue;
9655            }
9656            base = tmp;
9657            if (top == null || (top.state == ActivityState.INITIALIZING)) {
9658                top = base;
9659            }
9660            rti.numActivities++;
9661        }
9662
9663        rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9664        rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9665
9666        return rti;
9667    }
9668
9669    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9670        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9671                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9672        if (!allowed) {
9673            if (checkPermission(android.Manifest.permission.GET_TASKS,
9674                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9675                // Temporary compatibility: some existing apps on the system image may
9676                // still be requesting the old permission and not switched to the new
9677                // one; if so, we'll still allow them full access.  This means we need
9678                // to see if they are holding the old permission and are a system app.
9679                try {
9680                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9681                        allowed = true;
9682                        if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9683                                + " is using old GET_TASKS but privileged; allowing");
9684                    }
9685                } catch (RemoteException e) {
9686                }
9687            }
9688        }
9689        if (!allowed) {
9690            if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9691                    + " does not hold REAL_GET_TASKS; limiting output");
9692        }
9693        return allowed;
9694    }
9695
9696    @Override
9697    public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9698            int userId) {
9699        final int callingUid = Binder.getCallingUid();
9700        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9701                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9702
9703        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9704        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9705        synchronized (this) {
9706            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9707                    callingUid);
9708            final boolean detailed = checkCallingPermission(
9709                    android.Manifest.permission.GET_DETAILED_TASKS)
9710                    == PackageManager.PERMISSION_GRANTED;
9711
9712            if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9713                Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9714                return ParceledListSlice.emptyList();
9715            }
9716            mRecentTasks.loadUserRecentsLocked(userId);
9717
9718            final int recentsCount = mRecentTasks.size();
9719            ArrayList<ActivityManager.RecentTaskInfo> res =
9720                    new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9721
9722            final Set<Integer> includedUsers;
9723            if (includeProfiles) {
9724                includedUsers = mUserController.getProfileIds(userId);
9725            } else {
9726                includedUsers = new HashSet<>();
9727            }
9728            includedUsers.add(Integer.valueOf(userId));
9729
9730            for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9731                TaskRecord tr = mRecentTasks.get(i);
9732                // Only add calling user or related users recent tasks
9733                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9734                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9735                    continue;
9736                }
9737
9738                if (tr.realActivitySuspended) {
9739                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9740                    continue;
9741                }
9742
9743                // Return the entry if desired by the caller.  We always return
9744                // the first entry, because callers always expect this to be the
9745                // foreground app.  We may filter others if the caller has
9746                // not supplied RECENT_WITH_EXCLUDED and there is some reason
9747                // we should exclude the entry.
9748
9749                if (i == 0
9750                        || withExcluded
9751                        || (tr.intent == null)
9752                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9753                                == 0)) {
9754                    if (!allowed) {
9755                        // If the caller doesn't have the GET_TASKS permission, then only
9756                        // allow them to see a small subset of tasks -- their own and home.
9757                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9758                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9759                            continue;
9760                        }
9761                    }
9762                    final ActivityStack stack = tr.getStack();
9763                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9764                        if (stack != null && stack.isHomeOrRecentsStack()) {
9765                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9766                                    "Skipping, home or recents stack task: " + tr);
9767                            continue;
9768                        }
9769                    }
9770                    if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9771                        if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9772                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9773                                    "Skipping, top task in docked stack: " + tr);
9774                            continue;
9775                        }
9776                    }
9777                    if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9778                        if (stack != null && stack.isPinnedStack()) {
9779                            if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9780                                    "Skipping, pinned stack task: " + tr);
9781                            continue;
9782                        }
9783                    }
9784                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9785                        // Don't include auto remove tasks that are finished or finishing.
9786                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9787                                "Skipping, auto-remove without activity: " + tr);
9788                        continue;
9789                    }
9790                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9791                            && !tr.isAvailable) {
9792                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9793                                "Skipping, unavail real act: " + tr);
9794                        continue;
9795                    }
9796
9797                    if (!tr.mUserSetupComplete) {
9798                        // Don't include task launched while user is not done setting-up.
9799                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9800                                "Skipping, user setup not complete: " + tr);
9801                        continue;
9802                    }
9803
9804                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9805                    if (!detailed) {
9806                        rti.baseIntent.replaceExtras((Bundle)null);
9807                    }
9808
9809                    res.add(rti);
9810                    maxNum--;
9811                }
9812            }
9813            return new ParceledListSlice<>(res);
9814        }
9815    }
9816
9817    @Override
9818    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9819        synchronized (this) {
9820            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9821                    "getTaskThumbnail()");
9822            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9823                    id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9824            if (tr != null) {
9825                return tr.getTaskThumbnailLocked();
9826            }
9827        }
9828        return null;
9829    }
9830
9831    @Override
9832    public ActivityManager.TaskDescription getTaskDescription(int id) {
9833        synchronized (this) {
9834            enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9835                    "getTaskDescription()");
9836            final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
9837                    MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9838            if (tr != null) {
9839                return tr.lastTaskDescription;
9840            }
9841        }
9842        return null;
9843    }
9844
9845    @Override
9846    public int addAppTask(IBinder activityToken, Intent intent,
9847            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9848        final int callingUid = Binder.getCallingUid();
9849        final long callingIdent = Binder.clearCallingIdentity();
9850
9851        try {
9852            synchronized (this) {
9853                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9854                if (r == null) {
9855                    throw new IllegalArgumentException("Activity does not exist; token="
9856                            + activityToken);
9857                }
9858                ComponentName comp = intent.getComponent();
9859                if (comp == null) {
9860                    throw new IllegalArgumentException("Intent " + intent
9861                            + " must specify explicit component");
9862                }
9863                if (thumbnail.getWidth() != mThumbnailWidth
9864                        || thumbnail.getHeight() != mThumbnailHeight) {
9865                    throw new IllegalArgumentException("Bad thumbnail size: got "
9866                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9867                            + mThumbnailWidth + "x" + mThumbnailHeight);
9868                }
9869                if (intent.getSelector() != null) {
9870                    intent.setSelector(null);
9871                }
9872                if (intent.getSourceBounds() != null) {
9873                    intent.setSourceBounds(null);
9874                }
9875                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9876                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9877                        // The caller has added this as an auto-remove task...  that makes no
9878                        // sense, so turn off auto-remove.
9879                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9880                    }
9881                }
9882                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9883                    mLastAddedTaskActivity = null;
9884                }
9885                ActivityInfo ainfo = mLastAddedTaskActivity;
9886                if (ainfo == null) {
9887                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9888                            comp, 0, UserHandle.getUserId(callingUid));
9889                    if (ainfo.applicationInfo.uid != callingUid) {
9890                        throw new SecurityException(
9891                                "Can't add task for another application: target uid="
9892                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9893                    }
9894                }
9895
9896                TaskRecord task = new TaskRecord(this,
9897                        mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9898                        ainfo, intent, description, new TaskThumbnailInfo());
9899
9900                int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9901                if (trimIdx >= 0) {
9902                    // If this would have caused a trim, then we'll abort because that
9903                    // means it would be added at the end of the list but then just removed.
9904                    return INVALID_TASK_ID;
9905                }
9906
9907                final int N = mRecentTasks.size();
9908                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9909                    final TaskRecord tr = mRecentTasks.remove(N - 1);
9910                    tr.removedFromRecents();
9911                }
9912
9913                task.inRecents = true;
9914                mRecentTasks.add(task);
9915                r.getStack().addTask(task, false, "addAppTask");
9916
9917                task.setLastThumbnailLocked(thumbnail);
9918                task.freeLastThumbnail();
9919                return task.taskId;
9920            }
9921        } finally {
9922            Binder.restoreCallingIdentity(callingIdent);
9923        }
9924    }
9925
9926    @Override
9927    public Point getAppTaskThumbnailSize() {
9928        synchronized (this) {
9929            return new Point(mThumbnailWidth,  mThumbnailHeight);
9930        }
9931    }
9932
9933    @Override
9934    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9935        synchronized (this) {
9936            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9937            if (r != null) {
9938                r.setTaskDescription(td);
9939                r.task.updateTaskDescription();
9940                mTaskChangeNotificationController.notifyTaskDescriptionChanged(r.task.taskId, td);
9941            }
9942        }
9943    }
9944
9945    @Override
9946    public void setTaskResizeable(int taskId, int resizeableMode) {
9947        synchronized (this) {
9948            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9949                    taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
9950            if (task == null) {
9951                Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9952                return;
9953            }
9954            task.setResizeMode(resizeableMode);
9955        }
9956    }
9957
9958    @Override
9959    public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9960        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9961        long ident = Binder.clearCallingIdentity();
9962        try {
9963            synchronized (this) {
9964                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9965                if (task == null) {
9966                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9967                    return;
9968                }
9969                // Place the task in the right stack if it isn't there already based on
9970                // the requested bounds.
9971                // The stack transition logic is:
9972                // - a null bounds on a freeform task moves that task to fullscreen
9973                // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9974                //   that task to freeform
9975                // - otherwise the task is not moved
9976                int stackId = task.getStackId();
9977                if (!StackId.isTaskResizeAllowed(stackId)) {
9978                    throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9979                }
9980                if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9981                    stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9982                } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9983                    stackId = FREEFORM_WORKSPACE_STACK_ID;
9984                }
9985
9986                // Reparent the task to the right stack if necessary
9987                boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9988                if (stackId != task.getStackId()) {
9989                    // Defer resume until the task is resized below
9990                    task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
9991                            DEFER_RESUME, "resizeTask");
9992                    preserveWindow = false;
9993                }
9994
9995                // After reparenting (which only resizes the task to the stack bounds), resize the
9996                // task to the actual bounds provided
9997                task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
9998            }
9999        } finally {
10000            Binder.restoreCallingIdentity(ident);
10001        }
10002    }
10003
10004    @Override
10005    public Rect getTaskBounds(int taskId) {
10006        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10007        long ident = Binder.clearCallingIdentity();
10008        Rect rect = new Rect();
10009        try {
10010            synchronized (this) {
10011                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10012                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10013                if (task == null) {
10014                    Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10015                    return rect;
10016                }
10017                if (task.getStack() != null) {
10018                    // Return the bounds from window manager since it will be adjusted for various
10019                    // things like the presense of a docked stack for tasks that aren't resizeable.
10020                    task.getWindowContainerBounds(rect);
10021                } else {
10022                    // Task isn't in window manager yet since it isn't associated with a stack.
10023                    // Return the persist value from activity manager
10024                    if (task.mBounds != null) {
10025                        rect.set(task.mBounds);
10026                    } else if (task.mLastNonFullscreenBounds != null) {
10027                        rect.set(task.mLastNonFullscreenBounds);
10028                    }
10029                }
10030            }
10031        } finally {
10032            Binder.restoreCallingIdentity(ident);
10033        }
10034        return rect;
10035    }
10036
10037    @Override
10038    public void cancelTaskWindowTransition(int taskId) {
10039        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10040        final long ident = Binder.clearCallingIdentity();
10041        try {
10042            synchronized (this) {
10043                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10044                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10045                if (task == null) {
10046                    Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10047                    return;
10048                }
10049                task.cancelWindowTransition();
10050            }
10051        } finally {
10052            Binder.restoreCallingIdentity(ident);
10053        }
10054    }
10055
10056    @Override
10057    public void cancelTaskThumbnailTransition(int taskId) {
10058        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10059        final long ident = Binder.clearCallingIdentity();
10060        try {
10061            synchronized (this) {
10062                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10063                        MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10064                if (task == null) {
10065                    Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10066                    return;
10067                }
10068                task.cancelThumbnailTransition();
10069            }
10070        } finally {
10071            Binder.restoreCallingIdentity(ident);
10072        }
10073    }
10074
10075    @Override
10076    public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10077        enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10078        final long ident = Binder.clearCallingIdentity();
10079        try {
10080            final TaskRecord task;
10081            synchronized (this) {
10082                task = mStackSupervisor.anyTaskForIdLocked(taskId,
10083                        MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10084                if (task == null) {
10085                    Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10086                    return null;
10087                }
10088            }
10089            // Don't call this while holding the lock as this operation might hit the disk.
10090            return task.getSnapshot(reducedResolution);
10091        } finally {
10092            Binder.restoreCallingIdentity(ident);
10093        }
10094    }
10095
10096    @Override
10097    public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10098        if (userId != UserHandle.getCallingUserId()) {
10099            enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10100                    "getTaskDescriptionIcon");
10101        }
10102        final File passedIconFile = new File(filePath);
10103        final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10104                passedIconFile.getName());
10105        if (!legitIconFile.getPath().equals(filePath)
10106                || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10107            throw new IllegalArgumentException("Bad file path: " + filePath
10108                    + " passed for userId " + userId);
10109        }
10110        return mRecentTasks.getTaskDescriptionIcon(filePath);
10111    }
10112
10113    @Override
10114    public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10115            throws RemoteException {
10116        final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10117        if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10118                activityOptions.getCustomInPlaceResId() == 0) {
10119            throw new IllegalArgumentException("Expected in-place ActivityOption " +
10120                    "with valid animation");
10121        }
10122        mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10123        mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10124                activityOptions.getCustomInPlaceResId());
10125        mWindowManager.executeAppTransition();
10126    }
10127
10128    private void removeTasksByPackageNameLocked(String packageName, int userId) {
10129        // Remove all tasks with activities in the specified package from the list of recent tasks
10130        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10131            TaskRecord tr = mRecentTasks.get(i);
10132            if (tr.userId != userId) continue;
10133
10134            ComponentName cn = tr.intent.getComponent();
10135            if (cn != null && cn.getPackageName().equals(packageName)) {
10136                // If the package name matches, remove the task.
10137                mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10138            }
10139        }
10140    }
10141
10142    private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10143            int userId) {
10144
10145        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10146            TaskRecord tr = mRecentTasks.get(i);
10147            if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10148                continue;
10149            }
10150
10151            ComponentName cn = tr.intent.getComponent();
10152            final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10153                    && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10154            if (sameComponent) {
10155                mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10156            }
10157        }
10158    }
10159
10160    @Override
10161    public void removeStack(int stackId) {
10162        enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10163        if (StackId.isHomeOrRecentsStack(stackId)) {
10164            throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10165        }
10166
10167        synchronized (this) {
10168            final long ident = Binder.clearCallingIdentity();
10169            try {
10170                mStackSupervisor.removeStackLocked(stackId);
10171            } finally {
10172                Binder.restoreCallingIdentity(ident);
10173            }
10174        }
10175    }
10176
10177    @Override
10178    public void moveStackToDisplay(int stackId, int displayId) {
10179        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
10180
10181        synchronized (this) {
10182            final long ident = Binder.clearCallingIdentity();
10183            try {
10184                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10185                        + " to displayId=" + displayId);
10186                mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10187            } finally {
10188                Binder.restoreCallingIdentity(ident);
10189            }
10190        }
10191    }
10192
10193    @Override
10194    public boolean removeTask(int taskId) {
10195        enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10196        synchronized (this) {
10197            final long ident = Binder.clearCallingIdentity();
10198            try {
10199                return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10200            } finally {
10201                Binder.restoreCallingIdentity(ident);
10202            }
10203        }
10204    }
10205
10206    /**
10207     * TODO: Add mController hook
10208     */
10209    @Override
10210    public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10211        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10212
10213        if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10214        synchronized(this) {
10215            moveTaskToFrontLocked(taskId, flags, bOptions);
10216        }
10217    }
10218
10219    void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
10220        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10221
10222        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10223                Binder.getCallingUid(), -1, -1, "Task to front")) {
10224            ActivityOptions.abort(options);
10225            return;
10226        }
10227        final long origId = Binder.clearCallingIdentity();
10228        try {
10229            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10230            if (task == null) {
10231                Slog.d(TAG, "Could not find task for id: "+ taskId);
10232                return;
10233            }
10234            if (mStackSupervisor.isLockTaskModeViolation(task)) {
10235                mStackSupervisor.showLockTaskToast();
10236                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10237                return;
10238            }
10239            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10240            if (prev != null) {
10241                task.setTaskToReturnTo(prev);
10242            }
10243            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10244                    false /* forceNonResizable */);
10245
10246            final ActivityRecord topActivity = task.getTopActivity();
10247            if (topActivity != null) {
10248
10249                // We are reshowing a task, use a starting window to hide the initial draw delay
10250                // so the transition can start earlier.
10251                topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10252                        true /* taskSwitch */);
10253            }
10254        } finally {
10255            Binder.restoreCallingIdentity(origId);
10256        }
10257        ActivityOptions.abort(options);
10258    }
10259
10260    /**
10261     * Attempts to move a task backwards in z-order (the order of activities within the task is
10262     * unchanged).
10263     *
10264     * There are several possible results of this call:
10265     * - if the task is locked, then we will show the lock toast
10266     * - if there is a task behind the provided task, then that task is made visible and resumed as
10267     *   this task is moved to the back
10268     * - otherwise, if there are no other tasks in the stack:
10269     *     - if this task is in the pinned stack, then we remove the stack completely, which will
10270     *       have the effect of moving the task to the top or bottom of the fullscreen stack
10271     *       (depending on whether it is visible)
10272     *     - otherwise, we simply return home and hide this task
10273     *
10274     * @param token A reference to the activity we wish to move
10275     * @param nonRoot If false then this only works if the activity is the root
10276     *                of a task; if true it will work for any activity in a task.
10277     * @return Returns true if the move completed, false if not.
10278     */
10279    @Override
10280    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10281        enforceNotIsolatedCaller("moveActivityTaskToBack");
10282        synchronized(this) {
10283            final long origId = Binder.clearCallingIdentity();
10284            try {
10285                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10286                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10287                if (task != null) {
10288                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10289                }
10290            } finally {
10291                Binder.restoreCallingIdentity(origId);
10292            }
10293        }
10294        return false;
10295    }
10296
10297    @Override
10298    public void moveTaskBackwards(int task) {
10299        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10300                "moveTaskBackwards()");
10301
10302        synchronized(this) {
10303            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10304                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
10305                return;
10306            }
10307            final long origId = Binder.clearCallingIdentity();
10308            moveTaskBackwardsLocked(task);
10309            Binder.restoreCallingIdentity(origId);
10310        }
10311    }
10312
10313    private final void moveTaskBackwardsLocked(int task) {
10314        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10315    }
10316
10317    @Override
10318    public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
10319            IActivityContainerCallback callback) throws RemoteException {
10320        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
10321        synchronized (this) {
10322            if (parentActivityToken == null) {
10323                throw new IllegalArgumentException("parent token must not be null");
10324            }
10325            ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
10326            if (r == null) {
10327                return null;
10328            }
10329            if (callback == null) {
10330                throw new IllegalArgumentException("callback must not be null");
10331            }
10332            return mStackSupervisor.createVirtualActivityContainer(r, callback);
10333        }
10334    }
10335
10336    @Override
10337    public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
10338        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10339        synchronized (this) {
10340            final int stackId = mStackSupervisor.getNextStackId();
10341            final ActivityStack stack =
10342                    mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10343            if (stack == null) {
10344                return null;
10345            }
10346            return stack.mActivityContainer;
10347        }
10348    }
10349
10350    @Override
10351    public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10352        synchronized (this) {
10353            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10354            if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
10355                return stack.mActivityContainer.getDisplayId();
10356            }
10357            return DEFAULT_DISPLAY;
10358        }
10359    }
10360
10361    @Override
10362    public int getActivityStackId(IBinder token) throws RemoteException {
10363        synchronized (this) {
10364            ActivityStack stack = ActivityRecord.getStackLocked(token);
10365            if (stack == null) {
10366                return INVALID_STACK_ID;
10367            }
10368            return stack.mStackId;
10369        }
10370    }
10371
10372    @Override
10373    public void exitFreeformMode(IBinder token) throws RemoteException {
10374        synchronized (this) {
10375            long ident = Binder.clearCallingIdentity();
10376            try {
10377                final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10378                if (r == null) {
10379                    throw new IllegalArgumentException(
10380                            "exitFreeformMode: No activity record matching token=" + token);
10381                }
10382
10383                final ActivityStack stack = r.getStack();
10384                if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10385                    throw new IllegalStateException(
10386                            "exitFreeformMode: You can only go fullscreen from freeform.");
10387                }
10388
10389                if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10390                r.task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT,
10391                        ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10392            } finally {
10393                Binder.restoreCallingIdentity(ident);
10394            }
10395        }
10396    }
10397
10398    @Override
10399    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10400        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10401        if (StackId.isHomeOrRecentsStack(stackId)) {
10402            throw new IllegalArgumentException(
10403                    "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10404        }
10405        synchronized (this) {
10406            long ident = Binder.clearCallingIdentity();
10407            try {
10408                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10409                if (task == null) {
10410                    Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10411                    return;
10412                }
10413
10414                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10415                        + " to stackId=" + stackId + " toTop=" + toTop);
10416                if (stackId == DOCKED_STACK_ID) {
10417                    mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10418                            null /* initialBounds */);
10419                }
10420                task.reparent(stackId, toTop,
10421                        REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10422            } finally {
10423                Binder.restoreCallingIdentity(ident);
10424            }
10425        }
10426    }
10427
10428    @Override
10429    public void swapDockedAndFullscreenStack() throws RemoteException {
10430        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10431        synchronized (this) {
10432            long ident = Binder.clearCallingIdentity();
10433            try {
10434                final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10435                        FULLSCREEN_WORKSPACE_STACK_ID);
10436                final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10437                        : null;
10438                final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10439                final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10440                        : null;
10441                if (topTask == null || tasks == null || tasks.size() == 0) {
10442                    Slog.w(TAG,
10443                            "Unable to swap tasks, either docked or fullscreen stack is empty.");
10444                    return;
10445                }
10446
10447                // TODO: App transition
10448                mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10449
10450                // Defer the resume until we move all the docked tasks to the fullscreen stack below
10451                topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10452                        DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10453                final int size = tasks.size();
10454                for (int i = 0; i < size; i++) {
10455                    final int id = tasks.get(i).taskId;
10456                    if (id == topTask.taskId) {
10457                        continue;
10458                    }
10459
10460                    // Defer the resume until after all the tasks have been moved
10461                    tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10462                            REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10463                            "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10464                }
10465
10466                // Because we deferred the resume to avoid conflicts with stack switches while
10467                // resuming, we need to do it after all the tasks are moved.
10468                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10469                mStackSupervisor.resumeFocusedStackTopActivityLocked();
10470
10471                mWindowManager.executeAppTransition();
10472            } finally {
10473                Binder.restoreCallingIdentity(ident);
10474            }
10475        }
10476    }
10477
10478    /**
10479     * Moves the input task to the docked stack.
10480     *
10481     * @param taskId Id of task to move.
10482     * @param createMode The mode the docked stack should be created in if it doesn't exist
10483     *                   already. See
10484     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10485     *                   and
10486     *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10487     * @param toTop If the task and stack should be moved to the top.
10488     * @param animate Whether we should play an animation for the moving the task
10489     * @param initialBounds If the docked stack gets created, it will use these bounds for the
10490     *                      docked stack. Pass {@code null} to use default bounds.
10491     */
10492    @Override
10493    public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10494            Rect initialBounds) {
10495        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10496        synchronized (this) {
10497            long ident = Binder.clearCallingIdentity();
10498            try {
10499                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10500                if (task == null) {
10501                    Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10502                    return false;
10503                }
10504
10505                if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10506                        + " to createMode=" + createMode + " toTop=" + toTop);
10507                mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10508
10509                // Defer resuming until we move the home stack to the front below
10510                final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10511                        REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10512                        "moveTaskToDockedStack");
10513                if (moved) {
10514                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10515                }
10516                return moved;
10517            } finally {
10518                Binder.restoreCallingIdentity(ident);
10519            }
10520        }
10521    }
10522
10523    /**
10524     * Moves the top activity in the input stackId to the pinned stack.
10525     *
10526     * @param stackId Id of stack to move the top activity to pinned stack.
10527     * @param bounds Bounds to use for pinned stack.
10528     *
10529     * @return True if the top activity of the input stack was successfully moved to the pinned
10530     *          stack.
10531     */
10532    @Override
10533    public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10534        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10535        synchronized (this) {
10536            if (!mSupportsPictureInPicture) {
10537                throw new IllegalStateException("moveTopActivityToPinnedStack:"
10538                        + "Device doesn't support picture-in-picture mode");
10539            }
10540
10541            long ident = Binder.clearCallingIdentity();
10542            try {
10543                return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10544            } finally {
10545                Binder.restoreCallingIdentity(ident);
10546            }
10547        }
10548    }
10549
10550    @Override
10551    public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10552            boolean preserveWindows, boolean animate, int animationDuration) {
10553        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10554        long ident = Binder.clearCallingIdentity();
10555        try {
10556            synchronized (this) {
10557                if (animate) {
10558                    if (stackId == PINNED_STACK_ID) {
10559                        final PinnedActivityStack pinnedStack =
10560                                mStackSupervisor.getStack(PINNED_STACK_ID);
10561                        pinnedStack.animateResizePinnedStack(null /* sourceBounds */, destBounds,
10562                                animationDuration);
10563                    } else {
10564                        throw new IllegalArgumentException("Stack: " + stackId
10565                                + " doesn't support animated resize.");
10566                    }
10567                } else {
10568                    mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10569                            null /* tempTaskInsetBounds */, preserveWindows,
10570                            allowResizeInDockedMode, !DEFER_RESUME);
10571                }
10572            }
10573        } finally {
10574            Binder.restoreCallingIdentity(ident);
10575        }
10576    }
10577
10578    @Override
10579    public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10580            Rect tempDockedTaskInsetBounds,
10581            Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10582        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10583                "resizeDockedStack()");
10584        long ident = Binder.clearCallingIdentity();
10585        try {
10586            synchronized (this) {
10587                mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10588                        tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10589                        PRESERVE_WINDOWS);
10590            }
10591        } finally {
10592            Binder.restoreCallingIdentity(ident);
10593        }
10594    }
10595
10596    @Override
10597    public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10598        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10599                "resizePinnedStack()");
10600        final long ident = Binder.clearCallingIdentity();
10601        try {
10602            synchronized (this) {
10603                mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10604            }
10605        } finally {
10606            Binder.restoreCallingIdentity(ident);
10607        }
10608    }
10609
10610    /**
10611     * Try to place task to provided position. The final position might be different depending on
10612     * current user and stacks state. The task will be moved to target stack if it's currently in
10613     * different stack.
10614     */
10615    @Override
10616    public void positionTaskInStack(int taskId, int stackId, int position) {
10617        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10618        if (StackId.isHomeOrRecentsStack(stackId)) {
10619            throw new IllegalArgumentException(
10620                    "positionTaskInStack: Attempt to change the position of task "
10621                    + taskId + " in/to home/recents stack");
10622        }
10623        synchronized (this) {
10624            long ident = Binder.clearCallingIdentity();
10625            try {
10626                if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10627                        + taskId + " in stackId=" + stackId + " at position=" + position);
10628                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10629                if (task == null) {
10630                    throw new IllegalArgumentException("positionTaskInStack: no task for id="
10631                            + taskId);
10632                }
10633
10634                final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10635                        !ON_TOP);
10636
10637                // TODO: Have the callers of this API call a separate reparent method if that is
10638                // what they intended to do vs. having this method also do reparenting.
10639                if (task.getStack() == stack) {
10640                    // Change position in current stack.
10641                    stack.positionChildAt(task, position);
10642                } else {
10643                    // Reparent to new stack.
10644                    task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10645                            !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10646                }
10647            } finally {
10648                Binder.restoreCallingIdentity(ident);
10649            }
10650        }
10651    }
10652
10653    @Override
10654    public List<StackInfo> getAllStackInfos() {
10655        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10656        long ident = Binder.clearCallingIdentity();
10657        try {
10658            synchronized (this) {
10659                return mStackSupervisor.getAllStackInfosLocked();
10660            }
10661        } finally {
10662            Binder.restoreCallingIdentity(ident);
10663        }
10664    }
10665
10666    @Override
10667    public StackInfo getStackInfo(int stackId) {
10668        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10669        long ident = Binder.clearCallingIdentity();
10670        try {
10671            synchronized (this) {
10672                return mStackSupervisor.getStackInfoLocked(stackId);
10673            }
10674        } finally {
10675            Binder.restoreCallingIdentity(ident);
10676        }
10677    }
10678
10679    @Override
10680    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10681        synchronized(this) {
10682            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10683        }
10684    }
10685
10686    @Override
10687    public void updateDeviceOwner(String packageName) {
10688        final int callingUid = Binder.getCallingUid();
10689        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10690            throw new SecurityException("updateDeviceOwner called from non-system process");
10691        }
10692        synchronized (this) {
10693            mDeviceOwnerName = packageName;
10694        }
10695    }
10696
10697    @Override
10698    public void updateLockTaskPackages(int userId, String[] packages) {
10699        final int callingUid = Binder.getCallingUid();
10700        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10701            enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10702                    "updateLockTaskPackages()");
10703        }
10704        synchronized (this) {
10705            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10706                    Arrays.toString(packages));
10707            mLockTaskPackages.put(userId, packages);
10708            mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10709        }
10710    }
10711
10712
10713    void startLockTaskModeLocked(TaskRecord task) {
10714        if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10715        if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10716            return;
10717        }
10718
10719        // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10720        // is initiated by system after the pinning request was shown and locked mode is initiated
10721        // by an authorized app directly
10722        final int callingUid = Binder.getCallingUid();
10723        boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10724        long ident = Binder.clearCallingIdentity();
10725        try {
10726            if (!isSystemInitiated) {
10727                task.mLockTaskUid = callingUid;
10728                if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10729                    // startLockTask() called by app and task mode is lockTaskModeDefault.
10730                    if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10731                    StatusBarManagerInternal statusBarManager =
10732                            LocalServices.getService(StatusBarManagerInternal.class);
10733                    if (statusBarManager != null) {
10734                        statusBarManager.showScreenPinningRequest(task.taskId);
10735                    }
10736                    return;
10737                }
10738
10739                final ActivityStack stack = mStackSupervisor.getFocusedStack();
10740                if (stack == null || task != stack.topTask()) {
10741                    throw new IllegalArgumentException("Invalid task, not in foreground");
10742                }
10743            }
10744            if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10745                    "Locking fully");
10746            mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10747                    ActivityManager.LOCK_TASK_MODE_PINNED :
10748                    ActivityManager.LOCK_TASK_MODE_LOCKED,
10749                    "startLockTask", true);
10750        } finally {
10751            Binder.restoreCallingIdentity(ident);
10752        }
10753    }
10754
10755    @Override
10756    public void startLockTaskModeById(int taskId) {
10757        synchronized (this) {
10758            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10759            if (task != null) {
10760                startLockTaskModeLocked(task);
10761            }
10762        }
10763    }
10764
10765    @Override
10766    public void startLockTaskModeByToken(IBinder token) {
10767        synchronized (this) {
10768            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10769            if (r == null) {
10770                return;
10771            }
10772            final TaskRecord task = r.task;
10773            if (task != null) {
10774                startLockTaskModeLocked(task);
10775            }
10776        }
10777    }
10778
10779    @Override
10780    public void startSystemLockTaskMode(int taskId) throws RemoteException {
10781        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10782        // This makes inner call to look as if it was initiated by system.
10783        long ident = Binder.clearCallingIdentity();
10784        try {
10785            synchronized (this) {
10786                startLockTaskModeById(taskId);
10787            }
10788        } finally {
10789            Binder.restoreCallingIdentity(ident);
10790        }
10791    }
10792
10793    @Override
10794    public void stopLockTaskMode() {
10795        final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10796        if (lockTask == null) {
10797            // Our work here is done.
10798            return;
10799        }
10800
10801        final int callingUid = Binder.getCallingUid();
10802        final int lockTaskUid = lockTask.mLockTaskUid;
10803        final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10804        if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10805            // Done.
10806            return;
10807        } else {
10808            // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10809            // It is possible lockTaskMode was started by the system process because
10810            // android:lockTaskMode is set to a locking value in the application manifest
10811            // instead of the app calling startLockTaskMode. In this case
10812            // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10813            // {@link TaskRecord.effectiveUid} instead. Also caller with
10814            // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10815            if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10816                    && callingUid != lockTaskUid
10817                    && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10818                throw new SecurityException("Invalid uid, expected " + lockTaskUid
10819                        + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10820            }
10821        }
10822        long ident = Binder.clearCallingIdentity();
10823        try {
10824            Log.d(TAG, "stopLockTaskMode");
10825            // Stop lock task
10826            synchronized (this) {
10827                mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10828                        "stopLockTask", true);
10829            }
10830            TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10831            if (tm != null) {
10832                tm.showInCallScreen(false);
10833            }
10834        } finally {
10835            Binder.restoreCallingIdentity(ident);
10836        }
10837    }
10838
10839    /**
10840     * This API should be called by SystemUI only when user perform certain action to dismiss
10841     * lock task mode. We should only dismiss pinned lock task mode in this case.
10842     */
10843    @Override
10844    public void stopSystemLockTaskMode() throws RemoteException {
10845        if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10846            stopLockTaskMode();
10847        } else {
10848            mStackSupervisor.showLockTaskToast();
10849        }
10850    }
10851
10852    @Override
10853    public boolean isInLockTaskMode() {
10854        return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10855    }
10856
10857    @Override
10858    public int getLockTaskModeState() {
10859        synchronized (this) {
10860            return mStackSupervisor.getLockTaskModeState();
10861        }
10862    }
10863
10864    @Override
10865    public void showLockTaskEscapeMessage(IBinder token) {
10866        synchronized (this) {
10867            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10868            if (r == null) {
10869                return;
10870            }
10871            mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10872        }
10873    }
10874
10875    @Override
10876    public void setDisablePreviewScreenshots(IBinder token, boolean disable)
10877            throws RemoteException {
10878        synchronized (this) {
10879            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10880            if (r == null) {
10881                Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
10882                        + token);
10883                return;
10884            }
10885            final long origId = Binder.clearCallingIdentity();
10886            try {
10887                r.setDisablePreviewScreenshots(disable);
10888            } finally {
10889                Binder.restoreCallingIdentity(origId);
10890            }
10891        }
10892    }
10893
10894    // =========================================================
10895    // CONTENT PROVIDERS
10896    // =========================================================
10897
10898    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10899        List<ProviderInfo> providers = null;
10900        try {
10901            providers = AppGlobals.getPackageManager()
10902                    .queryContentProviders(app.processName, app.uid,
10903                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10904                                    | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
10905                    .getList();
10906        } catch (RemoteException ex) {
10907        }
10908        if (DEBUG_MU) Slog.v(TAG_MU,
10909                "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10910        int userId = app.userId;
10911        if (providers != null) {
10912            int N = providers.size();
10913            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10914            for (int i=0; i<N; i++) {
10915                // TODO: keep logic in sync with installEncryptionUnawareProviders
10916                ProviderInfo cpi =
10917                    (ProviderInfo)providers.get(i);
10918                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10919                        cpi.name, cpi.flags);
10920                if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10921                    // This is a singleton provider, but a user besides the
10922                    // default user is asking to initialize a process it runs
10923                    // in...  well, no, it doesn't actually run in this process,
10924                    // it runs in the process of the default user.  Get rid of it.
10925                    providers.remove(i);
10926                    N--;
10927                    i--;
10928                    continue;
10929                }
10930
10931                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10932                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10933                if (cpr == null) {
10934                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10935                    mProviderMap.putProviderByClass(comp, cpr);
10936                }
10937                if (DEBUG_MU) Slog.v(TAG_MU,
10938                        "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10939                app.pubProviders.put(cpi.name, cpr);
10940                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10941                    // Don't add this if it is a platform component that is marked
10942                    // to run in multiple processes, because this is actually
10943                    // part of the framework so doesn't make sense to track as a
10944                    // separate apk in the process.
10945                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10946                            mProcessStats);
10947                }
10948                notifyPackageUse(cpi.applicationInfo.packageName,
10949                                 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10950            }
10951        }
10952        return providers;
10953    }
10954
10955    /**
10956     * Check if the calling UID has a possible chance at accessing the provider
10957     * at the given authority and user.
10958     */
10959    public String checkContentProviderAccess(String authority, int userId) {
10960        if (userId == UserHandle.USER_ALL) {
10961            mContext.enforceCallingOrSelfPermission(
10962                    Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10963            userId = UserHandle.getCallingUserId();
10964        }
10965
10966        ProviderInfo cpi = null;
10967        try {
10968            cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10969                    STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10970                            | PackageManager.MATCH_DISABLED_COMPONENTS
10971                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
10972                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10973                    userId);
10974        } catch (RemoteException ignored) {
10975        }
10976        if (cpi == null) {
10977            return "Failed to find provider " + authority + " for user " + userId
10978                    + "; expected to find a valid ContentProvider for this authority";
10979        }
10980
10981        ProcessRecord r = null;
10982        synchronized (mPidsSelfLocked) {
10983            r = mPidsSelfLocked.get(Binder.getCallingPid());
10984        }
10985        if (r == null) {
10986            return "Failed to find PID " + Binder.getCallingPid();
10987        }
10988
10989        synchronized (this) {
10990            return checkContentProviderPermissionLocked(cpi, r, userId, true);
10991        }
10992    }
10993
10994    /**
10995     * Check if {@link ProcessRecord} has a possible chance at accessing the
10996     * given {@link ProviderInfo}. Final permission checking is always done
10997     * in {@link ContentProvider}.
10998     */
10999    private final String checkContentProviderPermissionLocked(
11000            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11001        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11002        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11003        boolean checkedGrants = false;
11004        if (checkUser) {
11005            // Looking for cross-user grants before enforcing the typical cross-users permissions
11006            int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11007            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11008                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11009                    return null;
11010                }
11011                checkedGrants = true;
11012            }
11013            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11014                    ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11015            if (userId != tmpTargetUserId) {
11016                // When we actually went to determine the final targer user ID, this ended
11017                // up different than our initial check for the authority.  This is because
11018                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11019                // SELF.  So we need to re-check the grants again.
11020                checkedGrants = false;
11021            }
11022        }
11023        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11024                cpi.applicationInfo.uid, cpi.exported)
11025                == PackageManager.PERMISSION_GRANTED) {
11026            return null;
11027        }
11028        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11029                cpi.applicationInfo.uid, cpi.exported)
11030                == PackageManager.PERMISSION_GRANTED) {
11031            return null;
11032        }
11033
11034        PathPermission[] pps = cpi.pathPermissions;
11035        if (pps != null) {
11036            int i = pps.length;
11037            while (i > 0) {
11038                i--;
11039                PathPermission pp = pps[i];
11040                String pprperm = pp.getReadPermission();
11041                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11042                        cpi.applicationInfo.uid, cpi.exported)
11043                        == PackageManager.PERMISSION_GRANTED) {
11044                    return null;
11045                }
11046                String ppwperm = pp.getWritePermission();
11047                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11048                        cpi.applicationInfo.uid, cpi.exported)
11049                        == PackageManager.PERMISSION_GRANTED) {
11050                    return null;
11051                }
11052            }
11053        }
11054        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11055            return null;
11056        }
11057
11058        final String suffix;
11059        if (!cpi.exported) {
11060            suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11061        } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11062            suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11063        } else {
11064            suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11065        }
11066        final String msg = "Permission Denial: opening provider " + cpi.name
11067                + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11068                + ", uid=" + callingUid + ")" + suffix;
11069        Slog.w(TAG, msg);
11070        return msg;
11071    }
11072
11073    /**
11074     * Returns if the ContentProvider has granted a uri to callingUid
11075     */
11076    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11077        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11078        if (perms != null) {
11079            for (int i=perms.size()-1; i>=0; i--) {
11080                GrantUri grantUri = perms.keyAt(i);
11081                if (grantUri.sourceUserId == userId || !checkUser) {
11082                    if (matchesProvider(grantUri.uri, cpi)) {
11083                        return true;
11084                    }
11085                }
11086            }
11087        }
11088        return false;
11089    }
11090
11091    /**
11092     * Returns true if the uri authority is one of the authorities specified in the provider.
11093     */
11094    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11095        String uriAuth = uri.getAuthority();
11096        String cpiAuth = cpi.authority;
11097        if (cpiAuth.indexOf(';') == -1) {
11098            return cpiAuth.equals(uriAuth);
11099        }
11100        String[] cpiAuths = cpiAuth.split(";");
11101        int length = cpiAuths.length;
11102        for (int i = 0; i < length; i++) {
11103            if (cpiAuths[i].equals(uriAuth)) return true;
11104        }
11105        return false;
11106    }
11107
11108    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11109            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11110        if (r != null) {
11111            for (int i=0; i<r.conProviders.size(); i++) {
11112                ContentProviderConnection conn = r.conProviders.get(i);
11113                if (conn.provider == cpr) {
11114                    if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11115                            "Adding provider requested by "
11116                            + r.processName + " from process "
11117                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11118                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11119                    if (stable) {
11120                        conn.stableCount++;
11121                        conn.numStableIncs++;
11122                    } else {
11123                        conn.unstableCount++;
11124                        conn.numUnstableIncs++;
11125                    }
11126                    return conn;
11127                }
11128            }
11129            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11130            if (stable) {
11131                conn.stableCount = 1;
11132                conn.numStableIncs = 1;
11133            } else {
11134                conn.unstableCount = 1;
11135                conn.numUnstableIncs = 1;
11136            }
11137            cpr.connections.add(conn);
11138            r.conProviders.add(conn);
11139            startAssociationLocked(r.uid, r.processName, r.curProcState,
11140                    cpr.uid, cpr.name, cpr.info.processName);
11141            return conn;
11142        }
11143        cpr.addExternalProcessHandleLocked(externalProcessToken);
11144        return null;
11145    }
11146
11147    boolean decProviderCountLocked(ContentProviderConnection conn,
11148            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11149        if (conn != null) {
11150            cpr = conn.provider;
11151            if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11152                    "Removing provider requested by "
11153                    + conn.client.processName + " from process "
11154                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11155                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11156            if (stable) {
11157                conn.stableCount--;
11158            } else {
11159                conn.unstableCount--;
11160            }
11161            if (conn.stableCount == 0 && conn.unstableCount == 0) {
11162                cpr.connections.remove(conn);
11163                conn.client.conProviders.remove(conn);
11164                if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11165                    // The client is more important than last activity -- note the time this
11166                    // is happening, so we keep the old provider process around a bit as last
11167                    // activity to avoid thrashing it.
11168                    if (cpr.proc != null) {
11169                        cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11170                    }
11171                }
11172                stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11173                return true;
11174            }
11175            return false;
11176        }
11177        cpr.removeExternalProcessHandleLocked(externalProcessToken);
11178        return false;
11179    }
11180
11181    private void checkTime(long startTime, String where) {
11182        long now = SystemClock.uptimeMillis();
11183        if ((now-startTime) > 50) {
11184            // If we are taking more than 50ms, log about it.
11185            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11186        }
11187    }
11188
11189    private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11190            PROC_SPACE_TERM,
11191            PROC_SPACE_TERM|PROC_PARENS,
11192            PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11193    };
11194
11195    private final long[] mProcessStateStatsLongs = new long[1];
11196
11197    boolean isProcessAliveLocked(ProcessRecord proc) {
11198        if (proc.procStatFile == null) {
11199            proc.procStatFile = "/proc/" + proc.pid + "/stat";
11200        }
11201        mProcessStateStatsLongs[0] = 0;
11202        if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11203                mProcessStateStatsLongs, null)) {
11204            if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11205            return false;
11206        }
11207        final long state = mProcessStateStatsLongs[0];
11208        if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11209                + (char)state);
11210        return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11211    }
11212
11213    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11214            String name, IBinder token, boolean stable, int userId) {
11215        ContentProviderRecord cpr;
11216        ContentProviderConnection conn = null;
11217        ProviderInfo cpi = null;
11218
11219        synchronized(this) {
11220            long startTime = SystemClock.uptimeMillis();
11221
11222            ProcessRecord r = null;
11223            if (caller != null) {
11224                r = getRecordForAppLocked(caller);
11225                if (r == null) {
11226                    throw new SecurityException(
11227                            "Unable to find app for caller " + caller
11228                          + " (pid=" + Binder.getCallingPid()
11229                          + ") when getting content provider " + name);
11230                }
11231            }
11232
11233            boolean checkCrossUser = true;
11234
11235            checkTime(startTime, "getContentProviderImpl: getProviderByName");
11236
11237            // First check if this content provider has been published...
11238            cpr = mProviderMap.getProviderByName(name, userId);
11239            // If that didn't work, check if it exists for user 0 and then
11240            // verify that it's a singleton provider before using it.
11241            if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11242                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11243                if (cpr != null) {
11244                    cpi = cpr.info;
11245                    if (isSingleton(cpi.processName, cpi.applicationInfo,
11246                            cpi.name, cpi.flags)
11247                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11248                        userId = UserHandle.USER_SYSTEM;
11249                        checkCrossUser = false;
11250                    } else {
11251                        cpr = null;
11252                        cpi = null;
11253                    }
11254                }
11255            }
11256
11257            boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11258            if (providerRunning) {
11259                cpi = cpr.info;
11260                String msg;
11261                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11262                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11263                        != null) {
11264                    throw new SecurityException(msg);
11265                }
11266                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11267
11268                if (r != null && cpr.canRunHere(r)) {
11269                    // This provider has been published or is in the process
11270                    // of being published...  but it is also allowed to run
11271                    // in the caller's process, so don't make a connection
11272                    // and just let the caller instantiate its own instance.
11273                    ContentProviderHolder holder = cpr.newHolder(null);
11274                    // don't give caller the provider object, it needs
11275                    // to make its own.
11276                    holder.provider = null;
11277                    return holder;
11278                }
11279
11280                final long origId = Binder.clearCallingIdentity();
11281
11282                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11283
11284                // In this case the provider instance already exists, so we can
11285                // return it right away.
11286                conn = incProviderCountLocked(r, cpr, token, stable);
11287                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11288                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11289                        // If this is a perceptible app accessing the provider,
11290                        // make sure to count it as being accessed and thus
11291                        // back up on the LRU list.  This is good because
11292                        // content providers are often expensive to start.
11293                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11294                        updateLruProcessLocked(cpr.proc, false, null);
11295                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11296                    }
11297                }
11298
11299                checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11300                final int verifiedAdj = cpr.proc.verifiedAdj;
11301                boolean success = updateOomAdjLocked(cpr.proc);
11302                // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11303                // if the process has been successfully adjusted.  So to reduce races with
11304                // it, we will check whether the process still exists.  Note that this doesn't
11305                // completely get rid of races with LMK killing the process, but should make
11306                // them much smaller.
11307                if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11308                    success = false;
11309                }
11310                maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11311                checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11312                if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11313                // NOTE: there is still a race here where a signal could be
11314                // pending on the process even though we managed to update its
11315                // adj level.  Not sure what to do about this, but at least
11316                // the race is now smaller.
11317                if (!success) {
11318                    // Uh oh...  it looks like the provider's process
11319                    // has been killed on us.  We need to wait for a new
11320                    // process to be started, and make sure its death
11321                    // doesn't kill our process.
11322                    Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11323                            + " is crashing; detaching " + r);
11324                    boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11325                    checkTime(startTime, "getContentProviderImpl: before appDied");
11326                    appDiedLocked(cpr.proc);
11327                    checkTime(startTime, "getContentProviderImpl: after appDied");
11328                    if (!lastRef) {
11329                        // This wasn't the last ref our process had on
11330                        // the provider...  we have now been killed, bail.
11331                        return null;
11332                    }
11333                    providerRunning = false;
11334                    conn = null;
11335                } else {
11336                    cpr.proc.verifiedAdj = cpr.proc.setAdj;
11337                }
11338
11339                Binder.restoreCallingIdentity(origId);
11340            }
11341
11342            if (!providerRunning) {
11343                try {
11344                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11345                    cpi = AppGlobals.getPackageManager().
11346                        resolveContentProvider(name,
11347                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11348                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11349                } catch (RemoteException ex) {
11350                }
11351                if (cpi == null) {
11352                    return null;
11353                }
11354                // If the provider is a singleton AND
11355                // (it's a call within the same user || the provider is a
11356                // privileged app)
11357                // Then allow connecting to the singleton provider
11358                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11359                        cpi.name, cpi.flags)
11360                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11361                if (singleton) {
11362                    userId = UserHandle.USER_SYSTEM;
11363                }
11364                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11365                checkTime(startTime, "getContentProviderImpl: got app info for user");
11366
11367                String msg;
11368                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11369                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11370                        != null) {
11371                    throw new SecurityException(msg);
11372                }
11373                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11374
11375                if (!mProcessesReady
11376                        && !cpi.processName.equals("system")) {
11377                    // If this content provider does not run in the system
11378                    // process, and the system is not yet ready to run other
11379                    // processes, then fail fast instead of hanging.
11380                    throw new IllegalArgumentException(
11381                            "Attempt to launch content provider before system ready");
11382                }
11383
11384                // Make sure that the user who owns this provider is running.  If not,
11385                // we don't want to allow it to run.
11386                if (!mUserController.isUserRunningLocked(userId, 0)) {
11387                    Slog.w(TAG, "Unable to launch app "
11388                            + cpi.applicationInfo.packageName + "/"
11389                            + cpi.applicationInfo.uid + " for provider "
11390                            + name + ": user " + userId + " is stopped");
11391                    return null;
11392                }
11393
11394                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11395                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11396                cpr = mProviderMap.getProviderByClass(comp, userId);
11397                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11398                final boolean firstClass = cpr == null;
11399                if (firstClass) {
11400                    final long ident = Binder.clearCallingIdentity();
11401
11402                    // If permissions need a review before any of the app components can run,
11403                    // we return no provider and launch a review activity if the calling app
11404                    // is in the foreground.
11405                    if (mPermissionReviewRequired) {
11406                        if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11407                            return null;
11408                        }
11409                    }
11410
11411                    try {
11412                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11413                        ApplicationInfo ai =
11414                            AppGlobals.getPackageManager().
11415                                getApplicationInfo(
11416                                        cpi.applicationInfo.packageName,
11417                                        STOCK_PM_FLAGS, userId);
11418                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11419                        if (ai == null) {
11420                            Slog.w(TAG, "No package info for content provider "
11421                                    + cpi.name);
11422                            return null;
11423                        }
11424                        ai = getAppInfoForUser(ai, userId);
11425                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11426                    } catch (RemoteException ex) {
11427                        // pm is in same process, this will never happen.
11428                    } finally {
11429                        Binder.restoreCallingIdentity(ident);
11430                    }
11431                }
11432
11433                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11434
11435                if (r != null && cpr.canRunHere(r)) {
11436                    // If this is a multiprocess provider, then just return its
11437                    // info and allow the caller to instantiate it.  Only do
11438                    // this if the provider is the same user as the caller's
11439                    // process, or can run as root (so can be in any process).
11440                    return cpr.newHolder(null);
11441                }
11442
11443                if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11444                            + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11445                            + cpr.info.name + " callers=" + Debug.getCallers(6));
11446
11447                // This is single process, and our app is now connecting to it.
11448                // See if we are already in the process of launching this
11449                // provider.
11450                final int N = mLaunchingProviders.size();
11451                int i;
11452                for (i = 0; i < N; i++) {
11453                    if (mLaunchingProviders.get(i) == cpr) {
11454                        break;
11455                    }
11456                }
11457
11458                // If the provider is not already being launched, then get it
11459                // started.
11460                if (i >= N) {
11461                    final long origId = Binder.clearCallingIdentity();
11462
11463                    try {
11464                        // Content provider is now in use, its package can't be stopped.
11465                        try {
11466                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
11467                            AppGlobals.getPackageManager().setPackageStoppedState(
11468                                    cpr.appInfo.packageName, false, userId);
11469                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
11470                        } catch (RemoteException e) {
11471                        } catch (IllegalArgumentException e) {
11472                            Slog.w(TAG, "Failed trying to unstop package "
11473                                    + cpr.appInfo.packageName + ": " + e);
11474                        }
11475
11476                        // Use existing process if already started
11477                        checkTime(startTime, "getContentProviderImpl: looking for process record");
11478                        ProcessRecord proc = getProcessRecordLocked(
11479                                cpi.processName, cpr.appInfo.uid, false);
11480                        if (proc != null && proc.thread != null && !proc.killed) {
11481                            if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11482                                    "Installing in existing process " + proc);
11483                            if (!proc.pubProviders.containsKey(cpi.name)) {
11484                                checkTime(startTime, "getContentProviderImpl: scheduling install");
11485                                proc.pubProviders.put(cpi.name, cpr);
11486                                try {
11487                                    proc.thread.scheduleInstallProvider(cpi);
11488                                } catch (RemoteException e) {
11489                                }
11490                            }
11491                        } else {
11492                            checkTime(startTime, "getContentProviderImpl: before start process");
11493                            proc = startProcessLocked(cpi.processName,
11494                                    cpr.appInfo, false, 0, "content provider",
11495                                    new ComponentName(cpi.applicationInfo.packageName,
11496                                            cpi.name), false, false, false);
11497                            checkTime(startTime, "getContentProviderImpl: after start process");
11498                            if (proc == null) {
11499                                Slog.w(TAG, "Unable to launch app "
11500                                        + cpi.applicationInfo.packageName + "/"
11501                                        + cpi.applicationInfo.uid + " for provider "
11502                                        + name + ": process is bad");
11503                                return null;
11504                            }
11505                        }
11506                        cpr.launchingApp = proc;
11507                        mLaunchingProviders.add(cpr);
11508                    } finally {
11509                        Binder.restoreCallingIdentity(origId);
11510                    }
11511                }
11512
11513                checkTime(startTime, "getContentProviderImpl: updating data structures");
11514
11515                // Make sure the provider is published (the same provider class
11516                // may be published under multiple names).
11517                if (firstClass) {
11518                    mProviderMap.putProviderByClass(comp, cpr);
11519                }
11520
11521                mProviderMap.putProviderByName(name, cpr);
11522                conn = incProviderCountLocked(r, cpr, token, stable);
11523                if (conn != null) {
11524                    conn.waiting = true;
11525                }
11526            }
11527            checkTime(startTime, "getContentProviderImpl: done!");
11528        }
11529
11530        // Wait for the provider to be published...
11531        synchronized (cpr) {
11532            while (cpr.provider == null) {
11533                if (cpr.launchingApp == null) {
11534                    Slog.w(TAG, "Unable to launch app "
11535                            + cpi.applicationInfo.packageName + "/"
11536                            + cpi.applicationInfo.uid + " for provider "
11537                            + name + ": launching app became null");
11538                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11539                            UserHandle.getUserId(cpi.applicationInfo.uid),
11540                            cpi.applicationInfo.packageName,
11541                            cpi.applicationInfo.uid, name);
11542                    return null;
11543                }
11544                try {
11545                    if (DEBUG_MU) Slog.v(TAG_MU,
11546                            "Waiting to start provider " + cpr
11547                            + " launchingApp=" + cpr.launchingApp);
11548                    if (conn != null) {
11549                        conn.waiting = true;
11550                    }
11551                    cpr.wait();
11552                } catch (InterruptedException ex) {
11553                } finally {
11554                    if (conn != null) {
11555                        conn.waiting = false;
11556                    }
11557                }
11558            }
11559        }
11560        return cpr != null ? cpr.newHolder(conn) : null;
11561    }
11562
11563    private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11564            ProcessRecord r, final int userId) {
11565        if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11566                cpi.packageName, userId)) {
11567
11568            final boolean callerForeground = r == null || r.setSchedGroup
11569                    != ProcessList.SCHED_GROUP_BACKGROUND;
11570
11571            // Show a permission review UI only for starting from a foreground app
11572            if (!callerForeground) {
11573                Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11574                        + cpi.packageName + " requires a permissions review");
11575                return false;
11576            }
11577
11578            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11579            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11580                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11581            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11582
11583            if (DEBUG_PERMISSIONS_REVIEW) {
11584                Slog.i(TAG, "u" + userId + " Launching permission review "
11585                        + "for package " + cpi.packageName);
11586            }
11587
11588            final UserHandle userHandle = new UserHandle(userId);
11589            mHandler.post(new Runnable() {
11590                @Override
11591                public void run() {
11592                    mContext.startActivityAsUser(intent, userHandle);
11593                }
11594            });
11595
11596            return false;
11597        }
11598
11599        return true;
11600    }
11601
11602    PackageManagerInternal getPackageManagerInternalLocked() {
11603        if (mPackageManagerInt == null) {
11604            mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11605        }
11606        return mPackageManagerInt;
11607    }
11608
11609    @Override
11610    public final ContentProviderHolder getContentProvider(
11611            IApplicationThread caller, String name, int userId, boolean stable) {
11612        enforceNotIsolatedCaller("getContentProvider");
11613        if (caller == null) {
11614            String msg = "null IApplicationThread when getting content provider "
11615                    + name;
11616            Slog.w(TAG, msg);
11617            throw new SecurityException(msg);
11618        }
11619        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11620        // with cross-user grant.
11621        return getContentProviderImpl(caller, name, null, stable, userId);
11622    }
11623
11624    public ContentProviderHolder getContentProviderExternal(
11625            String name, int userId, IBinder token) {
11626        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11627            "Do not have permission in call getContentProviderExternal()");
11628        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11629                userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11630        return getContentProviderExternalUnchecked(name, token, userId);
11631    }
11632
11633    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11634            IBinder token, int userId) {
11635        return getContentProviderImpl(null, name, token, true, userId);
11636    }
11637
11638    /**
11639     * Drop a content provider from a ProcessRecord's bookkeeping
11640     */
11641    public void removeContentProvider(IBinder connection, boolean stable) {
11642        enforceNotIsolatedCaller("removeContentProvider");
11643        long ident = Binder.clearCallingIdentity();
11644        try {
11645            synchronized (this) {
11646                ContentProviderConnection conn;
11647                try {
11648                    conn = (ContentProviderConnection)connection;
11649                } catch (ClassCastException e) {
11650                    String msg ="removeContentProvider: " + connection
11651                            + " not a ContentProviderConnection";
11652                    Slog.w(TAG, msg);
11653                    throw new IllegalArgumentException(msg);
11654                }
11655                if (conn == null) {
11656                    throw new NullPointerException("connection is null");
11657                }
11658                if (decProviderCountLocked(conn, null, null, stable)) {
11659                    updateOomAdjLocked();
11660                }
11661            }
11662        } finally {
11663            Binder.restoreCallingIdentity(ident);
11664        }
11665    }
11666
11667    public void removeContentProviderExternal(String name, IBinder token) {
11668        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11669            "Do not have permission in call removeContentProviderExternal()");
11670        int userId = UserHandle.getCallingUserId();
11671        long ident = Binder.clearCallingIdentity();
11672        try {
11673            removeContentProviderExternalUnchecked(name, token, userId);
11674        } finally {
11675            Binder.restoreCallingIdentity(ident);
11676        }
11677    }
11678
11679    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11680        synchronized (this) {
11681            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11682            if(cpr == null) {
11683                //remove from mProvidersByClass
11684                if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11685                return;
11686            }
11687
11688            //update content provider record entry info
11689            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11690            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11691            if (localCpr.hasExternalProcessHandles()) {
11692                if (localCpr.removeExternalProcessHandleLocked(token)) {
11693                    updateOomAdjLocked();
11694                } else {
11695                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11696                            + " with no external reference for token: "
11697                            + token + ".");
11698                }
11699            } else {
11700                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11701                        + " with no external references.");
11702            }
11703        }
11704    }
11705
11706    public final void publishContentProviders(IApplicationThread caller,
11707            List<ContentProviderHolder> providers) {
11708        if (providers == null) {
11709            return;
11710        }
11711
11712        enforceNotIsolatedCaller("publishContentProviders");
11713        synchronized (this) {
11714            final ProcessRecord r = getRecordForAppLocked(caller);
11715            if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11716            if (r == null) {
11717                throw new SecurityException(
11718                        "Unable to find app for caller " + caller
11719                      + " (pid=" + Binder.getCallingPid()
11720                      + ") when publishing content providers");
11721            }
11722
11723            final long origId = Binder.clearCallingIdentity();
11724
11725            final int N = providers.size();
11726            for (int i = 0; i < N; i++) {
11727                ContentProviderHolder src = providers.get(i);
11728                if (src == null || src.info == null || src.provider == null) {
11729                    continue;
11730                }
11731                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11732                if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11733                if (dst != null) {
11734                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11735                    mProviderMap.putProviderByClass(comp, dst);
11736                    String names[] = dst.info.authority.split(";");
11737                    for (int j = 0; j < names.length; j++) {
11738                        mProviderMap.putProviderByName(names[j], dst);
11739                    }
11740
11741                    int launchingCount = mLaunchingProviders.size();
11742                    int j;
11743                    boolean wasInLaunchingProviders = false;
11744                    for (j = 0; j < launchingCount; j++) {
11745                        if (mLaunchingProviders.get(j) == dst) {
11746                            mLaunchingProviders.remove(j);
11747                            wasInLaunchingProviders = true;
11748                            j--;
11749                            launchingCount--;
11750                        }
11751                    }
11752                    if (wasInLaunchingProviders) {
11753                        mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11754                    }
11755                    synchronized (dst) {
11756                        dst.provider = src.provider;
11757                        dst.proc = r;
11758                        dst.notifyAll();
11759                    }
11760                    updateOomAdjLocked(r);
11761                    maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11762                            src.info.authority);
11763                }
11764            }
11765
11766            Binder.restoreCallingIdentity(origId);
11767        }
11768    }
11769
11770    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11771        ContentProviderConnection conn;
11772        try {
11773            conn = (ContentProviderConnection)connection;
11774        } catch (ClassCastException e) {
11775            String msg ="refContentProvider: " + connection
11776                    + " not a ContentProviderConnection";
11777            Slog.w(TAG, msg);
11778            throw new IllegalArgumentException(msg);
11779        }
11780        if (conn == null) {
11781            throw new NullPointerException("connection is null");
11782        }
11783
11784        synchronized (this) {
11785            if (stable > 0) {
11786                conn.numStableIncs += stable;
11787            }
11788            stable = conn.stableCount + stable;
11789            if (stable < 0) {
11790                throw new IllegalStateException("stableCount < 0: " + stable);
11791            }
11792
11793            if (unstable > 0) {
11794                conn.numUnstableIncs += unstable;
11795            }
11796            unstable = conn.unstableCount + unstable;
11797            if (unstable < 0) {
11798                throw new IllegalStateException("unstableCount < 0: " + unstable);
11799            }
11800
11801            if ((stable+unstable) <= 0) {
11802                throw new IllegalStateException("ref counts can't go to zero here: stable="
11803                        + stable + " unstable=" + unstable);
11804            }
11805            conn.stableCount = stable;
11806            conn.unstableCount = unstable;
11807            return !conn.dead;
11808        }
11809    }
11810
11811    public void unstableProviderDied(IBinder connection) {
11812        ContentProviderConnection conn;
11813        try {
11814            conn = (ContentProviderConnection)connection;
11815        } catch (ClassCastException e) {
11816            String msg ="refContentProvider: " + connection
11817                    + " not a ContentProviderConnection";
11818            Slog.w(TAG, msg);
11819            throw new IllegalArgumentException(msg);
11820        }
11821        if (conn == null) {
11822            throw new NullPointerException("connection is null");
11823        }
11824
11825        // Safely retrieve the content provider associated with the connection.
11826        IContentProvider provider;
11827        synchronized (this) {
11828            provider = conn.provider.provider;
11829        }
11830
11831        if (provider == null) {
11832            // Um, yeah, we're way ahead of you.
11833            return;
11834        }
11835
11836        // Make sure the caller is being honest with us.
11837        if (provider.asBinder().pingBinder()) {
11838            // Er, no, still looks good to us.
11839            synchronized (this) {
11840                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11841                        + " says " + conn + " died, but we don't agree");
11842                return;
11843            }
11844        }
11845
11846        // Well look at that!  It's dead!
11847        synchronized (this) {
11848            if (conn.provider.provider != provider) {
11849                // But something changed...  good enough.
11850                return;
11851            }
11852
11853            ProcessRecord proc = conn.provider.proc;
11854            if (proc == null || proc.thread == null) {
11855                // Seems like the process is already cleaned up.
11856                return;
11857            }
11858
11859            // As far as we're concerned, this is just like receiving a
11860            // death notification...  just a bit prematurely.
11861            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11862                    + ") early provider death");
11863            final long ident = Binder.clearCallingIdentity();
11864            try {
11865                appDiedLocked(proc);
11866            } finally {
11867                Binder.restoreCallingIdentity(ident);
11868            }
11869        }
11870    }
11871
11872    @Override
11873    public void appNotRespondingViaProvider(IBinder connection) {
11874        enforceCallingPermission(
11875                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11876
11877        final ContentProviderConnection conn = (ContentProviderConnection) connection;
11878        if (conn == null) {
11879            Slog.w(TAG, "ContentProviderConnection is null");
11880            return;
11881        }
11882
11883        final ProcessRecord host = conn.provider.proc;
11884        if (host == null) {
11885            Slog.w(TAG, "Failed to find hosting ProcessRecord");
11886            return;
11887        }
11888
11889        mHandler.post(new Runnable() {
11890            @Override
11891            public void run() {
11892                mAppErrors.appNotResponding(host, null, null, false,
11893                        "ContentProvider not responding");
11894            }
11895        });
11896    }
11897
11898    public final void installSystemProviders() {
11899        List<ProviderInfo> providers;
11900        synchronized (this) {
11901            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11902            providers = generateApplicationProvidersLocked(app);
11903            if (providers != null) {
11904                for (int i=providers.size()-1; i>=0; i--) {
11905                    ProviderInfo pi = (ProviderInfo)providers.get(i);
11906                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11907                        Slog.w(TAG, "Not installing system proc provider " + pi.name
11908                                + ": not system .apk");
11909                        providers.remove(i);
11910                    }
11911                }
11912            }
11913        }
11914        if (providers != null) {
11915            mSystemThread.installSystemProviders(providers);
11916        }
11917
11918        mConstants.start(mContext.getContentResolver());
11919        mCoreSettingsObserver = new CoreSettingsObserver(this);
11920        mFontScaleSettingObserver = new FontScaleSettingObserver();
11921
11922        // Now that the settings provider is published we can consider sending
11923        // in a rescue party.
11924        RescueParty.onSettingsProviderPublished(mContext);
11925
11926        //mUsageStatsService.monitorPackages();
11927    }
11928
11929    private void startPersistentApps(int matchFlags) {
11930        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11931
11932        synchronized (this) {
11933            try {
11934                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11935                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11936                for (ApplicationInfo app : apps) {
11937                    if (!"android".equals(app.packageName)) {
11938                        addAppLocked(app, null, false, null /* ABI override */);
11939                    }
11940                }
11941            } catch (RemoteException ex) {
11942            }
11943        }
11944    }
11945
11946    /**
11947     * When a user is unlocked, we need to install encryption-unaware providers
11948     * belonging to any running apps.
11949     */
11950    private void installEncryptionUnawareProviders(int userId) {
11951        // We're only interested in providers that are encryption unaware, and
11952        // we don't care about uninstalled apps, since there's no way they're
11953        // running at this point.
11954        final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11955
11956        synchronized (this) {
11957            final int NP = mProcessNames.getMap().size();
11958            for (int ip = 0; ip < NP; ip++) {
11959                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11960                final int NA = apps.size();
11961                for (int ia = 0; ia < NA; ia++) {
11962                    final ProcessRecord app = apps.valueAt(ia);
11963                    if (app.userId != userId || app.thread == null || app.unlocked) continue;
11964
11965                    final int NG = app.pkgList.size();
11966                    for (int ig = 0; ig < NG; ig++) {
11967                        try {
11968                            final String pkgName = app.pkgList.keyAt(ig);
11969                            final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11970                                    .getPackageInfo(pkgName, matchFlags, userId);
11971                            if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11972                                for (ProviderInfo pi : pkgInfo.providers) {
11973                                    // TODO: keep in sync with generateApplicationProvidersLocked
11974                                    final boolean processMatch = Objects.equals(pi.processName,
11975                                            app.processName) || pi.multiprocess;
11976                                    final boolean userMatch = isSingleton(pi.processName,
11977                                            pi.applicationInfo, pi.name, pi.flags)
11978                                                    ? (app.userId == UserHandle.USER_SYSTEM) : true;
11979                                    if (processMatch && userMatch) {
11980                                        Log.v(TAG, "Installing " + pi);
11981                                        app.thread.scheduleInstallProvider(pi);
11982                                    } else {
11983                                        Log.v(TAG, "Skipping " + pi);
11984                                    }
11985                                }
11986                            }
11987                        } catch (RemoteException ignored) {
11988                        }
11989                    }
11990                }
11991            }
11992        }
11993    }
11994
11995    /**
11996     * Allows apps to retrieve the MIME type of a URI.
11997     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11998     * users, then it does not need permission to access the ContentProvider.
11999     * Either, it needs cross-user uri grants.
12000     *
12001     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12002     *
12003     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12004     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12005     */
12006    public String getProviderMimeType(Uri uri, int userId) {
12007        enforceNotIsolatedCaller("getProviderMimeType");
12008        final String name = uri.getAuthority();
12009        int callingUid = Binder.getCallingUid();
12010        int callingPid = Binder.getCallingPid();
12011        long ident = 0;
12012        boolean clearedIdentity = false;
12013        synchronized (this) {
12014            userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12015        }
12016        if (canClearIdentity(callingPid, callingUid, userId)) {
12017            clearedIdentity = true;
12018            ident = Binder.clearCallingIdentity();
12019        }
12020        ContentProviderHolder holder = null;
12021        try {
12022            holder = getContentProviderExternalUnchecked(name, null, userId);
12023            if (holder != null) {
12024                return holder.provider.getType(uri);
12025            }
12026        } catch (RemoteException e) {
12027            Log.w(TAG, "Content provider dead retrieving " + uri, e);
12028            return null;
12029        } catch (Exception e) {
12030            Log.w(TAG, "Exception while determining type of " + uri, e);
12031            return null;
12032        } finally {
12033            // We need to clear the identity to call removeContentProviderExternalUnchecked
12034            if (!clearedIdentity) {
12035                ident = Binder.clearCallingIdentity();
12036            }
12037            try {
12038                if (holder != null) {
12039                    removeContentProviderExternalUnchecked(name, null, userId);
12040                }
12041            } finally {
12042                Binder.restoreCallingIdentity(ident);
12043            }
12044        }
12045
12046        return null;
12047    }
12048
12049    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12050        if (UserHandle.getUserId(callingUid) == userId) {
12051            return true;
12052        }
12053        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12054                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12055                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12056                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12057                return true;
12058        }
12059        return false;
12060    }
12061
12062    // =========================================================
12063    // GLOBAL MANAGEMENT
12064    // =========================================================
12065
12066    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12067            boolean isolated, int isolatedUid) {
12068        String proc = customProcess != null ? customProcess : info.processName;
12069        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12070        final int userId = UserHandle.getUserId(info.uid);
12071        int uid = info.uid;
12072        if (isolated) {
12073            if (isolatedUid == 0) {
12074                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
12075                while (true) {
12076                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
12077                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
12078                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
12079                    }
12080                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12081                    mNextIsolatedProcessUid++;
12082                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12083                        // No process for this uid, use it.
12084                        break;
12085                    }
12086                    stepsLeft--;
12087                    if (stepsLeft <= 0) {
12088                        return null;
12089                    }
12090                }
12091            } else {
12092                // Special case for startIsolatedProcess (internal only), where
12093                // the uid of the isolated process is specified by the caller.
12094                uid = isolatedUid;
12095            }
12096
12097            // Register the isolated UID with this application so BatteryStats knows to
12098            // attribute resource usage to the application.
12099            //
12100            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12101            // about the process state of the isolated UID *before* it is registered with the
12102            // owning application.
12103            mBatteryStatsService.addIsolatedUid(uid, info.uid);
12104        }
12105        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12106        if (!mBooted && !mBooting
12107                && userId == UserHandle.USER_SYSTEM
12108                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12109            r.persistent = true;
12110            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12111        }
12112        addProcessNameLocked(r);
12113        return r;
12114    }
12115
12116    private boolean uidOnBackgroundWhitelist(final int uid) {
12117        final int N = mBackgroundUidWhitelist.length;
12118        for (int i = 0; i < N; i++) {
12119            if (uid == mBackgroundUidWhitelist[i]) {
12120                return true;
12121            }
12122        }
12123        return false;
12124    }
12125
12126    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12127            String abiOverride) {
12128        ProcessRecord app;
12129        if (!isolated) {
12130            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12131                    info.uid, true);
12132        } else {
12133            app = null;
12134        }
12135
12136        if (app == null) {
12137            app = newProcessRecordLocked(info, customProcess, isolated, 0);
12138            updateLruProcessLocked(app, false, null);
12139            updateOomAdjLocked();
12140        }
12141
12142        // This package really, really can not be stopped.
12143        try {
12144            AppGlobals.getPackageManager().setPackageStoppedState(
12145                    info.packageName, false, UserHandle.getUserId(app.uid));
12146        } catch (RemoteException e) {
12147        } catch (IllegalArgumentException e) {
12148            Slog.w(TAG, "Failed trying to unstop package "
12149                    + info.packageName + ": " + e);
12150        }
12151
12152        if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12153            app.persistent = true;
12154            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12155        }
12156        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12157            mPersistentStartingProcesses.add(app);
12158            startProcessLocked(app, "added application",
12159                    customProcess != null ? customProcess : app.processName, abiOverride,
12160                    null /* entryPoint */, null /* entryPointArgs */);
12161        }
12162
12163        return app;
12164    }
12165
12166    public void unhandledBack() {
12167        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12168                "unhandledBack()");
12169
12170        synchronized(this) {
12171            final long origId = Binder.clearCallingIdentity();
12172            try {
12173                getFocusedStack().unhandledBackLocked();
12174            } finally {
12175                Binder.restoreCallingIdentity(origId);
12176            }
12177        }
12178    }
12179
12180    public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12181        enforceNotIsolatedCaller("openContentUri");
12182        final int userId = UserHandle.getCallingUserId();
12183        final Uri uri = Uri.parse(uriString);
12184        String name = uri.getAuthority();
12185        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12186        ParcelFileDescriptor pfd = null;
12187        if (cph != null) {
12188            // We record the binder invoker's uid in thread-local storage before
12189            // going to the content provider to open the file.  Later, in the code
12190            // that handles all permissions checks, we look for this uid and use
12191            // that rather than the Activity Manager's own uid.  The effect is that
12192            // we do the check against the caller's permissions even though it looks
12193            // to the content provider like the Activity Manager itself is making
12194            // the request.
12195            Binder token = new Binder();
12196            sCallerIdentity.set(new Identity(
12197                    token, Binder.getCallingPid(), Binder.getCallingUid()));
12198            try {
12199                pfd = cph.provider.openFile(null, uri, "r", null, token);
12200            } catch (FileNotFoundException e) {
12201                // do nothing; pfd will be returned null
12202            } finally {
12203                // Ensure that whatever happens, we clean up the identity state
12204                sCallerIdentity.remove();
12205                // Ensure we're done with the provider.
12206                removeContentProviderExternalUnchecked(name, null, userId);
12207            }
12208        } else {
12209            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12210        }
12211        return pfd;
12212    }
12213
12214    // Actually is sleeping or shutting down or whatever else in the future
12215    // is an inactive state.
12216    boolean isSleepingOrShuttingDownLocked() {
12217        return isSleepingLocked() || mShuttingDown;
12218    }
12219
12220    boolean isShuttingDownLocked() {
12221        return mShuttingDown;
12222    }
12223
12224    boolean isSleepingLocked() {
12225        return mSleeping;
12226    }
12227
12228    void onWakefulnessChanged(int wakefulness) {
12229        synchronized(this) {
12230            mWakefulness = wakefulness;
12231            updateSleepIfNeededLocked();
12232        }
12233    }
12234
12235    void finishRunningVoiceLocked() {
12236        if (mRunningVoice != null) {
12237            mRunningVoice = null;
12238            mVoiceWakeLock.release();
12239            updateSleepIfNeededLocked();
12240        }
12241    }
12242
12243    void startTimeTrackingFocusedActivityLocked() {
12244        final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12245        if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12246            mCurAppTimeTracker.start(resumedActivity.packageName);
12247        }
12248    }
12249
12250    void updateSleepIfNeededLocked() {
12251        if (mSleeping && !shouldSleepLocked()) {
12252            mSleeping = false;
12253            startTimeTrackingFocusedActivityLocked();
12254            mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12255            mStackSupervisor.comeOutOfSleepIfNeededLocked();
12256            sendNotifyVrManagerOfSleepState(false);
12257            updateOomAdjLocked();
12258        } else if (!mSleeping && shouldSleepLocked()) {
12259            mSleeping = true;
12260            if (mCurAppTimeTracker != null) {
12261                mCurAppTimeTracker.stop();
12262            }
12263            mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12264            mStackSupervisor.goingToSleepLocked();
12265            sendNotifyVrManagerOfSleepState(true);
12266            updateOomAdjLocked();
12267
12268            // Initialize the wake times of all processes.
12269            checkExcessivePowerUsageLocked(false);
12270            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12271            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
12272            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
12273        }
12274    }
12275
12276    private boolean shouldSleepLocked() {
12277        // Resume applications while running a voice interactor.
12278        if (mRunningVoice != null) {
12279            return false;
12280        }
12281
12282        // TODO: Transform the lock screen state into a sleep token instead.
12283        switch (mWakefulness) {
12284            case PowerManagerInternal.WAKEFULNESS_AWAKE:
12285            case PowerManagerInternal.WAKEFULNESS_DREAMING:
12286            case PowerManagerInternal.WAKEFULNESS_DOZING:
12287                // Pause applications whenever the lock screen is shown or any sleep
12288                // tokens have been acquired.
12289                return mKeyguardController.isKeyguardShowing() || !mSleepTokens.isEmpty();
12290            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
12291            default:
12292                // If we're asleep then pause applications unconditionally.
12293                return true;
12294        }
12295    }
12296
12297    /** Pokes the task persister. */
12298    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12299        mRecentTasks.notifyTaskPersisterLocked(task, flush);
12300    }
12301
12302    /** Notifies all listeners when the pinned stack animation starts. */
12303    @Override
12304    public void notifyPinnedStackAnimationStarted() {
12305        mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12306    }
12307
12308    /** Notifies all listeners when the pinned stack animation ends. */
12309    @Override
12310    public void notifyPinnedStackAnimationEnded() {
12311        mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12312    }
12313
12314    @Override
12315    public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12316        mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12317    }
12318
12319    @Override
12320    public boolean shutdown(int timeout) {
12321        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12322                != PackageManager.PERMISSION_GRANTED) {
12323            throw new SecurityException("Requires permission "
12324                    + android.Manifest.permission.SHUTDOWN);
12325        }
12326
12327        boolean timedout = false;
12328
12329        synchronized(this) {
12330            mShuttingDown = true;
12331            updateEventDispatchingLocked();
12332            timedout = mStackSupervisor.shutdownLocked(timeout);
12333        }
12334
12335        mAppOpsService.shutdown();
12336        if (mUsageStatsService != null) {
12337            mUsageStatsService.prepareShutdown();
12338        }
12339        mBatteryStatsService.shutdown();
12340        synchronized (this) {
12341            mProcessStats.shutdownLocked();
12342            notifyTaskPersisterLocked(null, true);
12343        }
12344
12345        return timedout;
12346    }
12347
12348    public final void activitySlept(IBinder token) {
12349        if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12350
12351        final long origId = Binder.clearCallingIdentity();
12352
12353        synchronized (this) {
12354            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12355            if (r != null) {
12356                mStackSupervisor.activitySleptLocked(r);
12357            }
12358        }
12359
12360        Binder.restoreCallingIdentity(origId);
12361    }
12362
12363    void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12364        Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12365        mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12366        if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12367            boolean wasRunningVoice = mRunningVoice != null;
12368            mRunningVoice = session;
12369            if (!wasRunningVoice) {
12370                mVoiceWakeLock.acquire();
12371                updateSleepIfNeededLocked();
12372            }
12373        }
12374    }
12375
12376    private void updateEventDispatchingLocked() {
12377        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12378    }
12379
12380    @Override
12381    public void setLockScreenShown(boolean showing) {
12382        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12383                != PackageManager.PERMISSION_GRANTED) {
12384            throw new SecurityException("Requires permission "
12385                    + android.Manifest.permission.DEVICE_POWER);
12386        }
12387
12388        synchronized(this) {
12389            long ident = Binder.clearCallingIdentity();
12390            try {
12391                mKeyguardController.setKeyguardShown(showing);
12392            } finally {
12393                Binder.restoreCallingIdentity(ident);
12394            }
12395        }
12396    }
12397
12398    @Override
12399    public void notifyLockedProfile(@UserIdInt int userId) {
12400        try {
12401            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12402                throw new SecurityException("Only privileged app can call notifyLockedProfile");
12403            }
12404        } catch (RemoteException ex) {
12405            throw new SecurityException("Fail to check is caller a privileged app", ex);
12406        }
12407
12408        synchronized (this) {
12409            final long ident = Binder.clearCallingIdentity();
12410            try {
12411                if (mUserController.shouldConfirmCredentials(userId)) {
12412                    if (mKeyguardController.isKeyguardLocked()) {
12413                        // Showing launcher to avoid user entering credential twice.
12414                        final int currentUserId = mUserController.getCurrentUserIdLocked();
12415                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12416                    }
12417                    mStackSupervisor.lockAllProfileTasks(userId);
12418                }
12419            } finally {
12420                Binder.restoreCallingIdentity(ident);
12421            }
12422        }
12423    }
12424
12425    @Override
12426    public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12427        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12428        synchronized (this) {
12429            final long ident = Binder.clearCallingIdentity();
12430            try {
12431                mActivityStarter.startConfirmCredentialIntent(intent, options);
12432            } finally {
12433                Binder.restoreCallingIdentity(ident);
12434            }
12435        }
12436    }
12437
12438    @Override
12439    public void stopAppSwitches() {
12440        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12441                != PackageManager.PERMISSION_GRANTED) {
12442            throw new SecurityException("viewquires permission "
12443                    + android.Manifest.permission.STOP_APP_SWITCHES);
12444        }
12445
12446        synchronized(this) {
12447            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12448                    + APP_SWITCH_DELAY_TIME;
12449            mDidAppSwitch = false;
12450            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12451            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12452            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12453        }
12454    }
12455
12456    public void resumeAppSwitches() {
12457        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12458                != PackageManager.PERMISSION_GRANTED) {
12459            throw new SecurityException("Requires permission "
12460                    + android.Manifest.permission.STOP_APP_SWITCHES);
12461        }
12462
12463        synchronized(this) {
12464            // Note that we don't execute any pending app switches... we will
12465            // let those wait until either the timeout, or the next start
12466            // activity request.
12467            mAppSwitchesAllowedTime = 0;
12468        }
12469    }
12470
12471    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12472            int callingPid, int callingUid, String name) {
12473        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12474            return true;
12475        }
12476
12477        int perm = checkComponentPermission(
12478                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12479                sourceUid, -1, true);
12480        if (perm == PackageManager.PERMISSION_GRANTED) {
12481            return true;
12482        }
12483
12484        // If the actual IPC caller is different from the logical source, then
12485        // also see if they are allowed to control app switches.
12486        if (callingUid != -1 && callingUid != sourceUid) {
12487            perm = checkComponentPermission(
12488                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12489                    callingUid, -1, true);
12490            if (perm == PackageManager.PERMISSION_GRANTED) {
12491                return true;
12492            }
12493        }
12494
12495        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12496        return false;
12497    }
12498
12499    public void setDebugApp(String packageName, boolean waitForDebugger,
12500            boolean persistent) {
12501        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12502                "setDebugApp()");
12503
12504        long ident = Binder.clearCallingIdentity();
12505        try {
12506            // Note that this is not really thread safe if there are multiple
12507            // callers into it at the same time, but that's not a situation we
12508            // care about.
12509            if (persistent) {
12510                final ContentResolver resolver = mContext.getContentResolver();
12511                Settings.Global.putString(
12512                    resolver, Settings.Global.DEBUG_APP,
12513                    packageName);
12514                Settings.Global.putInt(
12515                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12516                    waitForDebugger ? 1 : 0);
12517            }
12518
12519            synchronized (this) {
12520                if (!persistent) {
12521                    mOrigDebugApp = mDebugApp;
12522                    mOrigWaitForDebugger = mWaitForDebugger;
12523                }
12524                mDebugApp = packageName;
12525                mWaitForDebugger = waitForDebugger;
12526                mDebugTransient = !persistent;
12527                if (packageName != null) {
12528                    forceStopPackageLocked(packageName, -1, false, false, true, true,
12529                            false, UserHandle.USER_ALL, "set debug app");
12530                }
12531            }
12532        } finally {
12533            Binder.restoreCallingIdentity(ident);
12534        }
12535    }
12536
12537    void setTrackAllocationApp(ApplicationInfo app, String processName) {
12538        synchronized (this) {
12539            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12540            if (!isDebuggable) {
12541                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12542                    throw new SecurityException("Process not debuggable: " + app.packageName);
12543                }
12544            }
12545
12546            mTrackAllocationApp = processName;
12547        }
12548    }
12549
12550    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12551        synchronized (this) {
12552            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12553            if (!isDebuggable) {
12554                if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12555                    throw new SecurityException("Process not debuggable: " + app.packageName);
12556                }
12557            }
12558            mProfileApp = processName;
12559            mProfileFile = profilerInfo.profileFile;
12560            if (mProfileFd != null) {
12561                try {
12562                    mProfileFd.close();
12563                } catch (IOException e) {
12564                }
12565                mProfileFd = null;
12566            }
12567            mProfileFd = profilerInfo.profileFd;
12568            mSamplingInterval = profilerInfo.samplingInterval;
12569            mAutoStopProfiler = profilerInfo.autoStopProfiler;
12570            mStreamingOutput = profilerInfo.streamingOutput;
12571            mProfileType = 0;
12572        }
12573    }
12574
12575    void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12576        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12577        if (!isDebuggable) {
12578            if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12579                throw new SecurityException("Process not debuggable: " + app.packageName);
12580            }
12581        }
12582        mNativeDebuggingApp = processName;
12583    }
12584
12585    @Override
12586    public void setAlwaysFinish(boolean enabled) {
12587        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12588                "setAlwaysFinish()");
12589
12590        long ident = Binder.clearCallingIdentity();
12591        try {
12592            Settings.Global.putInt(
12593                    mContext.getContentResolver(),
12594                    Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12595
12596            synchronized (this) {
12597                mAlwaysFinishActivities = enabled;
12598            }
12599        } finally {
12600            Binder.restoreCallingIdentity(ident);
12601        }
12602    }
12603
12604    @Override
12605    public void setActivityController(IActivityController controller, boolean imAMonkey) {
12606        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12607                "setActivityController()");
12608        synchronized (this) {
12609            mController = controller;
12610            mControllerIsAMonkey = imAMonkey;
12611            Watchdog.getInstance().setActivityController(controller);
12612        }
12613    }
12614
12615    @Override
12616    public void setUserIsMonkey(boolean userIsMonkey) {
12617        synchronized (this) {
12618            synchronized (mPidsSelfLocked) {
12619                final int callingPid = Binder.getCallingPid();
12620                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12621                if (proc == null) {
12622                    throw new SecurityException("Unknown process: " + callingPid);
12623                }
12624                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12625                    throw new SecurityException("Only an instrumentation process "
12626                            + "with a UiAutomation can call setUserIsMonkey");
12627                }
12628            }
12629            mUserIsMonkey = userIsMonkey;
12630        }
12631    }
12632
12633    @Override
12634    public boolean isUserAMonkey() {
12635        synchronized (this) {
12636            // If there is a controller also implies the user is a monkey.
12637            return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12638        }
12639    }
12640
12641    /**
12642     * @deprecated This method is only used by a few internal components and it will soon be
12643     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12644     * No new code should be calling it.
12645     */
12646    @Deprecated
12647    @Override
12648    public void requestBugReport(int bugreportType) {
12649        String extraOptions = null;
12650        switch (bugreportType) {
12651            case ActivityManager.BUGREPORT_OPTION_FULL:
12652                // Default options.
12653                break;
12654            case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12655                extraOptions = "bugreportplus";
12656                break;
12657            case ActivityManager.BUGREPORT_OPTION_REMOTE:
12658                extraOptions = "bugreportremote";
12659                break;
12660            case ActivityManager.BUGREPORT_OPTION_WEAR:
12661                extraOptions = "bugreportwear";
12662                break;
12663            case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12664                extraOptions = "bugreporttelephony";
12665                break;
12666            default:
12667                throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12668                        + bugreportType);
12669        }
12670        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12671        if (extraOptions != null) {
12672            SystemProperties.set("dumpstate.options", extraOptions);
12673        }
12674        SystemProperties.set("ctl.start", "bugreport");
12675    }
12676
12677    /**
12678     * @deprecated This method is only used by a few internal components and it will soon be
12679     * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12680     * No new code should be calling it.
12681     */
12682    @Deprecated
12683    @Override
12684    public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12685
12686        if (!TextUtils.isEmpty(shareTitle)) {
12687            if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12688                String errorStr = "shareTitle should be less than " +
12689                        MAX_BUGREPORT_TITLE_SIZE + " characters";
12690                throw new IllegalArgumentException(errorStr);
12691            } else {
12692                if (!TextUtils.isEmpty(shareDescription)) {
12693                    int length;
12694                    try {
12695                        length = shareDescription.getBytes("UTF-8").length;
12696                    } catch (UnsupportedEncodingException e) {
12697                        String errorStr = "shareDescription: UnsupportedEncodingException";
12698                        throw new IllegalArgumentException(errorStr);
12699                    }
12700                    if (length > SystemProperties.PROP_VALUE_MAX) {
12701                        String errorStr = "shareTitle should be less than " +
12702                                SystemProperties.PROP_VALUE_MAX + " bytes";
12703                        throw new IllegalArgumentException(errorStr);
12704                    } else {
12705                        SystemProperties.set("dumpstate.options.description", shareDescription);
12706                    }
12707                }
12708                SystemProperties.set("dumpstate.options.title", shareTitle);
12709            }
12710        }
12711
12712        Slog.d(TAG, "Bugreport notification title " + shareTitle
12713                + " description " + shareDescription);
12714        requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12715    }
12716
12717    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12718        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12719    }
12720
12721    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12722        if (r != null && (r.instr != null || r.usingWrapper)) {
12723            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12724        }
12725        return KEY_DISPATCHING_TIMEOUT;
12726    }
12727
12728    @Override
12729    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12730        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12731                != PackageManager.PERMISSION_GRANTED) {
12732            throw new SecurityException("Requires permission "
12733                    + android.Manifest.permission.FILTER_EVENTS);
12734        }
12735        ProcessRecord proc;
12736        long timeout;
12737        synchronized (this) {
12738            synchronized (mPidsSelfLocked) {
12739                proc = mPidsSelfLocked.get(pid);
12740            }
12741            timeout = getInputDispatchingTimeoutLocked(proc);
12742        }
12743
12744        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12745            return -1;
12746        }
12747
12748        return timeout;
12749    }
12750
12751    /**
12752     * Handle input dispatching timeouts.
12753     * Returns whether input dispatching should be aborted or not.
12754     */
12755    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12756            final ActivityRecord activity, final ActivityRecord parent,
12757            final boolean aboveSystem, String reason) {
12758        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12759                != PackageManager.PERMISSION_GRANTED) {
12760            throw new SecurityException("Requires permission "
12761                    + android.Manifest.permission.FILTER_EVENTS);
12762        }
12763
12764        final String annotation;
12765        if (reason == null) {
12766            annotation = "Input dispatching timed out";
12767        } else {
12768            annotation = "Input dispatching timed out (" + reason + ")";
12769        }
12770
12771        if (proc != null) {
12772            synchronized (this) {
12773                if (proc.debugging) {
12774                    return false;
12775                }
12776
12777                if (mDidDexOpt) {
12778                    // Give more time since we were dexopting.
12779                    mDidDexOpt = false;
12780                    return false;
12781                }
12782
12783                if (proc.instr != null) {
12784                    Bundle info = new Bundle();
12785                    info.putString("shortMsg", "keyDispatchingTimedOut");
12786                    info.putString("longMsg", annotation);
12787                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12788                    return true;
12789                }
12790            }
12791            mHandler.post(new Runnable() {
12792                @Override
12793                public void run() {
12794                    mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12795                }
12796            });
12797        }
12798
12799        return true;
12800    }
12801
12802    @Override
12803    public Bundle getAssistContextExtras(int requestType) {
12804        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12805                null, null, true /* focused */, true /* newSessionId */,
12806                UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12807        if (pae == null) {
12808            return null;
12809        }
12810        synchronized (pae) {
12811            while (!pae.haveResult) {
12812                try {
12813                    pae.wait();
12814                } catch (InterruptedException e) {
12815                }
12816            }
12817        }
12818        synchronized (this) {
12819            buildAssistBundleLocked(pae, pae.result);
12820            mPendingAssistExtras.remove(pae);
12821            mUiHandler.removeCallbacks(pae);
12822        }
12823        return pae.extras;
12824    }
12825
12826    @Override
12827    public boolean isAssistDataAllowedOnCurrentActivity() {
12828        int userId;
12829        synchronized (this) {
12830            final ActivityStack focusedStack = getFocusedStack();
12831            if (focusedStack == null || focusedStack.isAssistantStack()) {
12832                return false;
12833            }
12834
12835            final ActivityRecord activity = focusedStack.topActivity();
12836            if (activity == null) {
12837                return false;
12838            }
12839            userId = activity.userId;
12840        }
12841        DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12842                Context.DEVICE_POLICY_SERVICE);
12843        return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12844    }
12845
12846    @Override
12847    public boolean showAssistFromActivity(IBinder token, Bundle args) {
12848        long ident = Binder.clearCallingIdentity();
12849        try {
12850            synchronized (this) {
12851                ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12852                ActivityRecord top = getFocusedStack().topActivity();
12853                if (top != caller) {
12854                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12855                            + " is not current top " + top);
12856                    return false;
12857                }
12858                if (!top.nowVisible) {
12859                    Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12860                            + " is not visible");
12861                    return false;
12862                }
12863            }
12864            return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
12865                    token);
12866        } finally {
12867            Binder.restoreCallingIdentity(ident);
12868        }
12869    }
12870
12871    @Override
12872    public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12873            Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
12874        return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12875                activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
12876                PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
12877    }
12878
12879    @Override
12880    public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
12881            IBinder activityToken) {
12882        // NOTE: we could always use ActivityManager.ASSIST_CONTEXT_FULL and let ActivityThread
12883        // rely on the flags to decide whether the handleRequestAssistContextExtras() is for
12884        // autofill, but it's safer to explicitly use new AutoFill types, in case the Assist
12885        // requests use flags in the future as well (since their flags value might collide with the
12886        // autofill flag values).
12887        return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
12888                receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
12889                null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT) != null;
12890    }
12891
12892    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12893            IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12894            boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12895        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12896                "enqueueAssistContext()");
12897
12898        synchronized (this) {
12899            ActivityRecord activity = getFocusedStack().topActivity();
12900            if (activity == null) {
12901                Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12902                return null;
12903            }
12904            if (activity.app == null || activity.app.thread == null) {
12905                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12906                return null;
12907            }
12908            if (focused) {
12909                if (activityToken != null) {
12910                    ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12911                    if (activity != caller) {
12912                        Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12913                                + " is not current top " + activity);
12914                        return null;
12915                    }
12916                }
12917            } else {
12918                activity = ActivityRecord.forTokenLocked(activityToken);
12919                if (activity == null) {
12920                    Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12921                            + " couldn't be found");
12922                    return null;
12923                }
12924            }
12925
12926            PendingAssistExtras pae;
12927            Bundle extras = new Bundle();
12928            if (args != null) {
12929                extras.putAll(args);
12930            }
12931            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12932            extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12933
12934            pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12935                    userHandle);
12936            pae.isHome = activity.isHomeActivity();
12937
12938            // Increment the sessionId if necessary
12939            if (newSessionId) {
12940                mViSessionId++;
12941            }
12942            try {
12943                activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
12944                        mViSessionId);
12945                mPendingAssistExtras.add(pae);
12946                mUiHandler.postDelayed(pae, timeout);
12947            } catch (RemoteException e) {
12948                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12949                return null;
12950            }
12951            return pae;
12952        }
12953    }
12954
12955    void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12956        IResultReceiver receiver;
12957        synchronized (this) {
12958            mPendingAssistExtras.remove(pae);
12959            receiver = pae.receiver;
12960        }
12961        if (receiver != null) {
12962            // Caller wants result sent back to them.
12963            Bundle sendBundle = new Bundle();
12964            // At least return the receiver extras
12965            sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12966                    pae.receiverExtras);
12967            try {
12968                pae.receiver.send(0, sendBundle);
12969            } catch (RemoteException e) {
12970            }
12971        }
12972    }
12973
12974    private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12975        if (result != null) {
12976            pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12977        }
12978        if (pae.hint != null) {
12979            pae.extras.putBoolean(pae.hint, true);
12980        }
12981    }
12982
12983    /** Called from an app when assist data is ready. */
12984    @Override
12985    public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12986            AssistContent content, Uri referrer) {
12987        PendingAssistExtras pae = (PendingAssistExtras)token;
12988        synchronized (pae) {
12989            pae.result = extras;
12990            pae.structure = structure;
12991            pae.content = content;
12992            if (referrer != null) {
12993                pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12994            }
12995            if (structure != null) {
12996                structure.setHomeActivity(pae.isHome);
12997            }
12998            pae.haveResult = true;
12999            pae.notifyAll();
13000            if (pae.intent == null && pae.receiver == null) {
13001                // Caller is just waiting for the result.
13002                return;
13003            }
13004        }
13005
13006        // We are now ready to launch the assist activity.
13007        IResultReceiver sendReceiver = null;
13008        Bundle sendBundle = null;
13009        synchronized (this) {
13010            buildAssistBundleLocked(pae, extras);
13011            boolean exists = mPendingAssistExtras.remove(pae);
13012            mUiHandler.removeCallbacks(pae);
13013            if (!exists) {
13014                // Timed out.
13015                return;
13016            }
13017            if ((sendReceiver=pae.receiver) != null) {
13018                // Caller wants result sent back to them.
13019                sendBundle = new Bundle();
13020                sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13021                sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13022                sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13023                sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13024                        pae.receiverExtras);
13025            }
13026        }
13027        if (sendReceiver != null) {
13028            try {
13029                sendReceiver.send(0, sendBundle);
13030            } catch (RemoteException e) {
13031            }
13032            return;
13033        }
13034
13035        long ident = Binder.clearCallingIdentity();
13036        try {
13037            pae.intent.replaceExtras(pae.extras);
13038            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13039                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
13040                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13041            closeSystemDialogs("assist");
13042            try {
13043                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13044            } catch (ActivityNotFoundException e) {
13045                Slog.w(TAG, "No activity to handle assist action.", e);
13046            }
13047        } finally {
13048            Binder.restoreCallingIdentity(ident);
13049        }
13050    }
13051
13052    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13053            Bundle args) {
13054        return enqueueAssistContext(requestType, intent, hint, null, null, null,
13055                true /* focused */, true /* newSessionId */, userHandle, args,
13056                PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
13057    }
13058
13059    public void registerProcessObserver(IProcessObserver observer) {
13060        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13061                "registerProcessObserver()");
13062        synchronized (this) {
13063            mProcessObservers.register(observer);
13064        }
13065    }
13066
13067    @Override
13068    public void unregisterProcessObserver(IProcessObserver observer) {
13069        synchronized (this) {
13070            mProcessObservers.unregister(observer);
13071        }
13072    }
13073
13074    @Override
13075    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13076            String callingPackage) {
13077        if (!hasUsageStatsPermission(callingPackage)) {
13078            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13079                    "registerUidObserver");
13080        }
13081        synchronized (this) {
13082            mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13083                    callingPackage, which, cutpoint));
13084        }
13085    }
13086
13087    @Override
13088    public void unregisterUidObserver(IUidObserver observer) {
13089        synchronized (this) {
13090            mUidObservers.unregister(observer);
13091        }
13092    }
13093
13094    @Override
13095    public boolean convertFromTranslucent(IBinder token) {
13096        final long origId = Binder.clearCallingIdentity();
13097        try {
13098            synchronized (this) {
13099                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13100                if (r == null) {
13101                    return false;
13102                }
13103                final boolean translucentChanged = r.changeWindowTranslucency(true);
13104                if (translucentChanged) {
13105                    r.getStack().releaseBackgroundResources(r);
13106                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13107                }
13108                mWindowManager.setAppFullscreen(token, true);
13109                return translucentChanged;
13110            }
13111        } finally {
13112            Binder.restoreCallingIdentity(origId);
13113        }
13114    }
13115
13116    @Override
13117    public boolean convertToTranslucent(IBinder token, Bundle options) {
13118        final long origId = Binder.clearCallingIdentity();
13119        try {
13120            synchronized (this) {
13121                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13122                if (r == null) {
13123                    return false;
13124                }
13125                int index = r.task.mActivities.lastIndexOf(r);
13126                if (index > 0) {
13127                    ActivityRecord under = r.task.mActivities.get(index - 1);
13128                    under.returningOptions = ActivityOptions.fromBundle(options);
13129                }
13130                final boolean translucentChanged = r.changeWindowTranslucency(false);
13131                if (translucentChanged) {
13132                    r.getStack().convertActivityToTranslucent(r);
13133                }
13134                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13135                mWindowManager.setAppFullscreen(token, false);
13136                return translucentChanged;
13137            }
13138        } finally {
13139            Binder.restoreCallingIdentity(origId);
13140        }
13141    }
13142
13143    @Override
13144    public boolean requestVisibleBehind(IBinder token, boolean visible) {
13145        final long origId = Binder.clearCallingIdentity();
13146        try {
13147            synchronized (this) {
13148                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13149                if (r != null) {
13150                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
13151                }
13152            }
13153            return false;
13154        } finally {
13155            Binder.restoreCallingIdentity(origId);
13156        }
13157    }
13158
13159    @Override
13160    public boolean isBackgroundVisibleBehind(IBinder token) {
13161        final long origId = Binder.clearCallingIdentity();
13162        try {
13163            synchronized (this) {
13164                final ActivityStack stack = ActivityRecord.getStackLocked(token);
13165                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
13166                if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
13167                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
13168                return visible;
13169            }
13170        } finally {
13171            Binder.restoreCallingIdentity(origId);
13172        }
13173    }
13174
13175    @Override
13176    public Bundle getActivityOptions(IBinder token) {
13177        final long origId = Binder.clearCallingIdentity();
13178        try {
13179            synchronized (this) {
13180                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13181                if (r != null) {
13182                    final ActivityOptions activityOptions = r.pendingOptions;
13183                    r.pendingOptions = null;
13184                    return activityOptions == null ? null : activityOptions.toBundle();
13185                }
13186                return null;
13187            }
13188        } finally {
13189            Binder.restoreCallingIdentity(origId);
13190        }
13191    }
13192
13193    @Override
13194    public void setImmersive(IBinder token, boolean immersive) {
13195        synchronized(this) {
13196            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13197            if (r == null) {
13198                throw new IllegalArgumentException();
13199            }
13200            r.immersive = immersive;
13201
13202            // update associated state if we're frontmost
13203            if (r == mStackSupervisor.getResumedActivityLocked()) {
13204                if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13205                applyUpdateLockStateLocked(r);
13206            }
13207        }
13208    }
13209
13210    @Override
13211    public boolean isImmersive(IBinder token) {
13212        synchronized (this) {
13213            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13214            if (r == null) {
13215                throw new IllegalArgumentException();
13216            }
13217            return r.immersive;
13218        }
13219    }
13220
13221    @Override
13222    public void setVrThread(int tid) {
13223        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13224            throw new UnsupportedOperationException("VR mode not supported on this device!");
13225        }
13226
13227        synchronized (this) {
13228            if (tid > 0 && mVrState == PERSISTENT_VR_MODE) {
13229                Slog.e(TAG, "VR thread cannot be set in persistent VR mode!");
13230                return;
13231            }
13232            ProcessRecord proc;
13233            synchronized (mPidsSelfLocked) {
13234                final int pid = Binder.getCallingPid();
13235                proc = mPidsSelfLocked.get(pid);
13236                if (proc != null && mVrState == VR_MODE && tid >= 0) {
13237                    proc.vrThreadTid = updateVrThreadLocked(proc, proc.vrThreadTid, pid, tid);
13238                    mTopAppVrThreadTid = proc.vrThreadTid;
13239                }
13240            }
13241        }
13242    }
13243
13244    @Override
13245    public void setPersistentVrThread(int tid) {
13246        if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13247            String msg = "Permission Denial: setPersistentVrThread() from pid="
13248                    + Binder.getCallingPid()
13249                    + ", uid=" + Binder.getCallingUid()
13250                    + " requires " + permission.RESTRICTED_VR_ACCESS;
13251            Slog.w(TAG, msg);
13252            throw new SecurityException(msg);
13253        }
13254        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13255            throw new UnsupportedOperationException("VR mode not supported on this device!");
13256        }
13257
13258        synchronized (this) {
13259            // Disable any existing VR thread.
13260            if (mTopAppVrThreadTid > 0) {
13261                Process.setThreadScheduler(mTopAppVrThreadTid, Process.SCHED_OTHER, 0);
13262                mTopAppVrThreadTid = 0;
13263            }
13264
13265            if (tid > 0 && mVrState != PERSISTENT_VR_MODE) {
13266                Slog.e(TAG, "Persistent VR thread may only be set in persistent VR mode!");
13267                return;
13268            }
13269            ProcessRecord proc;
13270            synchronized (mPidsSelfLocked) {
13271                final int pid = Binder.getCallingPid();
13272                mPersistentVrThreadTid =
13273                        updateVrThreadLocked(null, mPersistentVrThreadTid, pid, tid);
13274            }
13275        }
13276    }
13277
13278    /**
13279     * Used by setVrThread and setPersistentVrThread to update a thread's priority. When proc is
13280     * non-null it must be in SCHED_GROUP_TOP_APP.  When it is null, the tid is unconditionally
13281     * rescheduled.
13282     */
13283    private int updateVrThreadLocked(ProcessRecord proc, int lastTid, int pid, int tid) {
13284        // ensure the tid belongs to the process
13285        if (!Process.isThreadInProcess(pid, tid)) {
13286            throw new IllegalArgumentException("VR thread does not belong to process");
13287        }
13288
13289        // reset existing VR thread to CFS if this thread still exists and belongs to
13290        // the calling process
13291        if (lastTid != 0 && Process.isThreadInProcess(pid, lastTid)) {
13292            try {
13293                Process.setThreadScheduler(lastTid, Process.SCHED_OTHER, 0);
13294            } catch (IllegalArgumentException e) {
13295                // Ignore this.  Only occurs in race condition where previous VR thread
13296                // was destroyed during this method call.
13297            }
13298        }
13299
13300        // promote to FIFO now if the tid is non-zero
13301        try {
13302            if ((proc == null || proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP)
13303                    && tid > 0) {
13304                Process.setThreadScheduler(tid,
13305                    Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13306            }
13307            return tid;
13308        } catch (IllegalArgumentException e) {
13309            Slog.e(TAG, "Failed to set scheduling policy, thread does"
13310                   + " not exist:\n" + e);
13311        }
13312        return lastTid;
13313    }
13314
13315    @Override
13316    public void setRenderThread(int tid) {
13317        synchronized (this) {
13318            ProcessRecord proc;
13319            synchronized (mPidsSelfLocked) {
13320                int pid = Binder.getCallingPid();
13321                proc = mPidsSelfLocked.get(pid);
13322                if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13323                    // ensure the tid belongs to the process
13324                    if (!Process.isThreadInProcess(pid, tid)) {
13325                        throw new IllegalArgumentException(
13326                            "Render thread does not belong to process");
13327                    }
13328                    proc.renderThreadTid = tid;
13329                    if (DEBUG_OOM_ADJ) {
13330                        Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13331                    }
13332                    // promote to FIFO now
13333                    if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13334                        if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13335                        if (mUseFifoUiScheduling) {
13336                            Process.setThreadScheduler(proc.renderThreadTid,
13337                                Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13338                        } else {
13339                            Process.setThreadPriority(proc.renderThreadTid, -10);
13340                        }
13341                    }
13342                } else {
13343                    if (DEBUG_OOM_ADJ) {
13344                        Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13345                               "PID: " + pid + ", TID: " + tid + " FIFO: " +
13346                               mUseFifoUiScheduling);
13347                    }
13348                }
13349            }
13350        }
13351    }
13352
13353    @Override
13354    public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13355        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13356            throw new UnsupportedOperationException("VR mode not supported on this device!");
13357        }
13358
13359        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13360
13361        ActivityRecord r;
13362        synchronized (this) {
13363            r = ActivityRecord.isInStackLocked(token);
13364        }
13365
13366        if (r == null) {
13367            throw new IllegalArgumentException();
13368        }
13369
13370        int err;
13371        if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13372                VrManagerInternal.NO_ERROR) {
13373            return err;
13374        }
13375
13376        synchronized(this) {
13377            r.requestedVrComponent = (enabled) ? packageName : null;
13378
13379            // Update associated state if this activity is currently focused
13380            if (r == mStackSupervisor.getResumedActivityLocked()) {
13381                applyUpdateVrModeLocked(r);
13382            }
13383            return 0;
13384        }
13385    }
13386
13387    @Override
13388    public boolean isVrModePackageEnabled(ComponentName packageName) {
13389        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13390            throw new UnsupportedOperationException("VR mode not supported on this device!");
13391        }
13392
13393        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13394
13395        return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13396                VrManagerInternal.NO_ERROR;
13397    }
13398
13399    public boolean isTopActivityImmersive() {
13400        enforceNotIsolatedCaller("startActivity");
13401        synchronized (this) {
13402            ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13403            return (r != null) ? r.immersive : false;
13404        }
13405    }
13406
13407    @Override
13408    public boolean isTopOfTask(IBinder token) {
13409        synchronized (this) {
13410            ActivityRecord r = ActivityRecord.isInStackLocked(token);
13411            if (r == null) {
13412                throw new IllegalArgumentException();
13413            }
13414            return r.task.getTopActivity() == r;
13415        }
13416    }
13417
13418    @Override
13419    public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13420        if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13421            String msg = "Permission Denial: setHasTopUi() from pid="
13422                    + Binder.getCallingPid()
13423                    + ", uid=" + Binder.getCallingUid()
13424                    + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13425            Slog.w(TAG, msg);
13426            throw new SecurityException(msg);
13427        }
13428        final int pid = Binder.getCallingPid();
13429        final long origId = Binder.clearCallingIdentity();
13430        try {
13431            synchronized (this) {
13432                boolean changed = false;
13433                ProcessRecord pr;
13434                synchronized (mPidsSelfLocked) {
13435                    pr = mPidsSelfLocked.get(pid);
13436                    if (pr == null) {
13437                        Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13438                        return;
13439                    }
13440                    if (pr.hasTopUi != hasTopUi) {
13441                        Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13442                        pr.hasTopUi = hasTopUi;
13443                        changed = true;
13444                    }
13445                }
13446                if (changed) {
13447                    updateOomAdjLocked(pr);
13448                }
13449            }
13450        } finally {
13451            Binder.restoreCallingIdentity(origId);
13452        }
13453    }
13454
13455    public final void enterSafeMode() {
13456        synchronized(this) {
13457            // It only makes sense to do this before the system is ready
13458            // and started launching other packages.
13459            if (!mSystemReady) {
13460                try {
13461                    AppGlobals.getPackageManager().enterSafeMode();
13462                } catch (RemoteException e) {
13463                }
13464            }
13465
13466            mSafeMode = true;
13467        }
13468    }
13469
13470    public final void showSafeModeOverlay() {
13471        View v = LayoutInflater.from(mContext).inflate(
13472                com.android.internal.R.layout.safe_mode, null);
13473        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13474        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13475        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13476        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13477        lp.gravity = Gravity.BOTTOM | Gravity.START;
13478        lp.format = v.getBackground().getOpacity();
13479        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13480                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13481        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13482        ((WindowManager)mContext.getSystemService(
13483                Context.WINDOW_SERVICE)).addView(v, lp);
13484    }
13485
13486    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13487        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13488            return;
13489        }
13490        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13491        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13492        synchronized (stats) {
13493            if (mBatteryStatsService.isOnBattery()) {
13494                mBatteryStatsService.enforceCallingPermission();
13495                int MY_UID = Binder.getCallingUid();
13496                final int uid;
13497                if (sender == null) {
13498                    uid = sourceUid;
13499                } else {
13500                    uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
13501                }
13502                BatteryStatsImpl.Uid.Pkg pkg =
13503                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13504                            sourcePkg != null ? sourcePkg : rec.key.packageName);
13505                pkg.noteWakeupAlarmLocked(tag);
13506            }
13507        }
13508    }
13509
13510    public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13511        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13512            return;
13513        }
13514        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13515        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13516        synchronized (stats) {
13517            mBatteryStatsService.enforceCallingPermission();
13518            int MY_UID = Binder.getCallingUid();
13519            final int uid;
13520            if (sender == null) {
13521                uid = sourceUid;
13522            } else {
13523                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
13524            }
13525            mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13526        }
13527    }
13528
13529    public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13530        if (sender != null && !(sender instanceof PendingIntentRecord)) {
13531            return;
13532        }
13533        final PendingIntentRecord rec = (PendingIntentRecord)sender;
13534        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13535        synchronized (stats) {
13536            mBatteryStatsService.enforceCallingPermission();
13537            int MY_UID = Binder.getCallingUid();
13538            final int uid;
13539            if (sender == null) {
13540                uid = sourceUid;
13541            } else {
13542                uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
13543            }
13544            mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13545        }
13546    }
13547
13548    public boolean killPids(int[] pids, String pReason, boolean secure) {
13549        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13550            throw new SecurityException("killPids only available to the system");
13551        }
13552        String reason = (pReason == null) ? "Unknown" : pReason;
13553        // XXX Note: don't acquire main activity lock here, because the window
13554        // manager calls in with its locks held.
13555
13556        boolean killed = false;
13557        synchronized (mPidsSelfLocked) {
13558            int worstType = 0;
13559            for (int i=0; i<pids.length; i++) {
13560                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13561                if (proc != null) {
13562                    int type = proc.setAdj;
13563                    if (type > worstType) {
13564                        worstType = type;
13565                    }
13566                }
13567            }
13568
13569            // If the worst oom_adj is somewhere in the cached proc LRU range,
13570            // then constrain it so we will kill all cached procs.
13571            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13572                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13573                worstType = ProcessList.CACHED_APP_MIN_ADJ;
13574            }
13575
13576            // If this is not a secure call, don't let it kill processes that
13577            // are important.
13578            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13579                worstType = ProcessList.SERVICE_ADJ;
13580            }
13581
13582            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13583            for (int i=0; i<pids.length; i++) {
13584                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13585                if (proc == null) {
13586                    continue;
13587                }
13588                int adj = proc.setAdj;
13589                if (adj >= worstType && !proc.killedByAm) {
13590                    proc.kill(reason, true);
13591                    killed = true;
13592                }
13593            }
13594        }
13595        return killed;
13596    }
13597
13598    @Override
13599    public void killUid(int appId, int userId, String reason) {
13600        enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13601        synchronized (this) {
13602            final long identity = Binder.clearCallingIdentity();
13603            try {
13604                killPackageProcessesLocked(null, appId, userId,
13605                        ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13606                        reason != null ? reason : "kill uid");
13607            } finally {
13608                Binder.restoreCallingIdentity(identity);
13609            }
13610        }
13611    }
13612
13613    @Override
13614    public boolean killProcessesBelowForeground(String reason) {
13615        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13616            throw new SecurityException("killProcessesBelowForeground() only available to system");
13617        }
13618
13619        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13620    }
13621
13622    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13623        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13624            throw new SecurityException("killProcessesBelowAdj() only available to system");
13625        }
13626
13627        boolean killed = false;
13628        synchronized (mPidsSelfLocked) {
13629            final int size = mPidsSelfLocked.size();
13630            for (int i = 0; i < size; i++) {
13631                final int pid = mPidsSelfLocked.keyAt(i);
13632                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13633                if (proc == null) continue;
13634
13635                final int adj = proc.setAdj;
13636                if (adj > belowAdj && !proc.killedByAm) {
13637                    proc.kill(reason, true);
13638                    killed = true;
13639                }
13640            }
13641        }
13642        return killed;
13643    }
13644
13645    @Override
13646    public void hang(final IBinder who, boolean allowRestart) {
13647        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13648                != PackageManager.PERMISSION_GRANTED) {
13649            throw new SecurityException("Requires permission "
13650                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13651        }
13652
13653        final IBinder.DeathRecipient death = new DeathRecipient() {
13654            @Override
13655            public void binderDied() {
13656                synchronized (this) {
13657                    notifyAll();
13658                }
13659            }
13660        };
13661
13662        try {
13663            who.linkToDeath(death, 0);
13664        } catch (RemoteException e) {
13665            Slog.w(TAG, "hang: given caller IBinder is already dead.");
13666            return;
13667        }
13668
13669        synchronized (this) {
13670            Watchdog.getInstance().setAllowRestart(allowRestart);
13671            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13672            synchronized (death) {
13673                while (who.isBinderAlive()) {
13674                    try {
13675                        death.wait();
13676                    } catch (InterruptedException e) {
13677                    }
13678                }
13679            }
13680            Watchdog.getInstance().setAllowRestart(true);
13681        }
13682    }
13683
13684    @Override
13685    public void restart() {
13686        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13687                != PackageManager.PERMISSION_GRANTED) {
13688            throw new SecurityException("Requires permission "
13689                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13690        }
13691
13692        Log.i(TAG, "Sending shutdown broadcast...");
13693
13694        BroadcastReceiver br = new BroadcastReceiver() {
13695            @Override public void onReceive(Context context, Intent intent) {
13696                // Now the broadcast is done, finish up the low-level shutdown.
13697                Log.i(TAG, "Shutting down activity manager...");
13698                shutdown(10000);
13699                Log.i(TAG, "Shutdown complete, restarting!");
13700                Process.killProcess(Process.myPid());
13701                System.exit(10);
13702            }
13703        };
13704
13705        // First send the high-level shut down broadcast.
13706        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13707        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13708        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13709        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13710        mContext.sendOrderedBroadcastAsUser(intent,
13711                UserHandle.ALL, null, br, mHandler, 0, null, null);
13712        */
13713        br.onReceive(mContext, intent);
13714    }
13715
13716    private long getLowRamTimeSinceIdle(long now) {
13717        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13718    }
13719
13720    @Override
13721    public void performIdleMaintenance() {
13722        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13723                != PackageManager.PERMISSION_GRANTED) {
13724            throw new SecurityException("Requires permission "
13725                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13726        }
13727
13728        synchronized (this) {
13729            final long now = SystemClock.uptimeMillis();
13730            final long timeSinceLastIdle = now - mLastIdleTime;
13731            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13732            mLastIdleTime = now;
13733            mLowRamTimeSinceLastIdle = 0;
13734            if (mLowRamStartTime != 0) {
13735                mLowRamStartTime = now;
13736            }
13737
13738            StringBuilder sb = new StringBuilder(128);
13739            sb.append("Idle maintenance over ");
13740            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13741            sb.append(" low RAM for ");
13742            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13743            Slog.i(TAG, sb.toString());
13744
13745            // If at least 1/3 of our time since the last idle period has been spent
13746            // with RAM low, then we want to kill processes.
13747            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13748
13749            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13750                ProcessRecord proc = mLruProcesses.get(i);
13751                if (proc.notCachedSinceIdle) {
13752                    if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13753                            && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13754                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13755                        if (doKilling && proc.initialIdlePss != 0
13756                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13757                            sb = new StringBuilder(128);
13758                            sb.append("Kill");
13759                            sb.append(proc.processName);
13760                            sb.append(" in idle maint: pss=");
13761                            sb.append(proc.lastPss);
13762                            sb.append(", swapPss=");
13763                            sb.append(proc.lastSwapPss);
13764                            sb.append(", initialPss=");
13765                            sb.append(proc.initialIdlePss);
13766                            sb.append(", period=");
13767                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
13768                            sb.append(", lowRamPeriod=");
13769                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13770                            Slog.wtfQuiet(TAG, sb.toString());
13771                            proc.kill("idle maint (pss " + proc.lastPss
13772                                    + " from " + proc.initialIdlePss + ")", true);
13773                        }
13774                    }
13775                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13776                        && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
13777                    proc.notCachedSinceIdle = true;
13778                    proc.initialIdlePss = 0;
13779                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13780                            mTestPssMode, isSleepingLocked(), now);
13781                }
13782            }
13783
13784            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13785            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13786        }
13787    }
13788
13789    @Override
13790    public void sendIdleJobTrigger() {
13791        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13792                != PackageManager.PERMISSION_GRANTED) {
13793            throw new SecurityException("Requires permission "
13794                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13795        }
13796
13797        final long ident = Binder.clearCallingIdentity();
13798        try {
13799            Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13800                    .setPackage("android")
13801                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13802            broadcastIntent(null, intent, null, null, 0, null, null, null,
13803                    android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13804        } finally {
13805            Binder.restoreCallingIdentity(ident);
13806        }
13807    }
13808
13809    private void retrieveSettings() {
13810        final ContentResolver resolver = mContext.getContentResolver();
13811        final boolean freeformWindowManagement =
13812                mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13813                        || Settings.Global.getInt(
13814                                resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13815        final boolean supportsPictureInPicture =
13816                mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13817
13818        final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13819        final boolean supportsSplitScreenMultiWindow =
13820                ActivityManager.supportsSplitScreenMultiWindow();
13821        final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13822        final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13823        final boolean alwaysFinishActivities =
13824                Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13825        final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13826        final boolean forceResizable = Settings.Global.getInt(
13827                resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13828        final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
13829                NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
13830        final boolean supportsLeanbackOnly =
13831                mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13832
13833        // Transfer any global setting for forcing RTL layout, into a System Property
13834        SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13835
13836        final Configuration configuration = new Configuration();
13837        Settings.System.getConfiguration(resolver, configuration);
13838        if (forceRtl) {
13839            // This will take care of setting the correct layout direction flags
13840            configuration.setLayoutDirection(configuration.locale);
13841        }
13842
13843        synchronized (this) {
13844            mDebugApp = mOrigDebugApp = debugApp;
13845            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13846            mAlwaysFinishActivities = alwaysFinishActivities;
13847            mSupportsLeanbackOnly = supportsLeanbackOnly;
13848            mForceResizableActivities = forceResizable;
13849            if (supportsMultiWindow || forceResizable) {
13850                mSupportsMultiWindow = true;
13851                mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13852            } else {
13853                mSupportsMultiWindow = false;
13854                mSupportsFreeformWindowManagement = false;
13855            }
13856            mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
13857            mSupportsPictureInPicture = supportsPictureInPicture;
13858            mWindowManager.setForceResizableTasks(mForceResizableActivities);
13859            mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
13860            // This happens before any activities are started, so we can change global configuration
13861            // in-place.
13862            updateConfigurationLocked(configuration, null, true);
13863            final Configuration globalConfig = getGlobalConfiguration();
13864            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
13865
13866            // Load resources only after the current configuration has been set.
13867            final Resources res = mContext.getResources();
13868            mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13869            mThumbnailWidth = res.getDimensionPixelSize(
13870                    com.android.internal.R.dimen.thumbnail_width);
13871            mThumbnailHeight = res.getDimensionPixelSize(
13872                    com.android.internal.R.dimen.thumbnail_height);
13873            mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13874                    com.android.internal.R.string.config_appsNotReportingCrashes));
13875            mUserController.mUserSwitchUiEnabled = !res.getBoolean(
13876                    com.android.internal.R.bool.config_customUserSwitchUi);
13877            if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13878                mFullscreenThumbnailScale = (float) res
13879                    .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13880                    (float) globalConfig.screenWidthDp;
13881            } else {
13882                mFullscreenThumbnailScale = res.getFraction(
13883                    com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13884            }
13885            mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
13886        }
13887    }
13888
13889    public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
13890        traceLog.traceBegin("PhaseActivityManagerReady");
13891        synchronized(this) {
13892            if (mSystemReady) {
13893                // If we're done calling all the receivers, run the next "boot phase" passed in
13894                // by the SystemServer
13895                if (goingCallback != null) {
13896                    goingCallback.run();
13897                }
13898                return;
13899            }
13900
13901            mLocalDeviceIdleController
13902                    = LocalServices.getService(DeviceIdleController.LocalService.class);
13903            mAssistUtils = new AssistUtils(mContext);
13904            VrManagerInternal vrManagerInternal = LocalServices.getService(VrManagerInternal.class);
13905            if (vrManagerInternal != null) {
13906                vrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener);
13907            }
13908            // Make sure we have the current profile info, since it is needed for security checks.
13909            mUserController.onSystemReady();
13910            mRecentTasks.onSystemReadyLocked();
13911            mAppOpsService.systemReady();
13912            mSystemReady = true;
13913        }
13914
13915        ArrayList<ProcessRecord> procsToKill = null;
13916        synchronized(mPidsSelfLocked) {
13917            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13918                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13919                if (!isAllowedWhileBooting(proc.info)){
13920                    if (procsToKill == null) {
13921                        procsToKill = new ArrayList<ProcessRecord>();
13922                    }
13923                    procsToKill.add(proc);
13924                }
13925            }
13926        }
13927
13928        synchronized(this) {
13929            if (procsToKill != null) {
13930                for (int i=procsToKill.size()-1; i>=0; i--) {
13931                    ProcessRecord proc = procsToKill.get(i);
13932                    Slog.i(TAG, "Removing system update proc: " + proc);
13933                    removeProcessLocked(proc, true, false, "system update done");
13934                }
13935            }
13936
13937            // Now that we have cleaned up any update processes, we
13938            // are ready to start launching real processes and know that
13939            // we won't trample on them any more.
13940            mProcessesReady = true;
13941        }
13942
13943        Slog.i(TAG, "System now ready");
13944        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13945            SystemClock.uptimeMillis());
13946
13947        synchronized(this) {
13948            // Make sure we have no pre-ready processes sitting around.
13949
13950            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13951                ResolveInfo ri = mContext.getPackageManager()
13952                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13953                                STOCK_PM_FLAGS);
13954                CharSequence errorMsg = null;
13955                if (ri != null) {
13956                    ActivityInfo ai = ri.activityInfo;
13957                    ApplicationInfo app = ai.applicationInfo;
13958                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13959                        mTopAction = Intent.ACTION_FACTORY_TEST;
13960                        mTopData = null;
13961                        mTopComponent = new ComponentName(app.packageName,
13962                                ai.name);
13963                    } else {
13964                        errorMsg = mContext.getResources().getText(
13965                                com.android.internal.R.string.factorytest_not_system);
13966                    }
13967                } else {
13968                    errorMsg = mContext.getResources().getText(
13969                            com.android.internal.R.string.factorytest_no_action);
13970                }
13971                if (errorMsg != null) {
13972                    mTopAction = null;
13973                    mTopData = null;
13974                    mTopComponent = null;
13975                    Message msg = Message.obtain();
13976                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13977                    msg.getData().putCharSequence("msg", errorMsg);
13978                    mUiHandler.sendMessage(msg);
13979                }
13980            }
13981        }
13982
13983        retrieveSettings();
13984        final int currentUserId;
13985        synchronized (this) {
13986            currentUserId = mUserController.getCurrentUserIdLocked();
13987            readGrantedUriPermissionsLocked();
13988        }
13989
13990        if (goingCallback != null) goingCallback.run();
13991        traceLog.traceBegin("ActivityManagerStartApps");
13992        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13993                Integer.toString(currentUserId), currentUserId);
13994        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13995                Integer.toString(currentUserId), currentUserId);
13996        mSystemServiceManager.startUser(currentUserId);
13997
13998        synchronized (this) {
13999            // Only start up encryption-aware persistent apps; once user is
14000            // unlocked we'll come back around and start unaware apps
14001            startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14002
14003            // Start up initial activity.
14004            mBooting = true;
14005            // Enable home activity for system user, so that the system can always boot. We don't
14006            // do this when the system user is not setup since the setup wizard should be the one
14007            // to handle home activity in this case.
14008            if (UserManager.isSplitSystemUser() &&
14009                    Settings.Secure.getInt(mContext.getContentResolver(),
14010                         Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14011                ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14012                try {
14013                    AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14014                            PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14015                            UserHandle.USER_SYSTEM);
14016                } catch (RemoteException e) {
14017                    throw e.rethrowAsRuntimeException();
14018                }
14019            }
14020            startHomeActivityLocked(currentUserId, "systemReady");
14021
14022            try {
14023                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14024                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14025                            + " data partition or your device will be unstable.");
14026                    mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14027                }
14028            } catch (RemoteException e) {
14029            }
14030
14031            if (!Build.isBuildConsistent()) {
14032                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14033                mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14034            }
14035
14036            long ident = Binder.clearCallingIdentity();
14037            try {
14038                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14039                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14040                        | Intent.FLAG_RECEIVER_FOREGROUND);
14041                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14042                broadcastIntentLocked(null, null, intent,
14043                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14044                        null, false, false, MY_PID, Process.SYSTEM_UID,
14045                        currentUserId);
14046                intent = new Intent(Intent.ACTION_USER_STARTING);
14047                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14048                intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14049                broadcastIntentLocked(null, null, intent,
14050                        null, new IIntentReceiver.Stub() {
14051                            @Override
14052                            public void performReceive(Intent intent, int resultCode, String data,
14053                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14054                                    throws RemoteException {
14055                            }
14056                        }, 0, null, null,
14057                        new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14058                        null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14059            } catch (Throwable t) {
14060                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14061            } finally {
14062                Binder.restoreCallingIdentity(ident);
14063            }
14064            mStackSupervisor.resumeFocusedStackTopActivityLocked();
14065            mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14066            traceLog.traceEnd(); // ActivityManagerStartApps
14067            traceLog.traceEnd(); // PhaseActivityManagerReady
14068        }
14069    }
14070
14071    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14072        synchronized (this) {
14073            mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14074        }
14075    }
14076
14077    void skipCurrentReceiverLocked(ProcessRecord app) {
14078        for (BroadcastQueue queue : mBroadcastQueues) {
14079            queue.skipCurrentReceiverLocked(app);
14080        }
14081    }
14082
14083    /**
14084     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14085     * The application process will exit immediately after this call returns.
14086     * @param app object of the crashing app, null for the system server
14087     * @param crashInfo describing the exception
14088     */
14089    public void handleApplicationCrash(IBinder app,
14090            ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14091        ProcessRecord r = findAppProcess(app, "Crash");
14092        final String processName = app == null ? "system_server"
14093                : (r == null ? "unknown" : r.processName);
14094
14095        handleApplicationCrashInner("crash", r, processName, crashInfo);
14096    }
14097
14098    /* Native crash reporting uses this inner version because it needs to be somewhat
14099     * decoupled from the AM-managed cleanup lifecycle
14100     */
14101    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14102            ApplicationErrorReport.CrashInfo crashInfo) {
14103        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14104                UserHandle.getUserId(Binder.getCallingUid()), processName,
14105                r == null ? -1 : r.info.flags,
14106                crashInfo.exceptionClassName,
14107                crashInfo.exceptionMessage,
14108                crashInfo.throwFileName,
14109                crashInfo.throwLineNumber);
14110
14111        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14112
14113        mAppErrors.crashApplication(r, crashInfo);
14114    }
14115
14116    public void handleApplicationStrictModeViolation(
14117            IBinder app,
14118            int violationMask,
14119            StrictMode.ViolationInfo info) {
14120        ProcessRecord r = findAppProcess(app, "StrictMode");
14121        if (r == null) {
14122            return;
14123        }
14124
14125        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14126            Integer stackFingerprint = info.hashCode();
14127            boolean logIt = true;
14128            synchronized (mAlreadyLoggedViolatedStacks) {
14129                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14130                    logIt = false;
14131                    // TODO: sub-sample into EventLog for these, with
14132                    // the info.durationMillis?  Then we'd get
14133                    // the relative pain numbers, without logging all
14134                    // the stack traces repeatedly.  We'd want to do
14135                    // likewise in the client code, which also does
14136                    // dup suppression, before the Binder call.
14137                } else {
14138                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14139                        mAlreadyLoggedViolatedStacks.clear();
14140                    }
14141                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14142                }
14143            }
14144            if (logIt) {
14145                logStrictModeViolationToDropBox(r, info);
14146            }
14147        }
14148
14149        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14150            AppErrorResult result = new AppErrorResult();
14151            synchronized (this) {
14152                final long origId = Binder.clearCallingIdentity();
14153
14154                Message msg = Message.obtain();
14155                msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14156                HashMap<String, Object> data = new HashMap<String, Object>();
14157                data.put("result", result);
14158                data.put("app", r);
14159                data.put("violationMask", violationMask);
14160                data.put("info", info);
14161                msg.obj = data;
14162                mUiHandler.sendMessage(msg);
14163
14164                Binder.restoreCallingIdentity(origId);
14165            }
14166            int res = result.get();
14167            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14168        }
14169    }
14170
14171    // Depending on the policy in effect, there could be a bunch of
14172    // these in quick succession so we try to batch these together to
14173    // minimize disk writes, number of dropbox entries, and maximize
14174    // compression, by having more fewer, larger records.
14175    private void logStrictModeViolationToDropBox(
14176            ProcessRecord process,
14177            StrictMode.ViolationInfo info) {
14178        if (info == null) {
14179            return;
14180        }
14181        final boolean isSystemApp = process == null ||
14182                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14183                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14184        final String processName = process == null ? "unknown" : process.processName;
14185        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14186        final DropBoxManager dbox = (DropBoxManager)
14187                mContext.getSystemService(Context.DROPBOX_SERVICE);
14188
14189        // Exit early if the dropbox isn't configured to accept this report type.
14190        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14191
14192        boolean bufferWasEmpty;
14193        boolean needsFlush;
14194        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14195        synchronized (sb) {
14196            bufferWasEmpty = sb.length() == 0;
14197            appendDropBoxProcessHeaders(process, processName, sb);
14198            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14199            sb.append("System-App: ").append(isSystemApp).append("\n");
14200            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14201            if (info.violationNumThisLoop != 0) {
14202                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14203            }
14204            if (info.numAnimationsRunning != 0) {
14205                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14206            }
14207            if (info.broadcastIntentAction != null) {
14208                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14209            }
14210            if (info.durationMillis != -1) {
14211                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14212            }
14213            if (info.numInstances != -1) {
14214                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14215            }
14216            if (info.tags != null) {
14217                for (String tag : info.tags) {
14218                    sb.append("Span-Tag: ").append(tag).append("\n");
14219                }
14220            }
14221            sb.append("\n");
14222            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14223                sb.append(info.crashInfo.stackTrace);
14224                sb.append("\n");
14225            }
14226            if (info.message != null) {
14227                sb.append(info.message);
14228                sb.append("\n");
14229            }
14230
14231            // Only buffer up to ~64k.  Various logging bits truncate
14232            // things at 128k.
14233            needsFlush = (sb.length() > 64 * 1024);
14234        }
14235
14236        // Flush immediately if the buffer's grown too large, or this
14237        // is a non-system app.  Non-system apps are isolated with a
14238        // different tag & policy and not batched.
14239        //
14240        // Batching is useful during internal testing with
14241        // StrictMode settings turned up high.  Without batching,
14242        // thousands of separate files could be created on boot.
14243        if (!isSystemApp || needsFlush) {
14244            new Thread("Error dump: " + dropboxTag) {
14245                @Override
14246                public void run() {
14247                    String report;
14248                    synchronized (sb) {
14249                        report = sb.toString();
14250                        sb.delete(0, sb.length());
14251                        sb.trimToSize();
14252                    }
14253                    if (report.length() != 0) {
14254                        dbox.addText(dropboxTag, report);
14255                    }
14256                }
14257            }.start();
14258            return;
14259        }
14260
14261        // System app batching:
14262        if (!bufferWasEmpty) {
14263            // An existing dropbox-writing thread is outstanding, so
14264            // we don't need to start it up.  The existing thread will
14265            // catch the buffer appends we just did.
14266            return;
14267        }
14268
14269        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14270        // (After this point, we shouldn't access AMS internal data structures.)
14271        new Thread("Error dump: " + dropboxTag) {
14272            @Override
14273            public void run() {
14274                // 5 second sleep to let stacks arrive and be batched together
14275                try {
14276                    Thread.sleep(5000);  // 5 seconds
14277                } catch (InterruptedException e) {}
14278
14279                String errorReport;
14280                synchronized (mStrictModeBuffer) {
14281                    errorReport = mStrictModeBuffer.toString();
14282                    if (errorReport.length() == 0) {
14283                        return;
14284                    }
14285                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14286                    mStrictModeBuffer.trimToSize();
14287                }
14288                dbox.addText(dropboxTag, errorReport);
14289            }
14290        }.start();
14291    }
14292
14293    /**
14294     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14295     * @param app object of the crashing app, null for the system server
14296     * @param tag reported by the caller
14297     * @param system whether this wtf is coming from the system
14298     * @param crashInfo describing the context of the error
14299     * @return true if the process should exit immediately (WTF is fatal)
14300     */
14301    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14302            final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14303        final int callingUid = Binder.getCallingUid();
14304        final int callingPid = Binder.getCallingPid();
14305
14306        if (system) {
14307            // If this is coming from the system, we could very well have low-level
14308            // system locks held, so we want to do this all asynchronously.  And we
14309            // never want this to become fatal, so there is that too.
14310            mHandler.post(new Runnable() {
14311                @Override public void run() {
14312                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14313                }
14314            });
14315            return false;
14316        }
14317
14318        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14319                crashInfo);
14320
14321        final boolean isFatal = "eng".equals(Build.TYPE) || Settings.Global
14322                .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14323        final boolean isSystem = (r == null) || r.persistent;
14324
14325        if (isFatal && !isSystem) {
14326            mAppErrors.crashApplication(r, crashInfo);
14327            return true;
14328        } else {
14329            return false;
14330        }
14331    }
14332
14333    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14334            final ApplicationErrorReport.CrashInfo crashInfo) {
14335        final ProcessRecord r = findAppProcess(app, "WTF");
14336        final String processName = app == null ? "system_server"
14337                : (r == null ? "unknown" : r.processName);
14338
14339        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14340                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14341
14342        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14343
14344        return r;
14345    }
14346
14347    /**
14348     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14349     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14350     */
14351    private ProcessRecord findAppProcess(IBinder app, String reason) {
14352        if (app == null) {
14353            return null;
14354        }
14355
14356        synchronized (this) {
14357            final int NP = mProcessNames.getMap().size();
14358            for (int ip=0; ip<NP; ip++) {
14359                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14360                final int NA = apps.size();
14361                for (int ia=0; ia<NA; ia++) {
14362                    ProcessRecord p = apps.valueAt(ia);
14363                    if (p.thread != null && p.thread.asBinder() == app) {
14364                        return p;
14365                    }
14366                }
14367            }
14368
14369            Slog.w(TAG, "Can't find mystery application for " + reason
14370                    + " from pid=" + Binder.getCallingPid()
14371                    + " uid=" + Binder.getCallingUid() + ": " + app);
14372            return null;
14373        }
14374    }
14375
14376    /**
14377     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14378     * to append various headers to the dropbox log text.
14379     */
14380    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14381            StringBuilder sb) {
14382        // Watchdog thread ends up invoking this function (with
14383        // a null ProcessRecord) to add the stack file to dropbox.
14384        // Do not acquire a lock on this (am) in such cases, as it
14385        // could cause a potential deadlock, if and when watchdog
14386        // is invoked due to unavailability of lock on am and it
14387        // would prevent watchdog from killing system_server.
14388        if (process == null) {
14389            sb.append("Process: ").append(processName).append("\n");
14390            return;
14391        }
14392        // Note: ProcessRecord 'process' is guarded by the service
14393        // instance.  (notably process.pkgList, which could otherwise change
14394        // concurrently during execution of this method)
14395        synchronized (this) {
14396            sb.append("Process: ").append(processName).append("\n");
14397            int flags = process.info.flags;
14398            IPackageManager pm = AppGlobals.getPackageManager();
14399            sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14400            for (int ip=0; ip<process.pkgList.size(); ip++) {
14401                String pkg = process.pkgList.keyAt(ip);
14402                sb.append("Package: ").append(pkg);
14403                try {
14404                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14405                    if (pi != null) {
14406                        sb.append(" v").append(pi.versionCode);
14407                        if (pi.versionName != null) {
14408                            sb.append(" (").append(pi.versionName).append(")");
14409                        }
14410                    }
14411                } catch (RemoteException e) {
14412                    Slog.e(TAG, "Error getting package info: " + pkg, e);
14413                }
14414                sb.append("\n");
14415            }
14416        }
14417    }
14418
14419    private static String processClass(ProcessRecord process) {
14420        if (process == null || process.pid == MY_PID) {
14421            return "system_server";
14422        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14423            return "system_app";
14424        } else {
14425            return "data_app";
14426        }
14427    }
14428
14429    private volatile long mWtfClusterStart;
14430    private volatile int mWtfClusterCount;
14431
14432    /**
14433     * Write a description of an error (crash, WTF, ANR) to the drop box.
14434     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14435     * @param process which caused the error, null means the system server
14436     * @param activity which triggered the error, null if unknown
14437     * @param parent activity related to the error, null if unknown
14438     * @param subject line related to the error, null if absent
14439     * @param report in long form describing the error, null if absent
14440     * @param dataFile text file to include in the report, null if none
14441     * @param crashInfo giving an application stack trace, null if absent
14442     */
14443    public void addErrorToDropBox(String eventType,
14444            ProcessRecord process, String processName, ActivityRecord activity,
14445            ActivityRecord parent, String subject,
14446            final String report, final File dataFile,
14447            final ApplicationErrorReport.CrashInfo crashInfo) {
14448        // NOTE -- this must never acquire the ActivityManagerService lock,
14449        // otherwise the watchdog may be prevented from resetting the system.
14450
14451        // Bail early if not published yet
14452        if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14453        final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14454
14455        // Exit early if the dropbox isn't configured to accept this report type.
14456        final String dropboxTag = processClass(process) + "_" + eventType;
14457        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14458
14459        // Rate-limit how often we're willing to do the heavy lifting below to
14460        // collect and record logs; currently 5 logs per 10 second period.
14461        final long now = SystemClock.elapsedRealtime();
14462        if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14463            mWtfClusterStart = now;
14464            mWtfClusterCount = 1;
14465        } else {
14466            if (mWtfClusterCount++ >= 5) return;
14467        }
14468
14469        final StringBuilder sb = new StringBuilder(1024);
14470        appendDropBoxProcessHeaders(process, processName, sb);
14471        if (process != null) {
14472            sb.append("Foreground: ")
14473                    .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14474                    .append("\n");
14475        }
14476        if (activity != null) {
14477            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14478        }
14479        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14480            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14481        }
14482        if (parent != null && parent != activity) {
14483            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14484        }
14485        if (subject != null) {
14486            sb.append("Subject: ").append(subject).append("\n");
14487        }
14488        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14489        if (Debug.isDebuggerConnected()) {
14490            sb.append("Debugger: Connected\n");
14491        }
14492        sb.append("\n");
14493
14494        // Do the rest in a worker thread to avoid blocking the caller on I/O
14495        // (After this point, we shouldn't access AMS internal data structures.)
14496        Thread worker = new Thread("Error dump: " + dropboxTag) {
14497            @Override
14498            public void run() {
14499                if (report != null) {
14500                    sb.append(report);
14501                }
14502
14503                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14504                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14505                int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14506                        - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14507
14508                if (dataFile != null && maxDataFileSize > 0) {
14509                    try {
14510                        sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14511                                    "\n\n[[TRUNCATED]]"));
14512                    } catch (IOException e) {
14513                        Slog.e(TAG, "Error reading " + dataFile, e);
14514                    }
14515                }
14516                if (crashInfo != null && crashInfo.stackTrace != null) {
14517                    sb.append(crashInfo.stackTrace);
14518                }
14519
14520                if (lines > 0) {
14521                    sb.append("\n");
14522
14523                    // Merge several logcat streams, and take the last N lines
14524                    InputStreamReader input = null;
14525                    try {
14526                        java.lang.Process logcat = new ProcessBuilder(
14527                                "/system/bin/timeout", "-k", "15s", "10s",
14528                                "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14529                                "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14530                                        .redirectErrorStream(true).start();
14531
14532                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
14533                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
14534                        input = new InputStreamReader(logcat.getInputStream());
14535
14536                        int num;
14537                        char[] buf = new char[8192];
14538                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14539                    } catch (IOException e) {
14540                        Slog.e(TAG, "Error running logcat", e);
14541                    } finally {
14542                        if (input != null) try { input.close(); } catch (IOException e) {}
14543                    }
14544                }
14545
14546                dbox.addText(dropboxTag, sb.toString());
14547            }
14548        };
14549
14550        if (process == null) {
14551            // If process is null, we are being called from some internal code
14552            // and may be about to die -- run this synchronously.
14553            worker.run();
14554        } else {
14555            worker.start();
14556        }
14557    }
14558
14559    @Override
14560    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14561        enforceNotIsolatedCaller("getProcessesInErrorState");
14562        // assume our apps are happy - lazy create the list
14563        List<ActivityManager.ProcessErrorStateInfo> errList = null;
14564
14565        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14566                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14567        int userId = UserHandle.getUserId(Binder.getCallingUid());
14568
14569        synchronized (this) {
14570
14571            // iterate across all processes
14572            for (int i=mLruProcesses.size()-1; i>=0; i--) {
14573                ProcessRecord app = mLruProcesses.get(i);
14574                if (!allUsers && app.userId != userId) {
14575                    continue;
14576                }
14577                if ((app.thread != null) && (app.crashing || app.notResponding)) {
14578                    // This one's in trouble, so we'll generate a report for it
14579                    // crashes are higher priority (in case there's a crash *and* an anr)
14580                    ActivityManager.ProcessErrorStateInfo report = null;
14581                    if (app.crashing) {
14582                        report = app.crashingReport;
14583                    } else if (app.notResponding) {
14584                        report = app.notRespondingReport;
14585                    }
14586
14587                    if (report != null) {
14588                        if (errList == null) {
14589                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14590                        }
14591                        errList.add(report);
14592                    } else {
14593                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
14594                                " crashing = " + app.crashing +
14595                                " notResponding = " + app.notResponding);
14596                    }
14597                }
14598            }
14599        }
14600
14601        return errList;
14602    }
14603
14604    static int procStateToImportance(int procState, int memAdj,
14605            ActivityManager.RunningAppProcessInfo currApp) {
14606        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
14607        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14608            currApp.lru = memAdj;
14609        } else {
14610            currApp.lru = 0;
14611        }
14612        return imp;
14613    }
14614
14615    private void fillInProcMemInfo(ProcessRecord app,
14616            ActivityManager.RunningAppProcessInfo outInfo) {
14617        outInfo.pid = app.pid;
14618        outInfo.uid = app.info.uid;
14619        if (mHeavyWeightProcess == app) {
14620            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14621        }
14622        if (app.persistent) {
14623            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14624        }
14625        if (app.activities.size() > 0) {
14626            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14627        }
14628        outInfo.lastTrimLevel = app.trimMemoryLevel;
14629        int adj = app.curAdj;
14630        int procState = app.curProcState;
14631        outInfo.importance = procStateToImportance(procState, adj, outInfo);
14632        outInfo.importanceReasonCode = app.adjTypeCode;
14633        outInfo.processState = app.curProcState;
14634    }
14635
14636    @Override
14637    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14638        enforceNotIsolatedCaller("getRunningAppProcesses");
14639
14640        final int callingUid = Binder.getCallingUid();
14641
14642        // Lazy instantiation of list
14643        List<ActivityManager.RunningAppProcessInfo> runList = null;
14644        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14645                callingUid) == PackageManager.PERMISSION_GRANTED;
14646        final int userId = UserHandle.getUserId(callingUid);
14647        final boolean allUids = isGetTasksAllowed(
14648                "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14649
14650        synchronized (this) {
14651            // Iterate across all processes
14652            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14653                ProcessRecord app = mLruProcesses.get(i);
14654                if ((!allUsers && app.userId != userId)
14655                        || (!allUids && app.uid != callingUid)) {
14656                    continue;
14657                }
14658                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14659                    // Generate process state info for running application
14660                    ActivityManager.RunningAppProcessInfo currApp =
14661                        new ActivityManager.RunningAppProcessInfo(app.processName,
14662                                app.pid, app.getPackageList());
14663                    fillInProcMemInfo(app, currApp);
14664                    if (app.adjSource instanceof ProcessRecord) {
14665                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14666                        currApp.importanceReasonImportance =
14667                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
14668                                        app.adjSourceProcState);
14669                    } else if (app.adjSource instanceof ActivityRecord) {
14670                        ActivityRecord r = (ActivityRecord)app.adjSource;
14671                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14672                    }
14673                    if (app.adjTarget instanceof ComponentName) {
14674                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14675                    }
14676                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14677                    //        + " lru=" + currApp.lru);
14678                    if (runList == null) {
14679                        runList = new ArrayList<>();
14680                    }
14681                    runList.add(currApp);
14682                }
14683            }
14684        }
14685        return runList;
14686    }
14687
14688    @Override
14689    public List<ApplicationInfo> getRunningExternalApplications() {
14690        enforceNotIsolatedCaller("getRunningExternalApplications");
14691        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14692        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14693        if (runningApps != null && runningApps.size() > 0) {
14694            Set<String> extList = new HashSet<String>();
14695            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14696                if (app.pkgList != null) {
14697                    for (String pkg : app.pkgList) {
14698                        extList.add(pkg);
14699                    }
14700                }
14701            }
14702            IPackageManager pm = AppGlobals.getPackageManager();
14703            for (String pkg : extList) {
14704                try {
14705                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14706                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14707                        retList.add(info);
14708                    }
14709                } catch (RemoteException e) {
14710                }
14711            }
14712        }
14713        return retList;
14714    }
14715
14716    @Override
14717    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14718        enforceNotIsolatedCaller("getMyMemoryState");
14719        synchronized (this) {
14720            ProcessRecord proc;
14721            synchronized (mPidsSelfLocked) {
14722                proc = mPidsSelfLocked.get(Binder.getCallingPid());
14723            }
14724            fillInProcMemInfo(proc, outInfo);
14725        }
14726    }
14727
14728    @Override
14729    public int getMemoryTrimLevel() {
14730        enforceNotIsolatedCaller("getMyMemoryState");
14731        synchronized (this) {
14732            return mLastMemoryLevel;
14733        }
14734    }
14735
14736    @Override
14737    public void onShellCommand(FileDescriptor in, FileDescriptor out,
14738            FileDescriptor err, String[] args, ShellCallback callback,
14739            ResultReceiver resultReceiver) {
14740        (new ActivityManagerShellCommand(this, false)).exec(
14741                this, in, out, err, args, callback, resultReceiver);
14742    }
14743
14744    @Override
14745    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14746        if (checkCallingPermission(android.Manifest.permission.DUMP)
14747                != PackageManager.PERMISSION_GRANTED) {
14748            pw.println("Permission Denial: can't dump ActivityManager from from pid="
14749                    + Binder.getCallingPid()
14750                    + ", uid=" + Binder.getCallingUid()
14751                    + " without permission "
14752                    + android.Manifest.permission.DUMP);
14753            return;
14754        }
14755
14756        boolean dumpAll = false;
14757        boolean dumpClient = false;
14758        boolean dumpCheckin = false;
14759        boolean dumpCheckinFormat = false;
14760        boolean dumpVisibleStacksOnly = false;
14761        boolean dumpFocusedStackOnly = false;
14762        String dumpPackage = null;
14763
14764        int opti = 0;
14765        while (opti < args.length) {
14766            String opt = args[opti];
14767            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14768                break;
14769            }
14770            opti++;
14771            if ("-a".equals(opt)) {
14772                dumpAll = true;
14773            } else if ("-c".equals(opt)) {
14774                dumpClient = true;
14775            } else if ("-v".equals(opt)) {
14776                dumpVisibleStacksOnly = true;
14777            } else if ("-f".equals(opt)) {
14778                dumpFocusedStackOnly = true;
14779            } else if ("-p".equals(opt)) {
14780                if (opti < args.length) {
14781                    dumpPackage = args[opti];
14782                    opti++;
14783                } else {
14784                    pw.println("Error: -p option requires package argument");
14785                    return;
14786                }
14787                dumpClient = true;
14788            } else if ("--checkin".equals(opt)) {
14789                dumpCheckin = dumpCheckinFormat = true;
14790            } else if ("-C".equals(opt)) {
14791                dumpCheckinFormat = true;
14792            } else if ("-h".equals(opt)) {
14793                ActivityManagerShellCommand.dumpHelp(pw, true);
14794                return;
14795            } else {
14796                pw.println("Unknown argument: " + opt + "; use -h for help");
14797            }
14798        }
14799
14800        long origId = Binder.clearCallingIdentity();
14801        boolean more = false;
14802        // Is the caller requesting to dump a particular piece of data?
14803        if (opti < args.length) {
14804            String cmd = args[opti];
14805            opti++;
14806            if ("activities".equals(cmd) || "a".equals(cmd)) {
14807                synchronized (this) {
14808                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14809                }
14810            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14811                synchronized (this) {
14812                    dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14813                }
14814            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14815                String[] newArgs;
14816                String name;
14817                if (opti >= args.length) {
14818                    name = null;
14819                    newArgs = EMPTY_STRING_ARRAY;
14820                } else {
14821                    dumpPackage = args[opti];
14822                    opti++;
14823                    newArgs = new String[args.length - opti];
14824                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14825                            args.length - opti);
14826                }
14827                synchronized (this) {
14828                    dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14829                }
14830            } else if ("broadcast-stats".equals(cmd)) {
14831                String[] newArgs;
14832                String name;
14833                if (opti >= args.length) {
14834                    name = null;
14835                    newArgs = EMPTY_STRING_ARRAY;
14836                } else {
14837                    dumpPackage = args[opti];
14838                    opti++;
14839                    newArgs = new String[args.length - opti];
14840                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14841                            args.length - opti);
14842                }
14843                synchronized (this) {
14844                    if (dumpCheckinFormat) {
14845                        dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14846                                dumpPackage);
14847                    } else {
14848                        dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14849                    }
14850                }
14851            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14852                String[] newArgs;
14853                String name;
14854                if (opti >= args.length) {
14855                    name = null;
14856                    newArgs = EMPTY_STRING_ARRAY;
14857                } else {
14858                    dumpPackage = args[opti];
14859                    opti++;
14860                    newArgs = new String[args.length - opti];
14861                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14862                            args.length - opti);
14863                }
14864                synchronized (this) {
14865                    dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14866                }
14867            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14868                String[] newArgs;
14869                String name;
14870                if (opti >= args.length) {
14871                    name = null;
14872                    newArgs = EMPTY_STRING_ARRAY;
14873                } else {
14874                    dumpPackage = args[opti];
14875                    opti++;
14876                    newArgs = new String[args.length - opti];
14877                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14878                            args.length - opti);
14879                }
14880                synchronized (this) {
14881                    dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14882                }
14883            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14884                synchronized (this) {
14885                    dumpOomLocked(fd, pw, args, opti, true);
14886                }
14887            } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14888                synchronized (this) {
14889                    dumpPermissionsLocked(fd, pw, args, opti, true, null);
14890                }
14891            } else if ("provider".equals(cmd)) {
14892                String[] newArgs;
14893                String name;
14894                if (opti >= args.length) {
14895                    name = null;
14896                    newArgs = EMPTY_STRING_ARRAY;
14897                } else {
14898                    name = args[opti];
14899                    opti++;
14900                    newArgs = new String[args.length - opti];
14901                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14902                }
14903                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14904                    pw.println("No providers match: " + name);
14905                    pw.println("Use -h for help.");
14906                }
14907            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14908                synchronized (this) {
14909                    dumpProvidersLocked(fd, pw, args, opti, true, null);
14910                }
14911            } else if ("service".equals(cmd)) {
14912                String[] newArgs;
14913                String name;
14914                if (opti >= args.length) {
14915                    name = null;
14916                    newArgs = EMPTY_STRING_ARRAY;
14917                } else {
14918                    name = args[opti];
14919                    opti++;
14920                    newArgs = new String[args.length - opti];
14921                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14922                            args.length - opti);
14923                }
14924                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14925                    pw.println("No services match: " + name);
14926                    pw.println("Use -h for help.");
14927                }
14928            } else if ("package".equals(cmd)) {
14929                String[] newArgs;
14930                if (opti >= args.length) {
14931                    pw.println("package: no package name specified");
14932                    pw.println("Use -h for help.");
14933                } else {
14934                    dumpPackage = args[opti];
14935                    opti++;
14936                    newArgs = new String[args.length - opti];
14937                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14938                            args.length - opti);
14939                    args = newArgs;
14940                    opti = 0;
14941                    more = true;
14942                }
14943            } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14944                synchronized (this) {
14945                    dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14946                }
14947            } else if ("settings".equals(cmd)) {
14948                synchronized (this) {
14949                    mConstants.dump(pw);
14950                }
14951            } else if ("services".equals(cmd) || "s".equals(cmd)) {
14952                if (dumpClient) {
14953                    ActiveServices.ServiceDumper dumper;
14954                    synchronized (this) {
14955                        dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14956                                dumpPackage);
14957                    }
14958                    dumper.dumpWithClient();
14959                } else {
14960                    synchronized (this) {
14961                        mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14962                                dumpPackage).dumpLocked();
14963                    }
14964                }
14965            } else if ("locks".equals(cmd)) {
14966                LockGuard.dump(fd, pw, args);
14967            } else {
14968                // Dumping a single activity?
14969                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
14970                        dumpFocusedStackOnly)) {
14971                    ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14972                    int res = shell.exec(this, null, fd, null, args, null,
14973                            new ResultReceiver(null));
14974                    if (res < 0) {
14975                        pw.println("Bad activity command, or no activities match: " + cmd);
14976                        pw.println("Use -h for help.");
14977                    }
14978                }
14979            }
14980            if (!more) {
14981                Binder.restoreCallingIdentity(origId);
14982                return;
14983            }
14984        }
14985
14986        // No piece of data specified, dump everything.
14987        if (dumpCheckinFormat) {
14988            dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14989        } else if (dumpClient) {
14990            ActiveServices.ServiceDumper sdumper;
14991            synchronized (this) {
14992                mConstants.dump(pw);
14993                pw.println();
14994                if (dumpAll) {
14995                    pw.println("-------------------------------------------------------------------------------");
14996                }
14997                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14998                pw.println();
14999                if (dumpAll) {
15000                    pw.println("-------------------------------------------------------------------------------");
15001                }
15002                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15003                pw.println();
15004                if (dumpAll) {
15005                    pw.println("-------------------------------------------------------------------------------");
15006                }
15007                if (dumpAll || dumpPackage != null) {
15008                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15009                    pw.println();
15010                    if (dumpAll) {
15011                        pw.println("-------------------------------------------------------------------------------");
15012                    }
15013                }
15014                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15015                pw.println();
15016                if (dumpAll) {
15017                    pw.println("-------------------------------------------------------------------------------");
15018                }
15019                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15020                pw.println();
15021                if (dumpAll) {
15022                    pw.println("-------------------------------------------------------------------------------");
15023                }
15024                sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15025                        dumpPackage);
15026            }
15027            sdumper.dumpWithClient();
15028            pw.println();
15029            synchronized (this) {
15030                if (dumpAll) {
15031                    pw.println("-------------------------------------------------------------------------------");
15032                }
15033                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15034                pw.println();
15035                if (dumpAll) {
15036                    pw.println("-------------------------------------------------------------------------------");
15037                }
15038                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15039                if (mAssociations.size() > 0) {
15040                    pw.println();
15041                    if (dumpAll) {
15042                        pw.println("-------------------------------------------------------------------------------");
15043                    }
15044                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15045                }
15046                pw.println();
15047                if (dumpAll) {
15048                    pw.println("-------------------------------------------------------------------------------");
15049                }
15050                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15051            }
15052
15053        } else {
15054            synchronized (this) {
15055                mConstants.dump(pw);
15056                pw.println();
15057                if (dumpAll) {
15058                    pw.println("-------------------------------------------------------------------------------");
15059                }
15060                dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15061                pw.println();
15062                if (dumpAll) {
15063                    pw.println("-------------------------------------------------------------------------------");
15064                }
15065                dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15066                pw.println();
15067                if (dumpAll) {
15068                    pw.println("-------------------------------------------------------------------------------");
15069                }
15070                if (dumpAll || dumpPackage != null) {
15071                    dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15072                    pw.println();
15073                    if (dumpAll) {
15074                        pw.println("-------------------------------------------------------------------------------");
15075                    }
15076                }
15077                dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15078                pw.println();
15079                if (dumpAll) {
15080                    pw.println("-------------------------------------------------------------------------------");
15081                }
15082                dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15083                pw.println();
15084                if (dumpAll) {
15085                    pw.println("-------------------------------------------------------------------------------");
15086                }
15087                mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15088                        .dumpLocked();
15089                pw.println();
15090                if (dumpAll) {
15091                    pw.println("-------------------------------------------------------------------------------");
15092                }
15093                dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15094                pw.println();
15095                if (dumpAll) {
15096                    pw.println("-------------------------------------------------------------------------------");
15097                }
15098                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15099                if (mAssociations.size() > 0) {
15100                    pw.println();
15101                    if (dumpAll) {
15102                        pw.println("-------------------------------------------------------------------------------");
15103                    }
15104                    dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15105                }
15106                pw.println();
15107                if (dumpAll) {
15108                    pw.println("-------------------------------------------------------------------------------");
15109                }
15110                dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15111            }
15112        }
15113        Binder.restoreCallingIdentity(origId);
15114    }
15115
15116    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15117            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15118        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15119
15120        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15121                dumpPackage);
15122        boolean needSep = printedAnything;
15123
15124        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15125                mStackSupervisor.getResumedActivityLocked(),
15126                dumpPackage, needSep, "  ResumedActivity: ");
15127        if (printed) {
15128            printedAnything = true;
15129            needSep = false;
15130        }
15131
15132        if (dumpPackage == null) {
15133            if (needSep) {
15134                pw.println();
15135            }
15136            needSep = true;
15137            printedAnything = true;
15138            mStackSupervisor.dump(pw, "  ");
15139        }
15140
15141        if (!printedAnything) {
15142            pw.println("  (nothing)");
15143        }
15144    }
15145
15146    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15147            int opti, boolean dumpAll, String dumpPackage) {
15148        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15149
15150        boolean printedAnything = false;
15151
15152        if (mRecentTasks != null && mRecentTasks.size() > 0) {
15153            boolean printedHeader = false;
15154
15155            final int N = mRecentTasks.size();
15156            for (int i=0; i<N; i++) {
15157                TaskRecord tr = mRecentTasks.get(i);
15158                if (dumpPackage != null) {
15159                    if (tr.realActivity == null ||
15160                            !dumpPackage.equals(tr.realActivity.getPackageName())) {
15161                        continue;
15162                    }
15163                }
15164                if (!printedHeader) {
15165                    pw.println("  Recent tasks:");
15166                    printedHeader = true;
15167                    printedAnything = true;
15168                }
15169                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15170                        pw.println(tr);
15171                if (dumpAll) {
15172                    mRecentTasks.get(i).dump(pw, "    ");
15173                }
15174            }
15175        }
15176
15177        if (!printedAnything) {
15178            pw.println("  (nothing)");
15179        }
15180    }
15181
15182    void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15183            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15184        pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15185
15186        int dumpUid = 0;
15187        if (dumpPackage != null) {
15188            IPackageManager pm = AppGlobals.getPackageManager();
15189            try {
15190                dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15191            } catch (RemoteException e) {
15192            }
15193        }
15194
15195        boolean printedAnything = false;
15196
15197        final long now = SystemClock.uptimeMillis();
15198
15199        for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15200            ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15201                    = mAssociations.valueAt(i1);
15202            for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15203                SparseArray<ArrayMap<String, Association>> sourceUids
15204                        = targetComponents.valueAt(i2);
15205                for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15206                    ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15207                    for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15208                        Association ass = sourceProcesses.valueAt(i4);
15209                        if (dumpPackage != null) {
15210                            if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15211                                    && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15212                                continue;
15213                            }
15214                        }
15215                        printedAnything = true;
15216                        pw.print("  ");
15217                        pw.print(ass.mTargetProcess);
15218                        pw.print("/");
15219                        UserHandle.formatUid(pw, ass.mTargetUid);
15220                        pw.print(" <- ");
15221                        pw.print(ass.mSourceProcess);
15222                        pw.print("/");
15223                        UserHandle.formatUid(pw, ass.mSourceUid);
15224                        pw.println();
15225                        pw.print("    via ");
15226                        pw.print(ass.mTargetComponent.flattenToShortString());
15227                        pw.println();
15228                        pw.print("    ");
15229                        long dur = ass.mTime;
15230                        if (ass.mNesting > 0) {
15231                            dur += now - ass.mStartTime;
15232                        }
15233                        TimeUtils.formatDuration(dur, pw);
15234                        pw.print(" (");
15235                        pw.print(ass.mCount);
15236                        pw.print(" times)");
15237                        pw.print("  ");
15238                        for (int i=0; i<ass.mStateTimes.length; i++) {
15239                            long amt = ass.mStateTimes[i];
15240                            if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15241                                amt += now - ass.mLastStateUptime;
15242                            }
15243                            if (amt != 0) {
15244                                pw.print(" ");
15245                                pw.print(ProcessList.makeProcStateString(
15246                                            i + ActivityManager.MIN_PROCESS_STATE));
15247                                pw.print("=");
15248                                TimeUtils.formatDuration(amt, pw);
15249                                if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15250                                    pw.print("*");
15251                                }
15252                            }
15253                        }
15254                        pw.println();
15255                        if (ass.mNesting > 0) {
15256                            pw.print("    Currently active: ");
15257                            TimeUtils.formatDuration(now - ass.mStartTime, pw);
15258                            pw.println();
15259                        }
15260                    }
15261                }
15262            }
15263
15264        }
15265
15266        if (!printedAnything) {
15267            pw.println("  (nothing)");
15268        }
15269    }
15270
15271    boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15272            String header, boolean needSep) {
15273        boolean printed = false;
15274        int whichAppId = -1;
15275        if (dumpPackage != null) {
15276            try {
15277                ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15278                        dumpPackage, 0);
15279                whichAppId = UserHandle.getAppId(info.uid);
15280            } catch (NameNotFoundException e) {
15281                e.printStackTrace();
15282            }
15283        }
15284        for (int i=0; i<uids.size(); i++) {
15285            UidRecord uidRec = uids.valueAt(i);
15286            if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15287                continue;
15288            }
15289            if (!printed) {
15290                printed = true;
15291                if (needSep) {
15292                    pw.println();
15293                }
15294                pw.print("  ");
15295                pw.println(header);
15296                needSep = true;
15297            }
15298            pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15299            pw.print(": "); pw.println(uidRec);
15300        }
15301        return printed;
15302    }
15303
15304    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15305            int opti, boolean dumpAll, String dumpPackage) {
15306        boolean needSep = false;
15307        boolean printedAnything = false;
15308        int numPers = 0;
15309
15310        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15311
15312        if (dumpAll) {
15313            final int NP = mProcessNames.getMap().size();
15314            for (int ip=0; ip<NP; ip++) {
15315                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15316                final int NA = procs.size();
15317                for (int ia=0; ia<NA; ia++) {
15318                    ProcessRecord r = procs.valueAt(ia);
15319                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15320                        continue;
15321                    }
15322                    if (!needSep) {
15323                        pw.println("  All known processes:");
15324                        needSep = true;
15325                        printedAnything = true;
15326                    }
15327                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15328                        pw.print(" UID "); pw.print(procs.keyAt(ia));
15329                        pw.print(" "); pw.println(r);
15330                    r.dump(pw, "    ");
15331                    if (r.persistent) {
15332                        numPers++;
15333                    }
15334                }
15335            }
15336        }
15337
15338        if (mIsolatedProcesses.size() > 0) {
15339            boolean printed = false;
15340            for (int i=0; i<mIsolatedProcesses.size(); i++) {
15341                ProcessRecord r = mIsolatedProcesses.valueAt(i);
15342                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15343                    continue;
15344                }
15345                if (!printed) {
15346                    if (needSep) {
15347                        pw.println();
15348                    }
15349                    pw.println("  Isolated process list (sorted by uid):");
15350                    printedAnything = true;
15351                    printed = true;
15352                    needSep = true;
15353                }
15354                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15355                pw.println(r);
15356            }
15357        }
15358
15359        if (mActiveInstrumentation.size() > 0) {
15360            boolean printed = false;
15361            for (int i=0; i<mActiveInstrumentation.size(); i++) {
15362                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15363                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15364                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15365                    continue;
15366                }
15367                if (!printed) {
15368                    if (needSep) {
15369                        pw.println();
15370                    }
15371                    pw.println("  Active instrumentation:");
15372                    printedAnything = true;
15373                    printed = true;
15374                    needSep = true;
15375                }
15376                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15377                pw.println(ai);
15378                ai.dump(pw, "      ");
15379            }
15380        }
15381
15382        if (mActiveUids.size() > 0) {
15383            if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15384                printedAnything = needSep = true;
15385            }
15386        }
15387        if (dumpAll) {
15388            if (mValidateUids.size() > 0) {
15389                if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15390                    printedAnything = needSep = true;
15391                }
15392            }
15393        }
15394
15395        if (mLruProcesses.size() > 0) {
15396            if (needSep) {
15397                pw.println();
15398            }
15399            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15400                    pw.print(" total, non-act at ");
15401                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15402                    pw.print(", non-svc at ");
15403                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15404                    pw.println("):");
15405            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15406            needSep = true;
15407            printedAnything = true;
15408        }
15409
15410        if (dumpAll || dumpPackage != null) {
15411            synchronized (mPidsSelfLocked) {
15412                boolean printed = false;
15413                for (int i=0; i<mPidsSelfLocked.size(); i++) {
15414                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
15415                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15416                        continue;
15417                    }
15418                    if (!printed) {
15419                        if (needSep) pw.println();
15420                        needSep = true;
15421                        pw.println("  PID mappings:");
15422                        printed = true;
15423                        printedAnything = true;
15424                    }
15425                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15426                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15427                }
15428            }
15429        }
15430
15431        if (mForegroundProcesses.size() > 0) {
15432            synchronized (mPidsSelfLocked) {
15433                boolean printed = false;
15434                for (int i=0; i<mForegroundProcesses.size(); i++) {
15435                    ProcessRecord r = mPidsSelfLocked.get(
15436                            mForegroundProcesses.valueAt(i).pid);
15437                    if (dumpPackage != null && (r == null
15438                            || !r.pkgList.containsKey(dumpPackage))) {
15439                        continue;
15440                    }
15441                    if (!printed) {
15442                        if (needSep) pw.println();
15443                        needSep = true;
15444                        pw.println("  Foreground Processes:");
15445                        printed = true;
15446                        printedAnything = true;
15447                    }
15448                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
15449                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
15450                }
15451            }
15452        }
15453
15454        if (mPersistentStartingProcesses.size() > 0) {
15455            if (needSep) pw.println();
15456            needSep = true;
15457            printedAnything = true;
15458            pw.println("  Persisent processes that are starting:");
15459            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15460                    "Starting Norm", "Restarting PERS", dumpPackage);
15461        }
15462
15463        if (mRemovedProcesses.size() > 0) {
15464            if (needSep) pw.println();
15465            needSep = true;
15466            printedAnything = true;
15467            pw.println("  Processes that are being removed:");
15468            dumpProcessList(pw, this, mRemovedProcesses, "    ",
15469                    "Removed Norm", "Removed PERS", dumpPackage);
15470        }
15471
15472        if (mProcessesOnHold.size() > 0) {
15473            if (needSep) pw.println();
15474            needSep = true;
15475            printedAnything = true;
15476            pw.println("  Processes that are on old until the system is ready:");
15477            dumpProcessList(pw, this, mProcessesOnHold, "    ",
15478                    "OnHold Norm", "OnHold PERS", dumpPackage);
15479        }
15480
15481        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15482
15483        needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15484        if (needSep) {
15485            printedAnything = true;
15486        }
15487
15488        if (dumpPackage == null) {
15489            pw.println();
15490            needSep = false;
15491            mUserController.dump(pw, dumpAll);
15492        }
15493        if (mHomeProcess != null && (dumpPackage == null
15494                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15495            if (needSep) {
15496                pw.println();
15497                needSep = false;
15498            }
15499            pw.println("  mHomeProcess: " + mHomeProcess);
15500        }
15501        if (mPreviousProcess != null && (dumpPackage == null
15502                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15503            if (needSep) {
15504                pw.println();
15505                needSep = false;
15506            }
15507            pw.println("  mPreviousProcess: " + mPreviousProcess);
15508        }
15509        if (dumpAll) {
15510            StringBuilder sb = new StringBuilder(128);
15511            sb.append("  mPreviousProcessVisibleTime: ");
15512            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15513            pw.println(sb);
15514        }
15515        if (mHeavyWeightProcess != null && (dumpPackage == null
15516                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15517            if (needSep) {
15518                pw.println();
15519                needSep = false;
15520            }
15521            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15522        }
15523        if (dumpPackage == null) {
15524            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15525            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15526        }
15527        if (dumpAll) {
15528            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15529            if (mCompatModePackages.getPackages().size() > 0) {
15530                boolean printed = false;
15531                for (Map.Entry<String, Integer> entry
15532                        : mCompatModePackages.getPackages().entrySet()) {
15533                    String pkg = entry.getKey();
15534                    int mode = entry.getValue();
15535                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15536                        continue;
15537                    }
15538                    if (!printed) {
15539                        pw.println("  mScreenCompatPackages:");
15540                        printed = true;
15541                    }
15542                    pw.print("    "); pw.print(pkg); pw.print(": ");
15543                            pw.print(mode); pw.println();
15544                }
15545            }
15546            final int NI = mUidObservers.getRegisteredCallbackCount();
15547            boolean printed = false;
15548            for (int i=0; i<NI; i++) {
15549                final UidObserverRegistration reg = (UidObserverRegistration)
15550                        mUidObservers.getRegisteredCallbackCookie(i);
15551                if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15552                    if (!printed) {
15553                        pw.println("  mUidObservers:");
15554                        printed = true;
15555                    }
15556                    pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15557                    pw.print(" "); pw.print(reg.pkg); pw.print(":");
15558                    if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15559                        pw.print(" IDLE");
15560                    }
15561                    if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15562                        pw.print(" ACT" );
15563                    }
15564                    if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15565                        pw.print(" GONE");
15566                    }
15567                    if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15568                        pw.print(" STATE");
15569                        pw.print(" (cut="); pw.print(reg.cutpoint);
15570                        pw.print(")");
15571                    }
15572                    pw.println();
15573                    if (reg.lastProcStates != null) {
15574                        final int NJ = reg.lastProcStates.size();
15575                        for (int j=0; j<NJ; j++) {
15576                            pw.print("      Last ");
15577                            UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15578                            pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15579                        }
15580                    }
15581                }
15582            }
15583            pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15584            pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15585        }
15586        if (dumpPackage == null) {
15587            pw.println("  mWakefulness="
15588                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
15589            pw.println("  mSleepTokens=" + mSleepTokens);
15590            pw.println("  mSleeping=" + mSleeping);
15591            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15592            if (mRunningVoice != null) {
15593                pw.println("  mRunningVoice=" + mRunningVoice);
15594                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15595            }
15596        }
15597        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15598                || mOrigWaitForDebugger) {
15599            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15600                    || dumpPackage.equals(mOrigDebugApp)) {
15601                if (needSep) {
15602                    pw.println();
15603                    needSep = false;
15604                }
15605                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15606                        + " mDebugTransient=" + mDebugTransient
15607                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15608            }
15609        }
15610        if (mCurAppTimeTracker != null) {
15611            mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15612        }
15613        if (mMemWatchProcesses.getMap().size() > 0) {
15614            pw.println("  Mem watch processes:");
15615            final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15616                    = mMemWatchProcesses.getMap();
15617            for (int i=0; i<procs.size(); i++) {
15618                final String proc = procs.keyAt(i);
15619                final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15620                for (int j=0; j<uids.size(); j++) {
15621                    if (needSep) {
15622                        pw.println();
15623                        needSep = false;
15624                    }
15625                    StringBuilder sb = new StringBuilder();
15626                    sb.append("    ").append(proc).append('/');
15627                    UserHandle.formatUid(sb, uids.keyAt(j));
15628                    Pair<Long, String> val = uids.valueAt(j);
15629                    sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15630                    if (val.second != null) {
15631                        sb.append(", report to ").append(val.second);
15632                    }
15633                    pw.println(sb.toString());
15634                }
15635            }
15636            pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15637            pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15638            pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15639                    pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15640        }
15641        if (mTrackAllocationApp != null) {
15642            if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15643                if (needSep) {
15644                    pw.println();
15645                    needSep = false;
15646                }
15647                pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15648            }
15649        }
15650        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
15651                || mProfileFd != null) {
15652            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15653                if (needSep) {
15654                    pw.println();
15655                    needSep = false;
15656                }
15657                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15658                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
15659                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
15660                        + mAutoStopProfiler + " mStreamingOutput=" + mStreamingOutput);
15661                pw.println("  mProfileType=" + mProfileType);
15662            }
15663        }
15664        if (mNativeDebuggingApp != null) {
15665            if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
15666                if (needSep) {
15667                    pw.println();
15668                    needSep = false;
15669                }
15670                pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
15671            }
15672        }
15673        if (dumpPackage == null) {
15674            if (mAlwaysFinishActivities) {
15675                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
15676            }
15677            if (mController != null) {
15678                pw.println("  mController=" + mController
15679                        + " mControllerIsAMonkey=" + mControllerIsAMonkey);
15680            }
15681            if (dumpAll) {
15682                pw.println("  Total persistent processes: " + numPers);
15683                pw.println("  mProcessesReady=" + mProcessesReady
15684                        + " mSystemReady=" + mSystemReady
15685                        + " mBooted=" + mBooted
15686                        + " mFactoryTest=" + mFactoryTest);
15687                pw.println("  mBooting=" + mBooting
15688                        + " mCallFinishBooting=" + mCallFinishBooting
15689                        + " mBootAnimationComplete=" + mBootAnimationComplete);
15690                pw.print("  mLastPowerCheckRealtime=");
15691                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15692                        pw.println("");
15693                pw.print("  mLastPowerCheckUptime=");
15694                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15695                        pw.println("");
15696                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15697                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15698                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15699                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
15700                        + " (" + mLruProcesses.size() + " total)"
15701                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15702                        + " mNumServiceProcs=" + mNumServiceProcs
15703                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15704                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
15705                        + " mLastMemoryLevel=" + mLastMemoryLevel
15706                        + " mLastNumProcesses=" + mLastNumProcesses);
15707                long now = SystemClock.uptimeMillis();
15708                pw.print("  mLastIdleTime=");
15709                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
15710                        pw.print(" mLowRamSinceLastIdle=");
15711                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15712                        pw.println();
15713            }
15714        }
15715
15716        if (!printedAnything) {
15717            pw.println("  (nothing)");
15718        }
15719    }
15720
15721    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15722            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15723        if (mProcessesToGc.size() > 0) {
15724            boolean printed = false;
15725            long now = SystemClock.uptimeMillis();
15726            for (int i=0; i<mProcessesToGc.size(); i++) {
15727                ProcessRecord proc = mProcessesToGc.get(i);
15728                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15729                    continue;
15730                }
15731                if (!printed) {
15732                    if (needSep) pw.println();
15733                    needSep = true;
15734                    pw.println("  Processes that are waiting to GC:");
15735                    printed = true;
15736                }
15737                pw.print("    Process "); pw.println(proc);
15738                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15739                        pw.print(", last gced=");
15740                        pw.print(now-proc.lastRequestedGc);
15741                        pw.print(" ms ago, last lowMem=");
15742                        pw.print(now-proc.lastLowMemory);
15743                        pw.println(" ms ago");
15744
15745            }
15746        }
15747        return needSep;
15748    }
15749
15750    void printOomLevel(PrintWriter pw, String name, int adj) {
15751        pw.print("    ");
15752        if (adj >= 0) {
15753            pw.print(' ');
15754            if (adj < 10) pw.print(' ');
15755        } else {
15756            if (adj > -10) pw.print(' ');
15757        }
15758        pw.print(adj);
15759        pw.print(": ");
15760        pw.print(name);
15761        pw.print(" (");
15762        pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15763        pw.println(")");
15764    }
15765
15766    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15767            int opti, boolean dumpAll) {
15768        boolean needSep = false;
15769
15770        if (mLruProcesses.size() > 0) {
15771            if (needSep) pw.println();
15772            needSep = true;
15773            pw.println("  OOM levels:");
15774            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15775            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15776            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15777            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15778            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15779            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15780            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15781            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15782            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15783            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15784            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15785            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15786            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15787            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15788
15789            if (needSep) pw.println();
15790            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15791                    pw.print(" total, non-act at ");
15792                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15793                    pw.print(", non-svc at ");
15794                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15795                    pw.println("):");
15796            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15797            needSep = true;
15798        }
15799
15800        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15801
15802        pw.println();
15803        pw.println("  mHomeProcess: " + mHomeProcess);
15804        pw.println("  mPreviousProcess: " + mPreviousProcess);
15805        if (mHeavyWeightProcess != null) {
15806            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15807        }
15808
15809        return true;
15810    }
15811
15812    /**
15813     * There are three ways to call this:
15814     *  - no provider specified: dump all the providers
15815     *  - a flattened component name that matched an existing provider was specified as the
15816     *    first arg: dump that one provider
15817     *  - the first arg isn't the flattened component name of an existing provider:
15818     *    dump all providers whose component contains the first arg as a substring
15819     */
15820    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15821            int opti, boolean dumpAll) {
15822        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15823    }
15824
15825    static class ItemMatcher {
15826        ArrayList<ComponentName> components;
15827        ArrayList<String> strings;
15828        ArrayList<Integer> objects;
15829        boolean all;
15830
15831        ItemMatcher() {
15832            all = true;
15833        }
15834
15835        void build(String name) {
15836            ComponentName componentName = ComponentName.unflattenFromString(name);
15837            if (componentName != null) {
15838                if (components == null) {
15839                    components = new ArrayList<ComponentName>();
15840                }
15841                components.add(componentName);
15842                all = false;
15843            } else {
15844                int objectId = 0;
15845                // Not a '/' separated full component name; maybe an object ID?
15846                try {
15847                    objectId = Integer.parseInt(name, 16);
15848                    if (objects == null) {
15849                        objects = new ArrayList<Integer>();
15850                    }
15851                    objects.add(objectId);
15852                    all = false;
15853                } catch (RuntimeException e) {
15854                    // Not an integer; just do string match.
15855                    if (strings == null) {
15856                        strings = new ArrayList<String>();
15857                    }
15858                    strings.add(name);
15859                    all = false;
15860                }
15861            }
15862        }
15863
15864        int build(String[] args, int opti) {
15865            for (; opti<args.length; opti++) {
15866                String name = args[opti];
15867                if ("--".equals(name)) {
15868                    return opti+1;
15869                }
15870                build(name);
15871            }
15872            return opti;
15873        }
15874
15875        boolean match(Object object, ComponentName comp) {
15876            if (all) {
15877                return true;
15878            }
15879            if (components != null) {
15880                for (int i=0; i<components.size(); i++) {
15881                    if (components.get(i).equals(comp)) {
15882                        return true;
15883                    }
15884                }
15885            }
15886            if (objects != null) {
15887                for (int i=0; i<objects.size(); i++) {
15888                    if (System.identityHashCode(object) == objects.get(i)) {
15889                        return true;
15890                    }
15891                }
15892            }
15893            if (strings != null) {
15894                String flat = comp.flattenToString();
15895                for (int i=0; i<strings.size(); i++) {
15896                    if (flat.contains(strings.get(i))) {
15897                        return true;
15898                    }
15899                }
15900            }
15901            return false;
15902        }
15903    }
15904
15905    /**
15906     * There are three things that cmd can be:
15907     *  - a flattened component name that matches an existing activity
15908     *  - the cmd arg isn't the flattened component name of an existing activity:
15909     *    dump all activity whose component contains the cmd as a substring
15910     *  - A hex number of the ActivityRecord object instance.
15911     *
15912     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
15913     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
15914     */
15915    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15916            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
15917        ArrayList<ActivityRecord> activities;
15918
15919        synchronized (this) {
15920            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
15921                    dumpFocusedStackOnly);
15922        }
15923
15924        if (activities.size() <= 0) {
15925            return false;
15926        }
15927
15928        String[] newArgs = new String[args.length - opti];
15929        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15930
15931        TaskRecord lastTask = null;
15932        boolean needSep = false;
15933        for (int i=activities.size()-1; i>=0; i--) {
15934            ActivityRecord r = activities.get(i);
15935            if (needSep) {
15936                pw.println();
15937            }
15938            needSep = true;
15939            synchronized (this) {
15940                if (lastTask != r.task) {
15941                    lastTask = r.task;
15942                    pw.print("TASK "); pw.print(lastTask.affinity);
15943                            pw.print(" id="); pw.print(lastTask.taskId);
15944                            pw.print(" userId="); pw.println(lastTask.userId);
15945                    if (dumpAll) {
15946                        lastTask.dump(pw, "  ");
15947                    }
15948                }
15949            }
15950            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15951        }
15952        return true;
15953    }
15954
15955    /**
15956     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15957     * there is a thread associated with the activity.
15958     */
15959    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15960            final ActivityRecord r, String[] args, boolean dumpAll) {
15961        String innerPrefix = prefix + "  ";
15962        synchronized (this) {
15963            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15964                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15965                    pw.print(" pid=");
15966                    if (r.app != null) pw.println(r.app.pid);
15967                    else pw.println("(not running)");
15968            if (dumpAll) {
15969                r.dump(pw, innerPrefix);
15970            }
15971        }
15972        if (r.app != null && r.app.thread != null) {
15973            // flush anything that is already in the PrintWriter since the thread is going
15974            // to write to the file descriptor directly
15975            pw.flush();
15976            try {
15977                TransferPipe tp = new TransferPipe();
15978                try {
15979                    r.app.thread.dumpActivity(tp.getWriteFd(),
15980                            r.appToken, innerPrefix, args);
15981                    tp.go(fd);
15982                } finally {
15983                    tp.kill();
15984                }
15985            } catch (IOException e) {
15986                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15987            } catch (RemoteException e) {
15988                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15989            }
15990        }
15991    }
15992
15993    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15994            int opti, boolean dumpAll, String dumpPackage) {
15995        boolean needSep = false;
15996        boolean onlyHistory = false;
15997        boolean printedAnything = false;
15998
15999        if ("history".equals(dumpPackage)) {
16000            if (opti < args.length && "-s".equals(args[opti])) {
16001                dumpAll = false;
16002            }
16003            onlyHistory = true;
16004            dumpPackage = null;
16005        }
16006
16007        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16008        if (!onlyHistory && dumpAll) {
16009            if (mRegisteredReceivers.size() > 0) {
16010                boolean printed = false;
16011                Iterator it = mRegisteredReceivers.values().iterator();
16012                while (it.hasNext()) {
16013                    ReceiverList r = (ReceiverList)it.next();
16014                    if (dumpPackage != null && (r.app == null ||
16015                            !dumpPackage.equals(r.app.info.packageName))) {
16016                        continue;
16017                    }
16018                    if (!printed) {
16019                        pw.println("  Registered Receivers:");
16020                        needSep = true;
16021                        printed = true;
16022                        printedAnything = true;
16023                    }
16024                    pw.print("  * "); pw.println(r);
16025                    r.dump(pw, "    ");
16026                }
16027            }
16028
16029            if (mReceiverResolver.dump(pw, needSep ?
16030                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16031                    "    ", dumpPackage, false, false)) {
16032                needSep = true;
16033                printedAnything = true;
16034            }
16035        }
16036
16037        for (BroadcastQueue q : mBroadcastQueues) {
16038            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16039            printedAnything |= needSep;
16040        }
16041
16042        needSep = true;
16043
16044        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16045            for (int user=0; user<mStickyBroadcasts.size(); user++) {
16046                if (needSep) {
16047                    pw.println();
16048                }
16049                needSep = true;
16050                printedAnything = true;
16051                pw.print("  Sticky broadcasts for user ");
16052                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16053                StringBuilder sb = new StringBuilder(128);
16054                for (Map.Entry<String, ArrayList<Intent>> ent
16055                        : mStickyBroadcasts.valueAt(user).entrySet()) {
16056                    pw.print("  * Sticky action "); pw.print(ent.getKey());
16057                    if (dumpAll) {
16058                        pw.println(":");
16059                        ArrayList<Intent> intents = ent.getValue();
16060                        final int N = intents.size();
16061                        for (int i=0; i<N; i++) {
16062                            sb.setLength(0);
16063                            sb.append("    Intent: ");
16064                            intents.get(i).toShortString(sb, false, true, false, false);
16065                            pw.println(sb.toString());
16066                            Bundle bundle = intents.get(i).getExtras();
16067                            if (bundle != null) {
16068                                pw.print("      ");
16069                                pw.println(bundle.toString());
16070                            }
16071                        }
16072                    } else {
16073                        pw.println("");
16074                    }
16075                }
16076            }
16077        }
16078
16079        if (!onlyHistory && dumpAll) {
16080            pw.println();
16081            for (BroadcastQueue queue : mBroadcastQueues) {
16082                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16083                        + queue.mBroadcastsScheduled);
16084            }
16085            pw.println("  mHandler:");
16086            mHandler.dump(new PrintWriterPrinter(pw), "    ");
16087            needSep = true;
16088            printedAnything = true;
16089        }
16090
16091        if (!printedAnything) {
16092            pw.println("  (nothing)");
16093        }
16094    }
16095
16096    void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16097            int opti, boolean dumpAll, String dumpPackage) {
16098        if (mCurBroadcastStats == null) {
16099            return;
16100        }
16101
16102        pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16103        final long now = SystemClock.elapsedRealtime();
16104        if (mLastBroadcastStats != null) {
16105            pw.print("  Last stats (from ");
16106            TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16107            pw.print(" to ");
16108            TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16109            pw.print(", ");
16110            TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16111                    - mLastBroadcastStats.mStartUptime, pw);
16112            pw.println(" uptime):");
16113            if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16114                pw.println("    (nothing)");
16115            }
16116            pw.println();
16117        }
16118        pw.print("  Current stats (from ");
16119        TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16120        pw.print(" to now, ");
16121        TimeUtils.formatDuration(SystemClock.uptimeMillis()
16122                - mCurBroadcastStats.mStartUptime, pw);
16123        pw.println(" uptime):");
16124        if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16125            pw.println("    (nothing)");
16126        }
16127    }
16128
16129    void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16130            int opti, boolean fullCheckin, String dumpPackage) {
16131        if (mCurBroadcastStats == null) {
16132            return;
16133        }
16134
16135        if (mLastBroadcastStats != null) {
16136            mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16137            if (fullCheckin) {
16138                mLastBroadcastStats = null;
16139                return;
16140            }
16141        }
16142        mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16143        if (fullCheckin) {
16144            mCurBroadcastStats = null;
16145        }
16146    }
16147
16148    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16149            int opti, boolean dumpAll, String dumpPackage) {
16150        boolean needSep;
16151        boolean printedAnything = false;
16152
16153        ItemMatcher matcher = new ItemMatcher();
16154        matcher.build(args, opti);
16155
16156        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16157
16158        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16159        printedAnything |= needSep;
16160
16161        if (mLaunchingProviders.size() > 0) {
16162            boolean printed = false;
16163            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16164                ContentProviderRecord r = mLaunchingProviders.get(i);
16165                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16166                    continue;
16167                }
16168                if (!printed) {
16169                    if (needSep) pw.println();
16170                    needSep = true;
16171                    pw.println("  Launching content providers:");
16172                    printed = true;
16173                    printedAnything = true;
16174                }
16175                pw.print("  Launching #"); pw.print(i); pw.print(": ");
16176                        pw.println(r);
16177            }
16178        }
16179
16180        if (!printedAnything) {
16181            pw.println("  (nothing)");
16182        }
16183    }
16184
16185    void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16186            int opti, boolean dumpAll, String dumpPackage) {
16187        boolean needSep = false;
16188        boolean printedAnything = false;
16189
16190        pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16191
16192        if (mGrantedUriPermissions.size() > 0) {
16193            boolean printed = false;
16194            int dumpUid = -2;
16195            if (dumpPackage != null) {
16196                try {
16197                    dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16198                            MATCH_ANY_USER, 0);
16199                } catch (NameNotFoundException e) {
16200                    dumpUid = -1;
16201                }
16202            }
16203            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16204                int uid = mGrantedUriPermissions.keyAt(i);
16205                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16206                    continue;
16207                }
16208                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16209                if (!printed) {
16210                    if (needSep) pw.println();
16211                    needSep = true;
16212                    pw.println("  Granted Uri Permissions:");
16213                    printed = true;
16214                    printedAnything = true;
16215                }
16216                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16217                for (UriPermission perm : perms.values()) {
16218                    pw.print("    "); pw.println(perm);
16219                    if (dumpAll) {
16220                        perm.dump(pw, "      ");
16221                    }
16222                }
16223            }
16224        }
16225
16226        if (!printedAnything) {
16227            pw.println("  (nothing)");
16228        }
16229    }
16230
16231    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16232            int opti, boolean dumpAll, String dumpPackage) {
16233        boolean printed = false;
16234
16235        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16236
16237        if (mIntentSenderRecords.size() > 0) {
16238            Iterator<WeakReference<PendingIntentRecord>> it
16239                    = mIntentSenderRecords.values().iterator();
16240            while (it.hasNext()) {
16241                WeakReference<PendingIntentRecord> ref = it.next();
16242                PendingIntentRecord rec = ref != null ? ref.get(): null;
16243                if (dumpPackage != null && (rec == null
16244                        || !dumpPackage.equals(rec.key.packageName))) {
16245                    continue;
16246                }
16247                printed = true;
16248                if (rec != null) {
16249                    pw.print("  * "); pw.println(rec);
16250                    if (dumpAll) {
16251                        rec.dump(pw, "    ");
16252                    }
16253                } else {
16254                    pw.print("  * "); pw.println(ref);
16255                }
16256            }
16257        }
16258
16259        if (!printed) {
16260            pw.println("  (nothing)");
16261        }
16262    }
16263
16264    private static final int dumpProcessList(PrintWriter pw,
16265            ActivityManagerService service, List list,
16266            String prefix, String normalLabel, String persistentLabel,
16267            String dumpPackage) {
16268        int numPers = 0;
16269        final int N = list.size()-1;
16270        for (int i=N; i>=0; i--) {
16271            ProcessRecord r = (ProcessRecord)list.get(i);
16272            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16273                continue;
16274            }
16275            pw.println(String.format("%s%s #%2d: %s",
16276                    prefix, (r.persistent ? persistentLabel : normalLabel),
16277                    i, r.toString()));
16278            if (r.persistent) {
16279                numPers++;
16280            }
16281        }
16282        return numPers;
16283    }
16284
16285    private static final boolean dumpProcessOomList(PrintWriter pw,
16286            ActivityManagerService service, List<ProcessRecord> origList,
16287            String prefix, String normalLabel, String persistentLabel,
16288            boolean inclDetails, String dumpPackage) {
16289
16290        ArrayList<Pair<ProcessRecord, Integer>> list
16291                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16292        for (int i=0; i<origList.size(); i++) {
16293            ProcessRecord r = origList.get(i);
16294            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16295                continue;
16296            }
16297            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16298        }
16299
16300        if (list.size() <= 0) {
16301            return false;
16302        }
16303
16304        Comparator<Pair<ProcessRecord, Integer>> comparator
16305                = new Comparator<Pair<ProcessRecord, Integer>>() {
16306            @Override
16307            public int compare(Pair<ProcessRecord, Integer> object1,
16308                    Pair<ProcessRecord, Integer> object2) {
16309                if (object1.first.setAdj != object2.first.setAdj) {
16310                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16311                }
16312                if (object1.first.setProcState != object2.first.setProcState) {
16313                    return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16314                }
16315                if (object1.second.intValue() != object2.second.intValue()) {
16316                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16317                }
16318                return 0;
16319            }
16320        };
16321
16322        Collections.sort(list, comparator);
16323
16324        final long curRealtime = SystemClock.elapsedRealtime();
16325        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
16326        final long curUptime = SystemClock.uptimeMillis();
16327        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16328
16329        for (int i=list.size()-1; i>=0; i--) {
16330            ProcessRecord r = list.get(i).first;
16331            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16332            char schedGroup;
16333            switch (r.setSchedGroup) {
16334                case ProcessList.SCHED_GROUP_BACKGROUND:
16335                    schedGroup = 'B';
16336                    break;
16337                case ProcessList.SCHED_GROUP_DEFAULT:
16338                    schedGroup = 'F';
16339                    break;
16340                case ProcessList.SCHED_GROUP_TOP_APP:
16341                    schedGroup = 'T';
16342                    break;
16343                default:
16344                    schedGroup = '?';
16345                    break;
16346            }
16347            char foreground;
16348            if (r.foregroundActivities) {
16349                foreground = 'A';
16350            } else if (r.foregroundServices) {
16351                foreground = 'S';
16352            } else {
16353                foreground = ' ';
16354            }
16355            String procState = ProcessList.makeProcStateString(r.curProcState);
16356            pw.print(prefix);
16357            pw.print(r.persistent ? persistentLabel : normalLabel);
16358            pw.print(" #");
16359            int num = (origList.size()-1)-list.get(i).second;
16360            if (num < 10) pw.print(' ');
16361            pw.print(num);
16362            pw.print(": ");
16363            pw.print(oomAdj);
16364            pw.print(' ');
16365            pw.print(schedGroup);
16366            pw.print('/');
16367            pw.print(foreground);
16368            pw.print('/');
16369            pw.print(procState);
16370            pw.print(" trm:");
16371            if (r.trimMemoryLevel < 10) pw.print(' ');
16372            pw.print(r.trimMemoryLevel);
16373            pw.print(' ');
16374            pw.print(r.toShortString());
16375            pw.print(" (");
16376            pw.print(r.adjType);
16377            pw.println(')');
16378            if (r.adjSource != null || r.adjTarget != null) {
16379                pw.print(prefix);
16380                pw.print("    ");
16381                if (r.adjTarget instanceof ComponentName) {
16382                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16383                } else if (r.adjTarget != null) {
16384                    pw.print(r.adjTarget.toString());
16385                } else {
16386                    pw.print("{null}");
16387                }
16388                pw.print("<=");
16389                if (r.adjSource instanceof ProcessRecord) {
16390                    pw.print("Proc{");
16391                    pw.print(((ProcessRecord)r.adjSource).toShortString());
16392                    pw.println("}");
16393                } else if (r.adjSource != null) {
16394                    pw.println(r.adjSource.toString());
16395                } else {
16396                    pw.println("{null}");
16397                }
16398            }
16399            if (inclDetails) {
16400                pw.print(prefix);
16401                pw.print("    ");
16402                pw.print("oom: max="); pw.print(r.maxAdj);
16403                pw.print(" curRaw="); pw.print(r.curRawAdj);
16404                pw.print(" setRaw="); pw.print(r.setRawAdj);
16405                pw.print(" cur="); pw.print(r.curAdj);
16406                pw.print(" set="); pw.println(r.setAdj);
16407                pw.print(prefix);
16408                pw.print("    ");
16409                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16410                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16411                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16412                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16413                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16414                pw.println();
16415                pw.print(prefix);
16416                pw.print("    ");
16417                pw.print("cached="); pw.print(r.cached);
16418                pw.print(" empty="); pw.print(r.empty);
16419                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16420
16421                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16422                    if (r.lastWakeTime != 0) {
16423                        long wtime;
16424                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
16425                        synchronized (stats) {
16426                            wtime = stats.getProcessWakeTime(r.info.uid,
16427                                    r.pid, curRealtime);
16428                        }
16429                        long timeUsed = wtime - r.lastWakeTime;
16430                        pw.print(prefix);
16431                        pw.print("    ");
16432                        pw.print("keep awake over ");
16433                        TimeUtils.formatDuration(realtimeSince, pw);
16434                        pw.print(" used ");
16435                        TimeUtils.formatDuration(timeUsed, pw);
16436                        pw.print(" (");
16437                        pw.print((timeUsed*100)/realtimeSince);
16438                        pw.println("%)");
16439                    }
16440                    if (r.lastCpuTime != 0) {
16441                        long timeUsed = r.curCpuTime - r.lastCpuTime;
16442                        pw.print(prefix);
16443                        pw.print("    ");
16444                        pw.print("run cpu over ");
16445                        TimeUtils.formatDuration(uptimeSince, pw);
16446                        pw.print(" used ");
16447                        TimeUtils.formatDuration(timeUsed, pw);
16448                        pw.print(" (");
16449                        pw.print((timeUsed*100)/uptimeSince);
16450                        pw.println("%)");
16451                    }
16452                }
16453            }
16454        }
16455        return true;
16456    }
16457
16458    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16459            String[] args) {
16460        ArrayList<ProcessRecord> procs;
16461        synchronized (this) {
16462            if (args != null && args.length > start
16463                    && args[start].charAt(0) != '-') {
16464                procs = new ArrayList<ProcessRecord>();
16465                int pid = -1;
16466                try {
16467                    pid = Integer.parseInt(args[start]);
16468                } catch (NumberFormatException e) {
16469                }
16470                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16471                    ProcessRecord proc = mLruProcesses.get(i);
16472                    if (proc.pid == pid) {
16473                        procs.add(proc);
16474                    } else if (allPkgs && proc.pkgList != null
16475                            && proc.pkgList.containsKey(args[start])) {
16476                        procs.add(proc);
16477                    } else if (proc.processName.equals(args[start])) {
16478                        procs.add(proc);
16479                    }
16480                }
16481                if (procs.size() <= 0) {
16482                    return null;
16483                }
16484            } else {
16485                procs = new ArrayList<ProcessRecord>(mLruProcesses);
16486            }
16487        }
16488        return procs;
16489    }
16490
16491    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16492            PrintWriter pw, String[] args) {
16493        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16494        if (procs == null) {
16495            pw.println("No process found for: " + args[0]);
16496            return;
16497        }
16498
16499        long uptime = SystemClock.uptimeMillis();
16500        long realtime = SystemClock.elapsedRealtime();
16501        pw.println("Applications Graphics Acceleration Info:");
16502        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16503
16504        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16505            ProcessRecord r = procs.get(i);
16506            if (r.thread != null) {
16507                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16508                pw.flush();
16509                try {
16510                    TransferPipe tp = new TransferPipe();
16511                    try {
16512                        r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16513                        tp.go(fd);
16514                    } finally {
16515                        tp.kill();
16516                    }
16517                } catch (IOException e) {
16518                    pw.println("Failure while dumping the app: " + r);
16519                    pw.flush();
16520                } catch (RemoteException e) {
16521                    pw.println("Got a RemoteException while dumping the app " + r);
16522                    pw.flush();
16523                }
16524            }
16525        }
16526    }
16527
16528    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16529        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16530        if (procs == null) {
16531            pw.println("No process found for: " + args[0]);
16532            return;
16533        }
16534
16535        pw.println("Applications Database Info:");
16536
16537        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16538            ProcessRecord r = procs.get(i);
16539            if (r.thread != null) {
16540                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16541                pw.flush();
16542                try {
16543                    TransferPipe tp = new TransferPipe();
16544                    try {
16545                        r.thread.dumpDbInfo(tp.getWriteFd(), args);
16546                        tp.go(fd);
16547                    } finally {
16548                        tp.kill();
16549                    }
16550                } catch (IOException e) {
16551                    pw.println("Failure while dumping the app: " + r);
16552                    pw.flush();
16553                } catch (RemoteException e) {
16554                    pw.println("Got a RemoteException while dumping the app " + r);
16555                    pw.flush();
16556                }
16557            }
16558        }
16559    }
16560
16561    final static class MemItem {
16562        final boolean isProc;
16563        final String label;
16564        final String shortLabel;
16565        final long pss;
16566        final long swapPss;
16567        final int id;
16568        final boolean hasActivities;
16569        ArrayList<MemItem> subitems;
16570
16571        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16572                boolean _hasActivities) {
16573            isProc = true;
16574            label = _label;
16575            shortLabel = _shortLabel;
16576            pss = _pss;
16577            swapPss = _swapPss;
16578            id = _id;
16579            hasActivities = _hasActivities;
16580        }
16581
16582        public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16583            isProc = false;
16584            label = _label;
16585            shortLabel = _shortLabel;
16586            pss = _pss;
16587            swapPss = _swapPss;
16588            id = _id;
16589            hasActivities = false;
16590        }
16591    }
16592
16593    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16594            ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16595        if (sort && !isCompact) {
16596            Collections.sort(items, new Comparator<MemItem>() {
16597                @Override
16598                public int compare(MemItem lhs, MemItem rhs) {
16599                    if (lhs.pss < rhs.pss) {
16600                        return 1;
16601                    } else if (lhs.pss > rhs.pss) {
16602                        return -1;
16603                    }
16604                    return 0;
16605                }
16606            });
16607        }
16608
16609        for (int i=0; i<items.size(); i++) {
16610            MemItem mi = items.get(i);
16611            if (!isCompact) {
16612                if (dumpSwapPss) {
16613                    pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16614                            mi.label, stringifyKBSize(mi.swapPss));
16615                } else {
16616                    pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16617                }
16618            } else if (mi.isProc) {
16619                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16620                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16621                pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16622                pw.println(mi.hasActivities ? ",a" : ",e");
16623            } else {
16624                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16625                pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16626            }
16627            if (mi.subitems != null) {
16628                dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16629                        true, isCompact, dumpSwapPss);
16630            }
16631        }
16632    }
16633
16634    // These are in KB.
16635    static final long[] DUMP_MEM_BUCKETS = new long[] {
16636        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16637        120*1024, 160*1024, 200*1024,
16638        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16639        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16640    };
16641
16642    static final void appendMemBucket(StringBuilder out, long memKB, String label,
16643            boolean stackLike) {
16644        int start = label.lastIndexOf('.');
16645        if (start >= 0) start++;
16646        else start = 0;
16647        int end = label.length();
16648        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16649            if (DUMP_MEM_BUCKETS[i] >= memKB) {
16650                long bucket = DUMP_MEM_BUCKETS[i]/1024;
16651                out.append(bucket);
16652                out.append(stackLike ? "MB." : "MB ");
16653                out.append(label, start, end);
16654                return;
16655            }
16656        }
16657        out.append(memKB/1024);
16658        out.append(stackLike ? "MB." : "MB ");
16659        out.append(label, start, end);
16660    }
16661
16662    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
16663            ProcessList.NATIVE_ADJ,
16664            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
16665            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
16666            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
16667            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
16668            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
16669            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
16670    };
16671    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
16672            "Native",
16673            "System", "Persistent", "Persistent Service", "Foreground",
16674            "Visible", "Perceptible",
16675            "Heavy Weight", "Backup",
16676            "A Services", "Home",
16677            "Previous", "B Services", "Cached"
16678    };
16679    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
16680            "native",
16681            "sys", "pers", "persvc", "fore",
16682            "vis", "percept",
16683            "heavy", "backup",
16684            "servicea", "home",
16685            "prev", "serviceb", "cached"
16686    };
16687
16688    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
16689            long realtime, boolean isCheckinRequest, boolean isCompact) {
16690        if (isCompact) {
16691            pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
16692        }
16693        if (isCheckinRequest || isCompact) {
16694            // short checkin version
16695            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16696        } else {
16697            pw.println("Applications Memory Usage (in Kilobytes):");
16698            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16699        }
16700    }
16701
16702    private static final int KSM_SHARED = 0;
16703    private static final int KSM_SHARING = 1;
16704    private static final int KSM_UNSHARED = 2;
16705    private static final int KSM_VOLATILE = 3;
16706
16707    private final long[] getKsmInfo() {
16708        long[] longOut = new long[4];
16709        final int[] SINGLE_LONG_FORMAT = new int[] {
16710            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16711        };
16712        long[] longTmp = new long[1];
16713        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16714                SINGLE_LONG_FORMAT, null, longTmp, null);
16715        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16716        longTmp[0] = 0;
16717        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16718                SINGLE_LONG_FORMAT, null, longTmp, null);
16719        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16720        longTmp[0] = 0;
16721        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16722                SINGLE_LONG_FORMAT, null, longTmp, null);
16723        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16724        longTmp[0] = 0;
16725        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16726                SINGLE_LONG_FORMAT, null, longTmp, null);
16727        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16728        return longOut;
16729    }
16730
16731    private static String stringifySize(long size, int order) {
16732        Locale locale = Locale.US;
16733        switch (order) {
16734            case 1:
16735                return String.format(locale, "%,13d", size);
16736            case 1024:
16737                return String.format(locale, "%,9dK", size / 1024);
16738            case 1024 * 1024:
16739                return String.format(locale, "%,5dM", size / 1024 / 1024);
16740            case 1024 * 1024 * 1024:
16741                return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16742            default:
16743                throw new IllegalArgumentException("Invalid size order");
16744        }
16745    }
16746
16747    private static String stringifyKBSize(long size) {
16748        return stringifySize(size * 1024, 1024);
16749    }
16750
16751    // Update this version number in case you change the 'compact' format
16752    private static final int MEMINFO_COMPACT_VERSION = 1;
16753
16754    final void dumpApplicationMemoryUsage(FileDescriptor fd,
16755            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16756        boolean dumpDetails = false;
16757        boolean dumpFullDetails = false;
16758        boolean dumpDalvik = false;
16759        boolean dumpSummaryOnly = false;
16760        boolean dumpUnreachable = false;
16761        boolean oomOnly = false;
16762        boolean isCompact = false;
16763        boolean localOnly = false;
16764        boolean packages = false;
16765        boolean isCheckinRequest = false;
16766        boolean dumpSwapPss = false;
16767
16768        int opti = 0;
16769        while (opti < args.length) {
16770            String opt = args[opti];
16771            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16772                break;
16773            }
16774            opti++;
16775            if ("-a".equals(opt)) {
16776                dumpDetails = true;
16777                dumpFullDetails = true;
16778                dumpDalvik = true;
16779                dumpSwapPss = true;
16780            } else if ("-d".equals(opt)) {
16781                dumpDalvik = true;
16782            } else if ("-c".equals(opt)) {
16783                isCompact = true;
16784            } else if ("-s".equals(opt)) {
16785                dumpDetails = true;
16786                dumpSummaryOnly = true;
16787            } else if ("-S".equals(opt)) {
16788                dumpSwapPss = true;
16789            } else if ("--unreachable".equals(opt)) {
16790                dumpUnreachable = true;
16791            } else if ("--oom".equals(opt)) {
16792                oomOnly = true;
16793            } else if ("--local".equals(opt)) {
16794                localOnly = true;
16795            } else if ("--package".equals(opt)) {
16796                packages = true;
16797            } else if ("--checkin".equals(opt)) {
16798                isCheckinRequest = true;
16799
16800            } else if ("-h".equals(opt)) {
16801                pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16802                pw.println("  -a: include all available information for each process.");
16803                pw.println("  -d: include dalvik details.");
16804                pw.println("  -c: dump in a compact machine-parseable representation.");
16805                pw.println("  -s: dump only summary of application memory usage.");
16806                pw.println("  -S: dump also SwapPss.");
16807                pw.println("  --oom: only show processes organized by oom adj.");
16808                pw.println("  --local: only collect details locally, don't call process.");
16809                pw.println("  --package: interpret process arg as package, dumping all");
16810                pw.println("             processes that have loaded that package.");
16811                pw.println("  --checkin: dump data for a checkin");
16812                pw.println("If [process] is specified it can be the name or ");
16813                pw.println("pid of a specific process to dump.");
16814                return;
16815            } else {
16816                pw.println("Unknown argument: " + opt + "; use -h for help");
16817            }
16818        }
16819
16820        long uptime = SystemClock.uptimeMillis();
16821        long realtime = SystemClock.elapsedRealtime();
16822        final long[] tmpLong = new long[1];
16823
16824        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16825        if (procs == null) {
16826            // No Java processes.  Maybe they want to print a native process.
16827            if (args != null && args.length > opti
16828                    && args[opti].charAt(0) != '-') {
16829                ArrayList<ProcessCpuTracker.Stats> nativeProcs
16830                        = new ArrayList<ProcessCpuTracker.Stats>();
16831                updateCpuStatsNow();
16832                int findPid = -1;
16833                try {
16834                    findPid = Integer.parseInt(args[opti]);
16835                } catch (NumberFormatException e) {
16836                }
16837                synchronized (mProcessCpuTracker) {
16838                    final int N = mProcessCpuTracker.countStats();
16839                    for (int i=0; i<N; i++) {
16840                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16841                        if (st.pid == findPid || (st.baseName != null
16842                                && st.baseName.equals(args[opti]))) {
16843                            nativeProcs.add(st);
16844                        }
16845                    }
16846                }
16847                if (nativeProcs.size() > 0) {
16848                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16849                            isCompact);
16850                    Debug.MemoryInfo mi = null;
16851                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16852                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16853                        final int pid = r.pid;
16854                        if (!isCheckinRequest && dumpDetails) {
16855                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16856                        }
16857                        if (mi == null) {
16858                            mi = new Debug.MemoryInfo();
16859                        }
16860                        if (dumpDetails || (!brief && !oomOnly)) {
16861                            Debug.getMemoryInfo(pid, mi);
16862                        } else {
16863                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16864                            mi.dalvikPrivateDirty = (int)tmpLong[0];
16865                        }
16866                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16867                                dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16868                        if (isCheckinRequest) {
16869                            pw.println();
16870                        }
16871                    }
16872                    return;
16873                }
16874            }
16875            pw.println("No process found for: " + args[opti]);
16876            return;
16877        }
16878
16879        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16880            dumpDetails = true;
16881        }
16882
16883        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16884
16885        String[] innerArgs = new String[args.length-opti];
16886        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16887
16888        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16889        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16890        long nativePss = 0;
16891        long nativeSwapPss = 0;
16892        long dalvikPss = 0;
16893        long dalvikSwapPss = 0;
16894        long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16895                EmptyArray.LONG;
16896        long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16897                EmptyArray.LONG;
16898        long otherPss = 0;
16899        long otherSwapPss = 0;
16900        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16901        long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16902
16903        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16904        long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16905        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16906                new ArrayList[DUMP_MEM_OOM_LABEL.length];
16907
16908        long totalPss = 0;
16909        long totalSwapPss = 0;
16910        long cachedPss = 0;
16911        long cachedSwapPss = 0;
16912        boolean hasSwapPss = false;
16913
16914        Debug.MemoryInfo mi = null;
16915        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16916            final ProcessRecord r = procs.get(i);
16917            final IApplicationThread thread;
16918            final int pid;
16919            final int oomAdj;
16920            final boolean hasActivities;
16921            synchronized (this) {
16922                thread = r.thread;
16923                pid = r.pid;
16924                oomAdj = r.getSetAdjWithServices();
16925                hasActivities = r.activities.size() > 0;
16926            }
16927            if (thread != null) {
16928                if (!isCheckinRequest && dumpDetails) {
16929                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16930                }
16931                if (mi == null) {
16932                    mi = new Debug.MemoryInfo();
16933                }
16934                if (dumpDetails || (!brief && !oomOnly)) {
16935                    Debug.getMemoryInfo(pid, mi);
16936                    hasSwapPss = mi.hasSwappedOutPss;
16937                } else {
16938                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16939                    mi.dalvikPrivateDirty = (int)tmpLong[0];
16940                }
16941                if (dumpDetails) {
16942                    if (localOnly) {
16943                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16944                                dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16945                        if (isCheckinRequest) {
16946                            pw.println();
16947                        }
16948                    } else {
16949                        pw.flush();
16950                        try {
16951                            TransferPipe tp = new TransferPipe();
16952                            try {
16953                                thread.dumpMemInfo(tp.getWriteFd(),
16954                                        mi, isCheckinRequest, dumpFullDetails,
16955                                        dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16956                                tp.go(fd);
16957                            } finally {
16958                                tp.kill();
16959                            }
16960                        } catch (IOException e) {
16961                            if (!isCheckinRequest) {
16962                                pw.println("Got IoException!");
16963                                pw.flush();
16964                            }
16965                        } catch (RemoteException e) {
16966                            if (!isCheckinRequest) {
16967                                pw.println("Got RemoteException!");
16968                                pw.flush();
16969                            }
16970                        }
16971                    }
16972                }
16973
16974                final long myTotalPss = mi.getTotalPss();
16975                final long myTotalUss = mi.getTotalUss();
16976                final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16977
16978                synchronized (this) {
16979                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16980                        // Record this for posterity if the process has been stable.
16981                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16982                    }
16983                }
16984
16985                if (!isCheckinRequest && mi != null) {
16986                    totalPss += myTotalPss;
16987                    totalSwapPss += myTotalSwapPss;
16988                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16989                            (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16990                            myTotalSwapPss, pid, hasActivities);
16991                    procMems.add(pssItem);
16992                    procMemsMap.put(pid, pssItem);
16993
16994                    nativePss += mi.nativePss;
16995                    nativeSwapPss += mi.nativeSwappedOutPss;
16996                    dalvikPss += mi.dalvikPss;
16997                    dalvikSwapPss += mi.dalvikSwappedOutPss;
16998                    for (int j=0; j<dalvikSubitemPss.length; j++) {
16999                        dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17000                        dalvikSubitemSwapPss[j] +=
17001                                mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17002                    }
17003                    otherPss += mi.otherPss;
17004                    otherSwapPss += mi.otherSwappedOutPss;
17005                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17006                        long mem = mi.getOtherPss(j);
17007                        miscPss[j] += mem;
17008                        otherPss -= mem;
17009                        mem = mi.getOtherSwappedOutPss(j);
17010                        miscSwapPss[j] += mem;
17011                        otherSwapPss -= mem;
17012                    }
17013
17014                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17015                        cachedPss += myTotalPss;
17016                        cachedSwapPss += myTotalSwapPss;
17017                    }
17018
17019                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17020                        if (oomIndex == (oomPss.length - 1)
17021                                || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17022                                        && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17023                            oomPss[oomIndex] += myTotalPss;
17024                            oomSwapPss[oomIndex] += myTotalSwapPss;
17025                            if (oomProcs[oomIndex] == null) {
17026                                oomProcs[oomIndex] = new ArrayList<MemItem>();
17027                            }
17028                            oomProcs[oomIndex].add(pssItem);
17029                            break;
17030                        }
17031                    }
17032                }
17033            }
17034        }
17035
17036        long nativeProcTotalPss = 0;
17037
17038        if (!isCheckinRequest && procs.size() > 1 && !packages) {
17039            // If we are showing aggregations, also look for native processes to
17040            // include so that our aggregations are more accurate.
17041            updateCpuStatsNow();
17042            mi = null;
17043            synchronized (mProcessCpuTracker) {
17044                final int N = mProcessCpuTracker.countStats();
17045                for (int i=0; i<N; i++) {
17046                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17047                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17048                        if (mi == null) {
17049                            mi = new Debug.MemoryInfo();
17050                        }
17051                        if (!brief && !oomOnly) {
17052                            Debug.getMemoryInfo(st.pid, mi);
17053                        } else {
17054                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17055                            mi.nativePrivateDirty = (int)tmpLong[0];
17056                        }
17057
17058                        final long myTotalPss = mi.getTotalPss();
17059                        final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17060                        totalPss += myTotalPss;
17061                        nativeProcTotalPss += myTotalPss;
17062
17063                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17064                                st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17065                        procMems.add(pssItem);
17066
17067                        nativePss += mi.nativePss;
17068                        nativeSwapPss += mi.nativeSwappedOutPss;
17069                        dalvikPss += mi.dalvikPss;
17070                        dalvikSwapPss += mi.dalvikSwappedOutPss;
17071                        for (int j=0; j<dalvikSubitemPss.length; j++) {
17072                            dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17073                            dalvikSubitemSwapPss[j] +=
17074                                    mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17075                        }
17076                        otherPss += mi.otherPss;
17077                        otherSwapPss += mi.otherSwappedOutPss;
17078                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17079                            long mem = mi.getOtherPss(j);
17080                            miscPss[j] += mem;
17081                            otherPss -= mem;
17082                            mem = mi.getOtherSwappedOutPss(j);
17083                            miscSwapPss[j] += mem;
17084                            otherSwapPss -= mem;
17085                        }
17086                        oomPss[0] += myTotalPss;
17087                        oomSwapPss[0] += myTotalSwapPss;
17088                        if (oomProcs[0] == null) {
17089                            oomProcs[0] = new ArrayList<MemItem>();
17090                        }
17091                        oomProcs[0].add(pssItem);
17092                    }
17093                }
17094            }
17095
17096            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17097
17098            catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17099            final MemItem dalvikItem =
17100                    new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
17101            if (dalvikSubitemPss.length > 0) {
17102                dalvikItem.subitems = new ArrayList<MemItem>();
17103                for (int j=0; j<dalvikSubitemPss.length; j++) {
17104                    final String name = Debug.MemoryInfo.getOtherLabel(
17105                            Debug.MemoryInfo.NUM_OTHER_STATS + j);
17106                    dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17107                                    dalvikSubitemSwapPss[j], j));
17108                }
17109            }
17110            catMems.add(dalvikItem);
17111            catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17112            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17113                String label = Debug.MemoryInfo.getOtherLabel(j);
17114                catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17115            }
17116
17117            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17118            for (int j=0; j<oomPss.length; j++) {
17119                if (oomPss[j] != 0) {
17120                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17121                            : DUMP_MEM_OOM_LABEL[j];
17122                    MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17123                            DUMP_MEM_OOM_ADJ[j]);
17124                    item.subitems = oomProcs[j];
17125                    oomMems.add(item);
17126                }
17127            }
17128
17129            dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17130            if (!brief && !oomOnly && !isCompact) {
17131                pw.println();
17132                pw.println("Total PSS by process:");
17133                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17134                pw.println();
17135            }
17136            if (!isCompact) {
17137                pw.println("Total PSS by OOM adjustment:");
17138            }
17139            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17140            if (!brief && !oomOnly) {
17141                PrintWriter out = categoryPw != null ? categoryPw : pw;
17142                if (!isCompact) {
17143                    out.println();
17144                    out.println("Total PSS by category:");
17145                }
17146                dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17147            }
17148            if (!isCompact) {
17149                pw.println();
17150            }
17151            MemInfoReader memInfo = new MemInfoReader();
17152            memInfo.readMemInfo();
17153            if (nativeProcTotalPss > 0) {
17154                synchronized (this) {
17155                    final long cachedKb = memInfo.getCachedSizeKb();
17156                    final long freeKb = memInfo.getFreeSizeKb();
17157                    final long zramKb = memInfo.getZramTotalSizeKb();
17158                    final long kernelKb = memInfo.getKernelUsedSizeKb();
17159                    EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17160                            kernelKb*1024, nativeProcTotalPss*1024);
17161                    mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17162                            nativeProcTotalPss);
17163                }
17164            }
17165            if (!brief) {
17166                if (!isCompact) {
17167                    pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17168                    pw.print(" (status ");
17169                    switch (mLastMemoryLevel) {
17170                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17171                            pw.println("normal)");
17172                            break;
17173                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17174                            pw.println("moderate)");
17175                            break;
17176                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
17177                            pw.println("low)");
17178                            break;
17179                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17180                            pw.println("critical)");
17181                            break;
17182                        default:
17183                            pw.print(mLastMemoryLevel);
17184                            pw.println(")");
17185                            break;
17186                    }
17187                    pw.print(" Free RAM: ");
17188                    pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17189                            + memInfo.getFreeSizeKb()));
17190                    pw.print(" (");
17191                    pw.print(stringifyKBSize(cachedPss));
17192                    pw.print(" cached pss + ");
17193                    pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17194                    pw.print(" cached kernel + ");
17195                    pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17196                    pw.println(" free)");
17197                } else {
17198                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17199                    pw.print(cachedPss + memInfo.getCachedSizeKb()
17200                            + memInfo.getFreeSizeKb()); pw.print(",");
17201                    pw.println(totalPss - cachedPss);
17202                }
17203            }
17204            long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17205                    - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17206                    - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17207            if (!isCompact) {
17208                pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17209                        + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17210                pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17211                pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17212                pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17213            } else {
17214                pw.print("lostram,"); pw.println(lostRAM);
17215            }
17216            if (!brief) {
17217                if (memInfo.getZramTotalSizeKb() != 0) {
17218                    if (!isCompact) {
17219                        pw.print("     ZRAM: ");
17220                        pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17221                                pw.print(" physical used for ");
17222                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17223                                        - memInfo.getSwapFreeSizeKb()));
17224                                pw.print(" in swap (");
17225                                pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17226                                pw.println(" total swap)");
17227                    } else {
17228                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17229                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17230                                pw.println(memInfo.getSwapFreeSizeKb());
17231                    }
17232                }
17233                final long[] ksm = getKsmInfo();
17234                if (!isCompact) {
17235                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17236                            || ksm[KSM_VOLATILE] != 0) {
17237                        pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17238                                pw.print(" saved from shared ");
17239                                pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17240                        pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17241                                pw.print(" unshared; ");
17242                                pw.print(stringifyKBSize(
17243                                             ksm[KSM_VOLATILE])); pw.println(" volatile");
17244                    }
17245                    pw.print("   Tuning: ");
17246                    pw.print(ActivityManager.staticGetMemoryClass());
17247                    pw.print(" (large ");
17248                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17249                    pw.print("), oom ");
17250                    pw.print(stringifySize(
17251                                mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17252                    pw.print(", restore limit ");
17253                    pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17254                    if (ActivityManager.isLowRamDeviceStatic()) {
17255                        pw.print(" (low-ram)");
17256                    }
17257                    if (ActivityManager.isHighEndGfx()) {
17258                        pw.print(" (high-end-gfx)");
17259                    }
17260                    pw.println();
17261                } else {
17262                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17263                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17264                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17265                    pw.print("tuning,");
17266                    pw.print(ActivityManager.staticGetMemoryClass());
17267                    pw.print(',');
17268                    pw.print(ActivityManager.staticGetLargeMemoryClass());
17269                    pw.print(',');
17270                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17271                    if (ActivityManager.isLowRamDeviceStatic()) {
17272                        pw.print(",low-ram");
17273                    }
17274                    if (ActivityManager.isHighEndGfx()) {
17275                        pw.print(",high-end-gfx");
17276                    }
17277                    pw.println();
17278                }
17279            }
17280        }
17281    }
17282
17283    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17284            long memtrack, String name) {
17285        sb.append("  ");
17286        sb.append(ProcessList.makeOomAdjString(oomAdj));
17287        sb.append(' ');
17288        sb.append(ProcessList.makeProcStateString(procState));
17289        sb.append(' ');
17290        ProcessList.appendRamKb(sb, pss);
17291        sb.append(": ");
17292        sb.append(name);
17293        if (memtrack > 0) {
17294            sb.append(" (");
17295            sb.append(stringifyKBSize(memtrack));
17296            sb.append(" memtrack)");
17297        }
17298    }
17299
17300    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17301        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17302        sb.append(" (pid ");
17303        sb.append(mi.pid);
17304        sb.append(") ");
17305        sb.append(mi.adjType);
17306        sb.append('\n');
17307        if (mi.adjReason != null) {
17308            sb.append("                      ");
17309            sb.append(mi.adjReason);
17310            sb.append('\n');
17311        }
17312    }
17313
17314    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17315        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17316        for (int i=0, N=memInfos.size(); i<N; i++) {
17317            ProcessMemInfo mi = memInfos.get(i);
17318            infoMap.put(mi.pid, mi);
17319        }
17320        updateCpuStatsNow();
17321        long[] memtrackTmp = new long[1];
17322        final List<ProcessCpuTracker.Stats> stats;
17323        // Get a list of Stats that have vsize > 0
17324        synchronized (mProcessCpuTracker) {
17325            stats = mProcessCpuTracker.getStats((st) -> {
17326                return st.vsize > 0;
17327            });
17328        }
17329        final int statsCount = stats.size();
17330        for (int i = 0; i < statsCount; i++) {
17331            ProcessCpuTracker.Stats st = stats.get(i);
17332            long pss = Debug.getPss(st.pid, null, memtrackTmp);
17333            if (pss > 0) {
17334                if (infoMap.indexOfKey(st.pid) < 0) {
17335                    ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17336                            ProcessList.NATIVE_ADJ, -1, "native", null);
17337                    mi.pss = pss;
17338                    mi.memtrack = memtrackTmp[0];
17339                    memInfos.add(mi);
17340                }
17341            }
17342        }
17343
17344        long totalPss = 0;
17345        long totalMemtrack = 0;
17346        for (int i=0, N=memInfos.size(); i<N; i++) {
17347            ProcessMemInfo mi = memInfos.get(i);
17348            if (mi.pss == 0) {
17349                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17350                mi.memtrack = memtrackTmp[0];
17351            }
17352            totalPss += mi.pss;
17353            totalMemtrack += mi.memtrack;
17354        }
17355        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17356            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17357                if (lhs.oomAdj != rhs.oomAdj) {
17358                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17359                }
17360                if (lhs.pss != rhs.pss) {
17361                    return lhs.pss < rhs.pss ? 1 : -1;
17362                }
17363                return 0;
17364            }
17365        });
17366
17367        StringBuilder tag = new StringBuilder(128);
17368        StringBuilder stack = new StringBuilder(128);
17369        tag.append("Low on memory -- ");
17370        appendMemBucket(tag, totalPss, "total", false);
17371        appendMemBucket(stack, totalPss, "total", true);
17372
17373        StringBuilder fullNativeBuilder = new StringBuilder(1024);
17374        StringBuilder shortNativeBuilder = new StringBuilder(1024);
17375        StringBuilder fullJavaBuilder = new StringBuilder(1024);
17376
17377        boolean firstLine = true;
17378        int lastOomAdj = Integer.MIN_VALUE;
17379        long extraNativeRam = 0;
17380        long extraNativeMemtrack = 0;
17381        long cachedPss = 0;
17382        for (int i=0, N=memInfos.size(); i<N; i++) {
17383            ProcessMemInfo mi = memInfos.get(i);
17384
17385            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17386                cachedPss += mi.pss;
17387            }
17388
17389            if (mi.oomAdj != ProcessList.NATIVE_ADJ
17390                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
17391                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
17392                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17393                if (lastOomAdj != mi.oomAdj) {
17394                    lastOomAdj = mi.oomAdj;
17395                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17396                        tag.append(" / ");
17397                    }
17398                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17399                        if (firstLine) {
17400                            stack.append(":");
17401                            firstLine = false;
17402                        }
17403                        stack.append("\n\t at ");
17404                    } else {
17405                        stack.append("$");
17406                    }
17407                } else {
17408                    tag.append(" ");
17409                    stack.append("$");
17410                }
17411                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17412                    appendMemBucket(tag, mi.pss, mi.name, false);
17413                }
17414                appendMemBucket(stack, mi.pss, mi.name, true);
17415                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17416                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17417                    stack.append("(");
17418                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17419                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17420                            stack.append(DUMP_MEM_OOM_LABEL[k]);
17421                            stack.append(":");
17422                            stack.append(DUMP_MEM_OOM_ADJ[k]);
17423                        }
17424                    }
17425                    stack.append(")");
17426                }
17427            }
17428
17429            appendMemInfo(fullNativeBuilder, mi);
17430            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17431                // The short form only has native processes that are >= 512K.
17432                if (mi.pss >= 512) {
17433                    appendMemInfo(shortNativeBuilder, mi);
17434                } else {
17435                    extraNativeRam += mi.pss;
17436                    extraNativeMemtrack += mi.memtrack;
17437                }
17438            } else {
17439                // Short form has all other details, but if we have collected RAM
17440                // from smaller native processes let's dump a summary of that.
17441                if (extraNativeRam > 0) {
17442                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17443                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17444                    shortNativeBuilder.append('\n');
17445                    extraNativeRam = 0;
17446                }
17447                appendMemInfo(fullJavaBuilder, mi);
17448            }
17449        }
17450
17451        fullJavaBuilder.append("           ");
17452        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17453        fullJavaBuilder.append(": TOTAL");
17454        if (totalMemtrack > 0) {
17455            fullJavaBuilder.append(" (");
17456            fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17457            fullJavaBuilder.append(" memtrack)");
17458        } else {
17459        }
17460        fullJavaBuilder.append("\n");
17461
17462        MemInfoReader memInfo = new MemInfoReader();
17463        memInfo.readMemInfo();
17464        final long[] infos = memInfo.getRawInfo();
17465
17466        StringBuilder memInfoBuilder = new StringBuilder(1024);
17467        Debug.getMemInfo(infos);
17468        memInfoBuilder.append("  MemInfo: ");
17469        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17470        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17471        memInfoBuilder.append(stringifyKBSize(
17472                                  infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17473        memInfoBuilder.append(stringifyKBSize(
17474                                  infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17475        memInfoBuilder.append(stringifyKBSize(
17476                                  infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17477        memInfoBuilder.append("           ");
17478        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17479        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17480        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17481        memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17482        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17483            memInfoBuilder.append("  ZRAM: ");
17484            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17485            memInfoBuilder.append(" RAM, ");
17486            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17487            memInfoBuilder.append(" swap total, ");
17488            memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17489            memInfoBuilder.append(" swap free\n");
17490        }
17491        final long[] ksm = getKsmInfo();
17492        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17493                || ksm[KSM_VOLATILE] != 0) {
17494            memInfoBuilder.append("  KSM: ");
17495            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17496            memInfoBuilder.append(" saved from shared ");
17497            memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17498            memInfoBuilder.append("\n       ");
17499            memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17500            memInfoBuilder.append(" unshared; ");
17501            memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17502            memInfoBuilder.append(" volatile\n");
17503        }
17504        memInfoBuilder.append("  Free RAM: ");
17505        memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17506                + memInfo.getFreeSizeKb()));
17507        memInfoBuilder.append("\n");
17508        memInfoBuilder.append("  Used RAM: ");
17509        memInfoBuilder.append(stringifyKBSize(
17510                                  totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17511        memInfoBuilder.append("\n");
17512        memInfoBuilder.append("  Lost RAM: ");
17513        memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17514                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17515                - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17516        memInfoBuilder.append("\n");
17517        Slog.i(TAG, "Low on memory:");
17518        Slog.i(TAG, shortNativeBuilder.toString());
17519        Slog.i(TAG, fullJavaBuilder.toString());
17520        Slog.i(TAG, memInfoBuilder.toString());
17521
17522        StringBuilder dropBuilder = new StringBuilder(1024);
17523        /*
17524        StringWriter oomSw = new StringWriter();
17525        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17526        StringWriter catSw = new StringWriter();
17527        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17528        String[] emptyArgs = new String[] { };
17529        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17530        oomPw.flush();
17531        String oomString = oomSw.toString();
17532        */
17533        dropBuilder.append("Low on memory:");
17534        dropBuilder.append(stack);
17535        dropBuilder.append('\n');
17536        dropBuilder.append(fullNativeBuilder);
17537        dropBuilder.append(fullJavaBuilder);
17538        dropBuilder.append('\n');
17539        dropBuilder.append(memInfoBuilder);
17540        dropBuilder.append('\n');
17541        /*
17542        dropBuilder.append(oomString);
17543        dropBuilder.append('\n');
17544        */
17545        StringWriter catSw = new StringWriter();
17546        synchronized (ActivityManagerService.this) {
17547            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17548            String[] emptyArgs = new String[] { };
17549            catPw.println();
17550            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17551            catPw.println();
17552            mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17553                    false, null).dumpLocked();
17554            catPw.println();
17555            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17556            catPw.flush();
17557        }
17558        dropBuilder.append(catSw.toString());
17559        addErrorToDropBox("lowmem", null, "system_server", null,
17560                null, tag.toString(), dropBuilder.toString(), null, null);
17561        //Slog.i(TAG, "Sent to dropbox:");
17562        //Slog.i(TAG, dropBuilder.toString());
17563        synchronized (ActivityManagerService.this) {
17564            long now = SystemClock.uptimeMillis();
17565            if (mLastMemUsageReportTime < now) {
17566                mLastMemUsageReportTime = now;
17567            }
17568        }
17569    }
17570
17571    /**
17572     * Searches array of arguments for the specified string
17573     * @param args array of argument strings
17574     * @param value value to search for
17575     * @return true if the value is contained in the array
17576     */
17577    private static boolean scanArgs(String[] args, String value) {
17578        if (args != null) {
17579            for (String arg : args) {
17580                if (value.equals(arg)) {
17581                    return true;
17582                }
17583            }
17584        }
17585        return false;
17586    }
17587
17588    private final boolean removeDyingProviderLocked(ProcessRecord proc,
17589            ContentProviderRecord cpr, boolean always) {
17590        final boolean inLaunching = mLaunchingProviders.contains(cpr);
17591
17592        if (!inLaunching || always) {
17593            synchronized (cpr) {
17594                cpr.launchingApp = null;
17595                cpr.notifyAll();
17596            }
17597            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17598            String names[] = cpr.info.authority.split(";");
17599            for (int j = 0; j < names.length; j++) {
17600                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17601            }
17602        }
17603
17604        for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17605            ContentProviderConnection conn = cpr.connections.get(i);
17606            if (conn.waiting) {
17607                // If this connection is waiting for the provider, then we don't
17608                // need to mess with its process unless we are always removing
17609                // or for some reason the provider is not currently launching.
17610                if (inLaunching && !always) {
17611                    continue;
17612                }
17613            }
17614            ProcessRecord capp = conn.client;
17615            conn.dead = true;
17616            if (conn.stableCount > 0) {
17617                if (!capp.persistent && capp.thread != null
17618                        && capp.pid != 0
17619                        && capp.pid != MY_PID) {
17620                    capp.kill("depends on provider "
17621                            + cpr.name.flattenToShortString()
17622                            + " in dying proc " + (proc != null ? proc.processName : "??")
17623                            + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17624                }
17625            } else if (capp.thread != null && conn.provider.provider != null) {
17626                try {
17627                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17628                } catch (RemoteException e) {
17629                }
17630                // In the protocol here, we don't expect the client to correctly
17631                // clean up this connection, we'll just remove it.
17632                cpr.connections.remove(i);
17633                if (conn.client.conProviders.remove(conn)) {
17634                    stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17635                }
17636            }
17637        }
17638
17639        if (inLaunching && always) {
17640            mLaunchingProviders.remove(cpr);
17641        }
17642        return inLaunching;
17643    }
17644
17645    /**
17646     * Main code for cleaning up a process when it has gone away.  This is
17647     * called both as a result of the process dying, or directly when stopping
17648     * a process when running in single process mode.
17649     *
17650     * @return Returns true if the given process has been restarted, so the
17651     * app that was passed in must remain on the process lists.
17652     */
17653    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
17654            boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
17655        Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
17656        if (index >= 0) {
17657            removeLruProcessLocked(app);
17658            ProcessList.remove(app.pid);
17659        }
17660
17661        mProcessesToGc.remove(app);
17662        mPendingPssProcesses.remove(app);
17663
17664        // Dismiss any open dialogs.
17665        if (app.crashDialog != null && !app.forceCrashReport) {
17666            app.crashDialog.dismiss();
17667            app.crashDialog = null;
17668        }
17669        if (app.anrDialog != null) {
17670            app.anrDialog.dismiss();
17671            app.anrDialog = null;
17672        }
17673        if (app.waitDialog != null) {
17674            app.waitDialog.dismiss();
17675            app.waitDialog = null;
17676        }
17677
17678        app.crashing = false;
17679        app.notResponding = false;
17680
17681        app.resetPackageList(mProcessStats);
17682        app.unlinkDeathRecipient();
17683        app.makeInactive(mProcessStats);
17684        app.waitingToKill = null;
17685        app.forcingToForeground = null;
17686        updateProcessForegroundLocked(app, false, false);
17687        app.foregroundActivities = false;
17688        app.hasShownUi = false;
17689        app.treatLikeActivity = false;
17690        app.hasAboveClient = false;
17691        app.hasClientActivities = false;
17692
17693        mServices.killServicesLocked(app, allowRestart);
17694
17695        boolean restart = false;
17696
17697        // Remove published content providers.
17698        for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
17699            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
17700            final boolean always = app.bad || !allowRestart;
17701            boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
17702            if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
17703                // We left the provider in the launching list, need to
17704                // restart it.
17705                restart = true;
17706            }
17707
17708            cpr.provider = null;
17709            cpr.proc = null;
17710        }
17711        app.pubProviders.clear();
17712
17713        // Take care of any launching providers waiting for this process.
17714        if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17715            restart = true;
17716        }
17717
17718        // Unregister from connected content providers.
17719        if (!app.conProviders.isEmpty()) {
17720            for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17721                ContentProviderConnection conn = app.conProviders.get(i);
17722                conn.provider.connections.remove(conn);
17723                stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17724                        conn.provider.name);
17725            }
17726            app.conProviders.clear();
17727        }
17728
17729        // At this point there may be remaining entries in mLaunchingProviders
17730        // where we were the only one waiting, so they are no longer of use.
17731        // Look for these and clean up if found.
17732        // XXX Commented out for now.  Trying to figure out a way to reproduce
17733        // the actual situation to identify what is actually going on.
17734        if (false) {
17735            for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17736                ContentProviderRecord cpr = mLaunchingProviders.get(i);
17737                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17738                    synchronized (cpr) {
17739                        cpr.launchingApp = null;
17740                        cpr.notifyAll();
17741                    }
17742                }
17743            }
17744        }
17745
17746        skipCurrentReceiverLocked(app);
17747
17748        // Unregister any receivers.
17749        for (int i = app.receivers.size() - 1; i >= 0; i--) {
17750            removeReceiverLocked(app.receivers.valueAt(i));
17751        }
17752        app.receivers.clear();
17753
17754        // If the app is undergoing backup, tell the backup manager about it
17755        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17756            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17757                    + mBackupTarget.appInfo + " died during backup");
17758            mHandler.post(new Runnable() {
17759                @Override
17760                public void run(){
17761                    try {
17762                        IBackupManager bm = IBackupManager.Stub.asInterface(
17763                                ServiceManager.getService(Context.BACKUP_SERVICE));
17764                        bm.agentDisconnected(app.info.packageName);
17765                    } catch (RemoteException e) {
17766                        // can't happen; backup manager is local
17767                    }
17768                }
17769            });
17770        }
17771
17772        for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17773            ProcessChangeItem item = mPendingProcessChanges.get(i);
17774            if (item.pid == app.pid) {
17775                mPendingProcessChanges.remove(i);
17776                mAvailProcessChanges.add(item);
17777            }
17778        }
17779        mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17780                null).sendToTarget();
17781
17782        // If the caller is restarting this app, then leave it in its
17783        // current lists and let the caller take care of it.
17784        if (restarting) {
17785            return false;
17786        }
17787
17788        if (!app.persistent || app.isolated) {
17789            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17790                    "Removing non-persistent process during cleanup: " + app);
17791            if (!replacingPid) {
17792                removeProcessNameLocked(app.processName, app.uid, app);
17793            }
17794            if (mHeavyWeightProcess == app) {
17795                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17796                        mHeavyWeightProcess.userId, 0));
17797                mHeavyWeightProcess = null;
17798            }
17799        } else if (!app.removed) {
17800            // This app is persistent, so we need to keep its record around.
17801            // If it is not already on the pending app list, add it there
17802            // and start a new process for it.
17803            if (mPersistentStartingProcesses.indexOf(app) < 0) {
17804                mPersistentStartingProcesses.add(app);
17805                restart = true;
17806            }
17807        }
17808        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17809                TAG_CLEANUP, "Clean-up removing on hold: " + app);
17810        mProcessesOnHold.remove(app);
17811
17812        if (app == mHomeProcess) {
17813            mHomeProcess = null;
17814        }
17815        if (app == mPreviousProcess) {
17816            mPreviousProcess = null;
17817        }
17818
17819        if (restart && !app.isolated) {
17820            // We have components that still need to be running in the
17821            // process, so re-launch it.
17822            if (index < 0) {
17823                ProcessList.remove(app.pid);
17824            }
17825            addProcessNameLocked(app);
17826            startProcessLocked(app, "restart", app.processName);
17827            return true;
17828        } else if (app.pid > 0 && app.pid != MY_PID) {
17829            // Goodbye!
17830            boolean removed;
17831            synchronized (mPidsSelfLocked) {
17832                mPidsSelfLocked.remove(app.pid);
17833                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17834            }
17835            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17836            if (app.isolated) {
17837                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17838            }
17839            app.setPid(0);
17840        }
17841        return false;
17842    }
17843
17844    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17845        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17846            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17847            if (cpr.launchingApp == app) {
17848                return true;
17849            }
17850        }
17851        return false;
17852    }
17853
17854    boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17855        // Look through the content providers we are waiting to have launched,
17856        // and if any run in this process then either schedule a restart of
17857        // the process or kill the client waiting for it if this process has
17858        // gone bad.
17859        boolean restart = false;
17860        for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17861            ContentProviderRecord cpr = mLaunchingProviders.get(i);
17862            if (cpr.launchingApp == app) {
17863                if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17864                    restart = true;
17865                } else {
17866                    removeDyingProviderLocked(app, cpr, true);
17867                }
17868            }
17869        }
17870        return restart;
17871    }
17872
17873    // =========================================================
17874    // SERVICES
17875    // =========================================================
17876
17877    @Override
17878    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17879            int flags) {
17880        enforceNotIsolatedCaller("getServices");
17881
17882        final int callingUid = Binder.getCallingUid();
17883        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
17884            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
17885        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
17886            callingUid);
17887        synchronized (this) {
17888            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
17889                allowed, canInteractAcrossUsers);
17890        }
17891    }
17892
17893    @Override
17894    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17895        enforceNotIsolatedCaller("getRunningServiceControlPanel");
17896        synchronized (this) {
17897            return mServices.getRunningServiceControlPanelLocked(name);
17898        }
17899    }
17900
17901    @Override
17902    public ComponentName startService(IApplicationThread caller, Intent service,
17903            String resolvedType, int id, Notification notification,
17904            String callingPackage, int userId)
17905            throws TransactionTooLargeException {
17906        enforceNotIsolatedCaller("startService");
17907        // Refuse possible leaked file descriptors
17908        if (service != null && service.hasFileDescriptors() == true) {
17909            throw new IllegalArgumentException("File descriptors passed in Intent");
17910        }
17911
17912        if (callingPackage == null) {
17913            throw new IllegalArgumentException("callingPackage cannot be null");
17914        }
17915
17916        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17917                "startService: " + service + " type=" + resolvedType);
17918        synchronized(this) {
17919            final int callingPid = Binder.getCallingPid();
17920            final int callingUid = Binder.getCallingUid();
17921            final long origId = Binder.clearCallingIdentity();
17922            ComponentName res = mServices.startServiceLocked(caller, service,
17923                    resolvedType, id, notification,
17924                    callingPid, callingUid, callingPackage, userId);
17925            Binder.restoreCallingIdentity(origId);
17926            return res;
17927        }
17928    }
17929
17930    ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17931            String callingPackage, int userId)
17932            throws TransactionTooLargeException {
17933        synchronized(this) {
17934            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17935                    "startServiceInPackage: " + service + " type=" + resolvedType);
17936            final long origId = Binder.clearCallingIdentity();
17937            ComponentName res = mServices.startServiceLocked(null, service,
17938                    resolvedType, 0, null, -1, uid, callingPackage, userId);
17939            Binder.restoreCallingIdentity(origId);
17940            return res;
17941        }
17942    }
17943
17944    @Override
17945    public int stopService(IApplicationThread caller, Intent service,
17946            String resolvedType, int userId) {
17947        enforceNotIsolatedCaller("stopService");
17948        // Refuse possible leaked file descriptors
17949        if (service != null && service.hasFileDescriptors() == true) {
17950            throw new IllegalArgumentException("File descriptors passed in Intent");
17951        }
17952
17953        synchronized(this) {
17954            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17955        }
17956    }
17957
17958    @Override
17959    public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17960        enforceNotIsolatedCaller("peekService");
17961        // Refuse possible leaked file descriptors
17962        if (service != null && service.hasFileDescriptors() == true) {
17963            throw new IllegalArgumentException("File descriptors passed in Intent");
17964        }
17965
17966        if (callingPackage == null) {
17967            throw new IllegalArgumentException("callingPackage cannot be null");
17968        }
17969
17970        synchronized(this) {
17971            return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17972        }
17973    }
17974
17975    @Override
17976    public boolean stopServiceToken(ComponentName className, IBinder token,
17977            int startId) {
17978        synchronized(this) {
17979            return mServices.stopServiceTokenLocked(className, token, startId);
17980        }
17981    }
17982
17983    @Override
17984    public void setServiceForeground(ComponentName className, IBinder token,
17985            int id, Notification notification, int flags) {
17986        synchronized(this) {
17987            mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17988        }
17989    }
17990
17991    @Override
17992    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17993            boolean requireFull, String name, String callerPackage) {
17994        return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17995                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17996    }
17997
17998    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17999            String className, int flags) {
18000        boolean result = false;
18001        // For apps that don't have pre-defined UIDs, check for permission
18002        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
18003            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18004                if (ActivityManager.checkUidPermission(
18005                        INTERACT_ACROSS_USERS,
18006                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18007                    ComponentName comp = new ComponentName(aInfo.packageName, className);
18008                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
18009                            + " requests FLAG_SINGLE_USER, but app does not hold "
18010                            + INTERACT_ACROSS_USERS;
18011                    Slog.w(TAG, msg);
18012                    throw new SecurityException(msg);
18013                }
18014                // Permission passed
18015                result = true;
18016            }
18017        } else if ("system".equals(componentProcessName)) {
18018            result = true;
18019        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18020            // Phone app and persistent apps are allowed to export singleuser providers.
18021            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
18022                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18023        }
18024        if (DEBUG_MU) Slog.v(TAG_MU,
18025                "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18026                + Integer.toHexString(flags) + ") = " + result);
18027        return result;
18028    }
18029
18030    /**
18031     * Checks to see if the caller is in the same app as the singleton
18032     * component, or the component is in a special app. It allows special apps
18033     * to export singleton components but prevents exporting singleton
18034     * components for regular apps.
18035     */
18036    boolean isValidSingletonCall(int callingUid, int componentUid) {
18037        int componentAppId = UserHandle.getAppId(componentUid);
18038        return UserHandle.isSameApp(callingUid, componentUid)
18039                || componentAppId == Process.SYSTEM_UID
18040                || componentAppId == Process.PHONE_UID
18041                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18042                        == PackageManager.PERMISSION_GRANTED;
18043    }
18044
18045    public int bindService(IApplicationThread caller, IBinder token, Intent service,
18046            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18047            int userId) throws TransactionTooLargeException {
18048        enforceNotIsolatedCaller("bindService");
18049
18050        // Refuse possible leaked file descriptors
18051        if (service != null && service.hasFileDescriptors() == true) {
18052            throw new IllegalArgumentException("File descriptors passed in Intent");
18053        }
18054
18055        if (callingPackage == null) {
18056            throw new IllegalArgumentException("callingPackage cannot be null");
18057        }
18058
18059        synchronized(this) {
18060            return mServices.bindServiceLocked(caller, token, service,
18061                    resolvedType, connection, flags, callingPackage, userId);
18062        }
18063    }
18064
18065    public boolean unbindService(IServiceConnection connection) {
18066        synchronized (this) {
18067            return mServices.unbindServiceLocked(connection);
18068        }
18069    }
18070
18071    public void publishService(IBinder token, Intent intent, IBinder service) {
18072        // Refuse possible leaked file descriptors
18073        if (intent != null && intent.hasFileDescriptors() == true) {
18074            throw new IllegalArgumentException("File descriptors passed in Intent");
18075        }
18076
18077        synchronized(this) {
18078            if (!(token instanceof ServiceRecord)) {
18079                throw new IllegalArgumentException("Invalid service token");
18080            }
18081            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18082        }
18083    }
18084
18085    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18086        // Refuse possible leaked file descriptors
18087        if (intent != null && intent.hasFileDescriptors() == true) {
18088            throw new IllegalArgumentException("File descriptors passed in Intent");
18089        }
18090
18091        synchronized(this) {
18092            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18093        }
18094    }
18095
18096    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18097        synchronized(this) {
18098            if (!(token instanceof ServiceRecord)) {
18099                Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18100                throw new IllegalArgumentException("Invalid service token");
18101            }
18102            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18103        }
18104    }
18105
18106    // =========================================================
18107    // BACKUP AND RESTORE
18108    // =========================================================
18109
18110    // Cause the target app to be launched if necessary and its backup agent
18111    // instantiated.  The backup agent will invoke backupAgentCreated() on the
18112    // activity manager to announce its creation.
18113    public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18114        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18115        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18116
18117        IPackageManager pm = AppGlobals.getPackageManager();
18118        ApplicationInfo app = null;
18119        try {
18120            app = pm.getApplicationInfo(packageName, 0, userId);
18121        } catch (RemoteException e) {
18122            // can't happen; package manager is process-local
18123        }
18124        if (app == null) {
18125            Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18126            return false;
18127        }
18128
18129        synchronized(this) {
18130            // !!! TODO: currently no check here that we're already bound
18131            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18132            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18133            synchronized (stats) {
18134                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18135            }
18136
18137            // Backup agent is now in use, its package can't be stopped.
18138            try {
18139                AppGlobals.getPackageManager().setPackageStoppedState(
18140                        app.packageName, false, UserHandle.getUserId(app.uid));
18141            } catch (RemoteException e) {
18142            } catch (IllegalArgumentException e) {
18143                Slog.w(TAG, "Failed trying to unstop package "
18144                        + app.packageName + ": " + e);
18145            }
18146
18147            BackupRecord r = new BackupRecord(ss, app, backupMode);
18148            ComponentName hostingName =
18149                    (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18150                            ? new ComponentName(app.packageName, app.backupAgentName)
18151                            : new ComponentName("android", "FullBackupAgent");
18152            // startProcessLocked() returns existing proc's record if it's already running
18153            ProcessRecord proc = startProcessLocked(app.processName, app,
18154                    false, 0, "backup", hostingName, false, false, false);
18155            if (proc == null) {
18156                Slog.e(TAG, "Unable to start backup agent process " + r);
18157                return false;
18158            }
18159
18160            // If the app is a regular app (uid >= 10000) and not the system server or phone
18161            // process, etc, then mark it as being in full backup so that certain calls to the
18162            // process can be blocked. This is not reset to false anywhere because we kill the
18163            // process after the full backup is done and the ProcessRecord will vaporize anyway.
18164            if (UserHandle.isApp(app.uid) &&
18165                    backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18166                proc.inFullBackup = true;
18167            }
18168            r.app = proc;
18169            mBackupTarget = r;
18170            mBackupAppName = app.packageName;
18171
18172            // Try not to kill the process during backup
18173            updateOomAdjLocked(proc);
18174
18175            // If the process is already attached, schedule the creation of the backup agent now.
18176            // If it is not yet live, this will be done when it attaches to the framework.
18177            if (proc.thread != null) {
18178                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18179                try {
18180                    proc.thread.scheduleCreateBackupAgent(app,
18181                            compatibilityInfoForPackageLocked(app), backupMode);
18182                } catch (RemoteException e) {
18183                    // Will time out on the backup manager side
18184                }
18185            } else {
18186                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18187            }
18188            // Invariants: at this point, the target app process exists and the application
18189            // is either already running or in the process of coming up.  mBackupTarget and
18190            // mBackupAppName describe the app, so that when it binds back to the AM we
18191            // know that it's scheduled for a backup-agent operation.
18192        }
18193
18194        return true;
18195    }
18196
18197    @Override
18198    public void clearPendingBackup() {
18199        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18200        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18201
18202        synchronized (this) {
18203            mBackupTarget = null;
18204            mBackupAppName = null;
18205        }
18206    }
18207
18208    // A backup agent has just come up
18209    public void backupAgentCreated(String agentPackageName, IBinder agent) {
18210        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18211                + " = " + agent);
18212
18213        synchronized(this) {
18214            if (!agentPackageName.equals(mBackupAppName)) {
18215                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18216                return;
18217            }
18218        }
18219
18220        long oldIdent = Binder.clearCallingIdentity();
18221        try {
18222            IBackupManager bm = IBackupManager.Stub.asInterface(
18223                    ServiceManager.getService(Context.BACKUP_SERVICE));
18224            bm.agentConnected(agentPackageName, agent);
18225        } catch (RemoteException e) {
18226            // can't happen; the backup manager service is local
18227        } catch (Exception e) {
18228            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18229            e.printStackTrace();
18230        } finally {
18231            Binder.restoreCallingIdentity(oldIdent);
18232        }
18233    }
18234
18235    // done with this agent
18236    public void unbindBackupAgent(ApplicationInfo appInfo) {
18237        if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18238        if (appInfo == null) {
18239            Slog.w(TAG, "unbind backup agent for null app");
18240            return;
18241        }
18242
18243        synchronized(this) {
18244            try {
18245                if (mBackupAppName == null) {
18246                    Slog.w(TAG, "Unbinding backup agent with no active backup");
18247                    return;
18248                }
18249
18250                if (!mBackupAppName.equals(appInfo.packageName)) {
18251                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18252                    return;
18253                }
18254
18255                // Not backing this app up any more; reset its OOM adjustment
18256                final ProcessRecord proc = mBackupTarget.app;
18257                updateOomAdjLocked(proc);
18258                proc.inFullBackup = false;
18259
18260                // If the app crashed during backup, 'thread' will be null here
18261                if (proc.thread != null) {
18262                    try {
18263                        proc.thread.scheduleDestroyBackupAgent(appInfo,
18264                                compatibilityInfoForPackageLocked(appInfo));
18265                    } catch (Exception e) {
18266                        Slog.e(TAG, "Exception when unbinding backup agent:");
18267                        e.printStackTrace();
18268                    }
18269                }
18270            } finally {
18271                mBackupTarget = null;
18272                mBackupAppName = null;
18273            }
18274        }
18275    }
18276    // =========================================================
18277    // BROADCASTS
18278    // =========================================================
18279
18280    private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18281        if (UserHandle.getAppId(uid) < Process.FIRST_APPLICATION_UID) {
18282            return false;
18283        }
18284        // Easy case -- we have the app's ProcessRecord.
18285        if (record != null) {
18286            return record.info.isInstantApp();
18287        }
18288        // Otherwise check with PackageManager.
18289        if (callerPackage == null) {
18290            Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18291            throw new IllegalArgumentException("Calling application did not provide package name");
18292        }
18293        mAppOpsService.checkPackage(uid, callerPackage);
18294        try {
18295            IPackageManager pm = AppGlobals.getPackageManager();
18296            return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18297        } catch (RemoteException e) {
18298            Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18299            return true;
18300        }
18301    }
18302
18303    boolean isPendingBroadcastProcessLocked(int pid) {
18304        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18305                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18306    }
18307
18308    void skipPendingBroadcastLocked(int pid) {
18309            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18310            for (BroadcastQueue queue : mBroadcastQueues) {
18311                queue.skipPendingBroadcastLocked(pid);
18312            }
18313    }
18314
18315    // The app just attached; send any pending broadcasts that it should receive
18316    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18317        boolean didSomething = false;
18318        for (BroadcastQueue queue : mBroadcastQueues) {
18319            didSomething |= queue.sendPendingBroadcastsLocked(app);
18320        }
18321        return didSomething;
18322    }
18323
18324    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18325            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18326            boolean visibleToInstantApps) {
18327        enforceNotIsolatedCaller("registerReceiver");
18328        ArrayList<Intent> stickyIntents = null;
18329        ProcessRecord callerApp = null;
18330        int callingUid;
18331        int callingPid;
18332        boolean instantApp;
18333        synchronized(this) {
18334            if (caller != null) {
18335                callerApp = getRecordForAppLocked(caller);
18336                if (callerApp == null) {
18337                    throw new SecurityException(
18338                            "Unable to find app for caller " + caller
18339                            + " (pid=" + Binder.getCallingPid()
18340                            + ") when registering receiver " + receiver);
18341                }
18342                if (callerApp.info.uid != Process.SYSTEM_UID &&
18343                        !callerApp.pkgList.containsKey(callerPackage) &&
18344                        !"android".equals(callerPackage)) {
18345                    throw new SecurityException("Given caller package " + callerPackage
18346                            + " is not running in process " + callerApp);
18347                }
18348                callingUid = callerApp.info.uid;
18349                callingPid = callerApp.pid;
18350            } else {
18351                callerPackage = null;
18352                callingUid = Binder.getCallingUid();
18353                callingPid = Binder.getCallingPid();
18354            }
18355
18356            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18357            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18358                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18359
18360            Iterator<String> actions = filter.actionsIterator();
18361            if (actions == null) {
18362                ArrayList<String> noAction = new ArrayList<String>(1);
18363                noAction.add(null);
18364                actions = noAction.iterator();
18365            }
18366
18367            // Collect stickies of users
18368            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18369            while (actions.hasNext()) {
18370                String action = actions.next();
18371                for (int id : userIds) {
18372                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18373                    if (stickies != null) {
18374                        ArrayList<Intent> intents = stickies.get(action);
18375                        if (intents != null) {
18376                            if (stickyIntents == null) {
18377                                stickyIntents = new ArrayList<Intent>();
18378                            }
18379                            stickyIntents.addAll(intents);
18380                        }
18381                    }
18382                }
18383            }
18384        }
18385
18386        ArrayList<Intent> allSticky = null;
18387        if (stickyIntents != null) {
18388            final ContentResolver resolver = mContext.getContentResolver();
18389            // Look for any matching sticky broadcasts...
18390            for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18391                Intent intent = stickyIntents.get(i);
18392                // Don't provided intents that aren't available to instant apps.
18393                if (instantApp &&
18394                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18395                    continue;
18396                }
18397                // If intent has scheme "content", it will need to acccess
18398                // provider that needs to lock mProviderMap in ActivityThread
18399                // and also it may need to wait application response, so we
18400                // cannot lock ActivityManagerService here.
18401                if (filter.match(resolver, intent, true, TAG) >= 0) {
18402                    if (allSticky == null) {
18403                        allSticky = new ArrayList<Intent>();
18404                    }
18405                    allSticky.add(intent);
18406                }
18407            }
18408        }
18409
18410        // The first sticky in the list is returned directly back to the client.
18411        Intent sticky = allSticky != null ? allSticky.get(0) : null;
18412        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18413        if (receiver == null) {
18414            return sticky;
18415        }
18416
18417        synchronized (this) {
18418            if (callerApp != null && (callerApp.thread == null
18419                    || callerApp.thread.asBinder() != caller.asBinder())) {
18420                // Original caller already died
18421                return null;
18422            }
18423            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18424            if (rl == null) {
18425                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18426                        userId, receiver);
18427                if (rl.app != null) {
18428                    rl.app.receivers.add(rl);
18429                } else {
18430                    try {
18431                        receiver.asBinder().linkToDeath(rl, 0);
18432                    } catch (RemoteException e) {
18433                        return sticky;
18434                    }
18435                    rl.linkedToDeath = true;
18436                }
18437                mRegisteredReceivers.put(receiver.asBinder(), rl);
18438            } else if (rl.uid != callingUid) {
18439                throw new IllegalArgumentException(
18440                        "Receiver requested to register for uid " + callingUid
18441                        + " was previously registered for uid " + rl.uid
18442                        + " callerPackage is " + callerPackage);
18443            } else if (rl.pid != callingPid) {
18444                throw new IllegalArgumentException(
18445                        "Receiver requested to register for pid " + callingPid
18446                        + " was previously registered for pid " + rl.pid
18447                        + " callerPackage is " + callerPackage);
18448            } else if (rl.userId != userId) {
18449                throw new IllegalArgumentException(
18450                        "Receiver requested to register for user " + userId
18451                        + " was previously registered for user " + rl.userId
18452                        + " callerPackage is " + callerPackage);
18453            }
18454            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18455                    permission, callingUid, userId, instantApp, visibleToInstantApps);
18456            rl.add(bf);
18457            if (!bf.debugCheck()) {
18458                Slog.w(TAG, "==> For Dynamic broadcast");
18459            }
18460            mReceiverResolver.addFilter(bf);
18461
18462            // Enqueue broadcasts for all existing stickies that match
18463            // this filter.
18464            if (allSticky != null) {
18465                ArrayList receivers = new ArrayList();
18466                receivers.add(bf);
18467
18468                final int stickyCount = allSticky.size();
18469                for (int i = 0; i < stickyCount; i++) {
18470                    Intent intent = allSticky.get(i);
18471                    BroadcastQueue queue = broadcastQueueForIntent(intent);
18472                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18473                            null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18474                            null, 0, null, null, false, true, true, -1);
18475                    queue.enqueueParallelBroadcastLocked(r);
18476                    queue.scheduleBroadcastsLocked();
18477                }
18478            }
18479
18480            return sticky;
18481        }
18482    }
18483
18484    public void unregisterReceiver(IIntentReceiver receiver) {
18485        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18486
18487        final long origId = Binder.clearCallingIdentity();
18488        try {
18489            boolean doTrim = false;
18490
18491            synchronized(this) {
18492                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18493                if (rl != null) {
18494                    final BroadcastRecord r = rl.curBroadcast;
18495                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18496                        final boolean doNext = r.queue.finishReceiverLocked(
18497                                r, r.resultCode, r.resultData, r.resultExtras,
18498                                r.resultAbort, false);
18499                        if (doNext) {
18500                            doTrim = true;
18501                            r.queue.processNextBroadcast(false);
18502                        }
18503                    }
18504
18505                    if (rl.app != null) {
18506                        rl.app.receivers.remove(rl);
18507                    }
18508                    removeReceiverLocked(rl);
18509                    if (rl.linkedToDeath) {
18510                        rl.linkedToDeath = false;
18511                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
18512                    }
18513                }
18514            }
18515
18516            // If we actually concluded any broadcasts, we might now be able
18517            // to trim the recipients' apps from our working set
18518            if (doTrim) {
18519                trimApplications();
18520                return;
18521            }
18522
18523        } finally {
18524            Binder.restoreCallingIdentity(origId);
18525        }
18526    }
18527
18528    void removeReceiverLocked(ReceiverList rl) {
18529        mRegisteredReceivers.remove(rl.receiver.asBinder());
18530        for (int i = rl.size() - 1; i >= 0; i--) {
18531            mReceiverResolver.removeFilter(rl.get(i));
18532        }
18533    }
18534
18535    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18536        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18537            ProcessRecord r = mLruProcesses.get(i);
18538            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18539                try {
18540                    r.thread.dispatchPackageBroadcast(cmd, packages);
18541                } catch (RemoteException ex) {
18542                }
18543            }
18544        }
18545    }
18546
18547    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18548            int callingUid, int[] users) {
18549        // TODO: come back and remove this assumption to triage all broadcasts
18550        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18551
18552        List<ResolveInfo> receivers = null;
18553        try {
18554            HashSet<ComponentName> singleUserReceivers = null;
18555            boolean scannedFirstReceivers = false;
18556            for (int user : users) {
18557                // Skip users that have Shell restrictions, with exception of always permitted
18558                // Shell broadcasts
18559                if (callingUid == Process.SHELL_UID
18560                        && mUserController.hasUserRestriction(
18561                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18562                        && !isPermittedShellBroadcast(intent)) {
18563                    continue;
18564                }
18565                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18566                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18567                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18568                    // If this is not the system user, we need to check for
18569                    // any receivers that should be filtered out.
18570                    for (int i=0; i<newReceivers.size(); i++) {
18571                        ResolveInfo ri = newReceivers.get(i);
18572                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18573                            newReceivers.remove(i);
18574                            i--;
18575                        }
18576                    }
18577                }
18578                if (newReceivers != null && newReceivers.size() == 0) {
18579                    newReceivers = null;
18580                }
18581                if (receivers == null) {
18582                    receivers = newReceivers;
18583                } else if (newReceivers != null) {
18584                    // We need to concatenate the additional receivers
18585                    // found with what we have do far.  This would be easy,
18586                    // but we also need to de-dup any receivers that are
18587                    // singleUser.
18588                    if (!scannedFirstReceivers) {
18589                        // Collect any single user receivers we had already retrieved.
18590                        scannedFirstReceivers = true;
18591                        for (int i=0; i<receivers.size(); i++) {
18592                            ResolveInfo ri = receivers.get(i);
18593                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18594                                ComponentName cn = new ComponentName(
18595                                        ri.activityInfo.packageName, ri.activityInfo.name);
18596                                if (singleUserReceivers == null) {
18597                                    singleUserReceivers = new HashSet<ComponentName>();
18598                                }
18599                                singleUserReceivers.add(cn);
18600                            }
18601                        }
18602                    }
18603                    // Add the new results to the existing results, tracking
18604                    // and de-dupping single user receivers.
18605                    for (int i=0; i<newReceivers.size(); i++) {
18606                        ResolveInfo ri = newReceivers.get(i);
18607                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18608                            ComponentName cn = new ComponentName(
18609                                    ri.activityInfo.packageName, ri.activityInfo.name);
18610                            if (singleUserReceivers == null) {
18611                                singleUserReceivers = new HashSet<ComponentName>();
18612                            }
18613                            if (!singleUserReceivers.contains(cn)) {
18614                                singleUserReceivers.add(cn);
18615                                receivers.add(ri);
18616                            }
18617                        } else {
18618                            receivers.add(ri);
18619                        }
18620                    }
18621                }
18622            }
18623        } catch (RemoteException ex) {
18624            // pm is in same process, this will never happen.
18625        }
18626        return receivers;
18627    }
18628
18629    private boolean isPermittedShellBroadcast(Intent intent) {
18630        // remote bugreport should always be allowed to be taken
18631        return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
18632    }
18633
18634    private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
18635            String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
18636        if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
18637            // Don't yell about broadcasts sent via shell
18638            return;
18639        }
18640
18641        final String action = intent.getAction();
18642        if (isProtectedBroadcast
18643                || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
18644                || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
18645                || Intent.ACTION_MEDIA_BUTTON.equals(action)
18646                || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
18647                || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
18648                || Intent.ACTION_MASTER_CLEAR.equals(action)
18649                || Intent.ACTION_FACTORY_RESET.equals(action)
18650                || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18651                || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
18652                || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
18653                || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
18654                || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
18655                || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
18656                || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
18657            // Broadcast is either protected, or it's a public action that
18658            // we've relaxed, so it's fine for system internals to send.
18659            return;
18660        }
18661
18662        // This broadcast may be a problem...  but there are often system components that
18663        // want to send an internal broadcast to themselves, which is annoying to have to
18664        // explicitly list each action as a protected broadcast, so we will check for that
18665        // one safe case and allow it: an explicit broadcast, only being received by something
18666        // that has protected itself.
18667        if (receivers != null && receivers.size() > 0
18668                && (intent.getPackage() != null || intent.getComponent() != null)) {
18669            boolean allProtected = true;
18670            for (int i = receivers.size()-1; i >= 0; i--) {
18671                Object target = receivers.get(i);
18672                if (target instanceof ResolveInfo) {
18673                    ResolveInfo ri = (ResolveInfo)target;
18674                    if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
18675                        allProtected = false;
18676                        break;
18677                    }
18678                } else {
18679                    BroadcastFilter bf = (BroadcastFilter)target;
18680                    if (bf.requiredPermission == null) {
18681                        allProtected = false;
18682                        break;
18683                    }
18684                }
18685            }
18686            if (allProtected) {
18687                // All safe!
18688                return;
18689            }
18690        }
18691
18692        // The vast majority of broadcasts sent from system internals
18693        // should be protected to avoid security holes, so yell loudly
18694        // to ensure we examine these cases.
18695        if (callerApp != null) {
18696            Log.wtf(TAG, "Sending non-protected broadcast " + action
18697                            + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
18698                    new Throwable());
18699        } else {
18700            Log.wtf(TAG, "Sending non-protected broadcast " + action
18701                            + " from system uid " + UserHandle.formatUid(callingUid)
18702                            + " pkg " + callerPackage,
18703                    new Throwable());
18704        }
18705    }
18706
18707    final int broadcastIntentLocked(ProcessRecord callerApp,
18708            String callerPackage, Intent intent, String resolvedType,
18709            IIntentReceiver resultTo, int resultCode, String resultData,
18710            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
18711            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
18712        intent = new Intent(intent);
18713
18714        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
18715        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
18716        if (callerInstantApp) {
18717            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
18718        }
18719
18720        // By default broadcasts do not go to stopped apps.
18721        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
18722
18723        // If we have not finished booting, don't allow this to launch new processes.
18724        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
18725            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18726        }
18727
18728        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
18729                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
18730                + " ordered=" + ordered + " userid=" + userId);
18731        if ((resultTo != null) && !ordered) {
18732            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
18733        }
18734
18735        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18736                ALLOW_NON_FULL, "broadcast", callerPackage);
18737
18738        // Make sure that the user who is receiving this broadcast is running.
18739        // If not, we will just skip it. Make an exception for shutdown broadcasts
18740        // and upgrade steps.
18741
18742        if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
18743            if ((callingUid != Process.SYSTEM_UID
18744                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
18745                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
18746                Slog.w(TAG, "Skipping broadcast of " + intent
18747                        + ": user " + userId + " is stopped");
18748                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
18749            }
18750        }
18751
18752        BroadcastOptions brOptions = null;
18753        if (bOptions != null) {
18754            brOptions = new BroadcastOptions(bOptions);
18755            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
18756                // See if the caller is allowed to do this.  Note we are checking against
18757                // the actual real caller (not whoever provided the operation as say a
18758                // PendingIntent), because that who is actually supplied the arguments.
18759                if (checkComponentPermission(
18760                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
18761                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
18762                        != PackageManager.PERMISSION_GRANTED) {
18763                    String msg = "Permission Denial: " + intent.getAction()
18764                            + " broadcast from " + callerPackage + " (pid=" + callingPid
18765                            + ", uid=" + callingUid + ")"
18766                            + " requires "
18767                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
18768                    Slog.w(TAG, msg);
18769                    throw new SecurityException(msg);
18770                }
18771            }
18772        }
18773
18774        // Verify that protected broadcasts are only being sent by system code,
18775        // and that system code is only sending protected broadcasts.
18776        final String action = intent.getAction();
18777        final boolean isProtectedBroadcast;
18778        try {
18779            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18780        } catch (RemoteException e) {
18781            Slog.w(TAG, "Remote exception", e);
18782            return ActivityManager.BROADCAST_SUCCESS;
18783        }
18784
18785        final boolean isCallerSystem;
18786        switch (UserHandle.getAppId(callingUid)) {
18787            case Process.ROOT_UID:
18788            case Process.SYSTEM_UID:
18789            case Process.PHONE_UID:
18790            case Process.BLUETOOTH_UID:
18791            case Process.NFC_UID:
18792                isCallerSystem = true;
18793                break;
18794            default:
18795                isCallerSystem = (callerApp != null) && callerApp.persistent;
18796                break;
18797        }
18798
18799        // First line security check before anything else: stop non-system apps from
18800        // sending protected broadcasts.
18801        if (!isCallerSystem) {
18802            if (isProtectedBroadcast) {
18803                String msg = "Permission Denial: not allowed to send broadcast "
18804                        + action + " from pid="
18805                        + callingPid + ", uid=" + callingUid;
18806                Slog.w(TAG, msg);
18807                throw new SecurityException(msg);
18808
18809            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18810                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18811                // Special case for compatibility: we don't want apps to send this,
18812                // but historically it has not been protected and apps may be using it
18813                // to poke their own app widget.  So, instead of making it protected,
18814                // just limit it to the caller.
18815                if (callerPackage == null) {
18816                    String msg = "Permission Denial: not allowed to send broadcast "
18817                            + action + " from unknown caller.";
18818                    Slog.w(TAG, msg);
18819                    throw new SecurityException(msg);
18820                } else if (intent.getComponent() != null) {
18821                    // They are good enough to send to an explicit component...  verify
18822                    // it is being sent to the calling app.
18823                    if (!intent.getComponent().getPackageName().equals(
18824                            callerPackage)) {
18825                        String msg = "Permission Denial: not allowed to send broadcast "
18826                                + action + " to "
18827                                + intent.getComponent().getPackageName() + " from "
18828                                + callerPackage;
18829                        Slog.w(TAG, msg);
18830                        throw new SecurityException(msg);
18831                    }
18832                } else {
18833                    // Limit broadcast to their own package.
18834                    intent.setPackage(callerPackage);
18835                }
18836            }
18837        }
18838
18839        if (action != null) {
18840            if (getBackgroundLaunchBroadcasts().contains(action)) {
18841                if (DEBUG_BACKGROUND_CHECK) {
18842                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
18843                }
18844                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
18845            }
18846
18847            switch (action) {
18848                case Intent.ACTION_UID_REMOVED:
18849                case Intent.ACTION_PACKAGE_REMOVED:
18850                case Intent.ACTION_PACKAGE_CHANGED:
18851                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18852                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18853                case Intent.ACTION_PACKAGES_SUSPENDED:
18854                case Intent.ACTION_PACKAGES_UNSUSPENDED:
18855                    // Handle special intents: if this broadcast is from the package
18856                    // manager about a package being removed, we need to remove all of
18857                    // its activities from the history stack.
18858                    if (checkComponentPermission(
18859                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18860                            callingPid, callingUid, -1, true)
18861                            != PackageManager.PERMISSION_GRANTED) {
18862                        String msg = "Permission Denial: " + intent.getAction()
18863                                + " broadcast from " + callerPackage + " (pid=" + callingPid
18864                                + ", uid=" + callingUid + ")"
18865                                + " requires "
18866                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18867                        Slog.w(TAG, msg);
18868                        throw new SecurityException(msg);
18869                    }
18870                    switch (action) {
18871                        case Intent.ACTION_UID_REMOVED:
18872                            final Bundle intentExtras = intent.getExtras();
18873                            final int uid = intentExtras != null
18874                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18875                            if (uid >= 0) {
18876                                mBatteryStatsService.removeUid(uid);
18877                                mAppOpsService.uidRemoved(uid);
18878                            }
18879                            break;
18880                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18881                            // If resources are unavailable just force stop all those packages
18882                            // and flush the attribute cache as well.
18883                            String list[] =
18884                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18885                            if (list != null && list.length > 0) {
18886                                for (int i = 0; i < list.length; i++) {
18887                                    forceStopPackageLocked(list[i], -1, false, true, true,
18888                                            false, false, userId, "storage unmount");
18889                                }
18890                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18891                                sendPackageBroadcastLocked(
18892                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
18893                                        list, userId);
18894                            }
18895                            break;
18896                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18897                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18898                            break;
18899                        case Intent.ACTION_PACKAGE_REMOVED:
18900                        case Intent.ACTION_PACKAGE_CHANGED:
18901                            Uri data = intent.getData();
18902                            String ssp;
18903                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18904                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18905                                final boolean replacing =
18906                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18907                                final boolean killProcess =
18908                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18909                                final boolean fullUninstall = removed && !replacing;
18910                                if (removed) {
18911                                    if (killProcess) {
18912                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
18913                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18914                                                false, true, true, false, fullUninstall, userId,
18915                                                removed ? "pkg removed" : "pkg changed");
18916                                    }
18917                                    final int cmd = killProcess
18918                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
18919                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
18920                                    sendPackageBroadcastLocked(cmd,
18921                                            new String[] {ssp}, userId);
18922                                    if (fullUninstall) {
18923                                        mAppOpsService.packageRemoved(
18924                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18925
18926                                        // Remove all permissions granted from/to this package
18927                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
18928
18929                                        removeTasksByPackageNameLocked(ssp, userId);
18930
18931                                        // Hide the "unsupported display" dialog if necessary.
18932                                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18933                                                mUnsupportedDisplaySizeDialog.getPackageName())) {
18934                                            mUnsupportedDisplaySizeDialog.dismiss();
18935                                            mUnsupportedDisplaySizeDialog = null;
18936                                        }
18937                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
18938                                        mBatteryStatsService.notePackageUninstalled(ssp);
18939                                    }
18940                                } else {
18941                                    if (killProcess) {
18942                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
18943                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
18944                                                userId, ProcessList.INVALID_ADJ,
18945                                                false, true, true, false, "change " + ssp);
18946                                    }
18947                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18948                                            intent.getStringArrayExtra(
18949                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18950                                }
18951                            }
18952                            break;
18953                        case Intent.ACTION_PACKAGES_SUSPENDED:
18954                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
18955                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18956                                    intent.getAction());
18957                            final String[] packageNames = intent.getStringArrayExtra(
18958                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
18959                            final int userHandle = intent.getIntExtra(
18960                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18961
18962                            synchronized(ActivityManagerService.this) {
18963                                mRecentTasks.onPackagesSuspendedChanged(
18964                                        packageNames, suspended, userHandle);
18965                            }
18966                            break;
18967                    }
18968                    break;
18969                case Intent.ACTION_PACKAGE_REPLACED:
18970                {
18971                    final Uri data = intent.getData();
18972                    final String ssp;
18973                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18974                        final ApplicationInfo aInfo =
18975                                getPackageManagerInternalLocked().getApplicationInfo(
18976                                        ssp,
18977                                        userId);
18978                        if (aInfo == null) {
18979                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18980                                    + " ssp=" + ssp + " data=" + data);
18981                            return ActivityManager.BROADCAST_SUCCESS;
18982                        }
18983                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18984                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
18985                                new String[] {ssp}, userId);
18986                    }
18987                    break;
18988                }
18989                case Intent.ACTION_PACKAGE_ADDED:
18990                {
18991                    // Special case for adding a package: by default turn on compatibility mode.
18992                    Uri data = intent.getData();
18993                    String ssp;
18994                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18995                        final boolean replacing =
18996                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18997                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18998
18999                        try {
19000                            ApplicationInfo ai = AppGlobals.getPackageManager().
19001                                    getApplicationInfo(ssp, 0, 0);
19002                            mBatteryStatsService.notePackageInstalled(ssp,
19003                                    ai != null ? ai.versionCode : 0);
19004                        } catch (RemoteException e) {
19005                        }
19006                    }
19007                    break;
19008                }
19009                case Intent.ACTION_PACKAGE_DATA_CLEARED:
19010                {
19011                    Uri data = intent.getData();
19012                    String ssp;
19013                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19014                        // Hide the "unsupported display" dialog if necessary.
19015                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19016                                mUnsupportedDisplaySizeDialog.getPackageName())) {
19017                            mUnsupportedDisplaySizeDialog.dismiss();
19018                            mUnsupportedDisplaySizeDialog = null;
19019                        }
19020                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
19021                    }
19022                    break;
19023                }
19024                case Intent.ACTION_TIMEZONE_CHANGED:
19025                    // If this is the time zone changed action, queue up a message that will reset
19026                    // the timezone of all currently running processes. This message will get
19027                    // queued up before the broadcast happens.
19028                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19029                    break;
19030                case Intent.ACTION_TIME_CHANGED:
19031                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19032                    // the tri-state value it may contain and "unknown".
19033                    // For convenience we re-use the Intent extra values.
19034                    final int NO_EXTRA_VALUE_FOUND = -1;
19035                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19036                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19037                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
19038                    // Only send a message if the time preference is available.
19039                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19040                        Message updateTimePreferenceMsg =
19041                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19042                                        timeFormatPreferenceMsgValue, 0);
19043                        mHandler.sendMessage(updateTimePreferenceMsg);
19044                    }
19045                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19046                    synchronized (stats) {
19047                        stats.noteCurrentTimeChangedLocked();
19048                    }
19049                    break;
19050                case Intent.ACTION_CLEAR_DNS_CACHE:
19051                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19052                    break;
19053                case Proxy.PROXY_CHANGE_ACTION:
19054                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19055                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19056                    break;
19057                case android.hardware.Camera.ACTION_NEW_PICTURE:
19058                case android.hardware.Camera.ACTION_NEW_VIDEO:
19059                    // In N we just turned these off; in O we are turing them back on partly,
19060                    // only for registered receivers.  This will still address the main problem
19061                    // (a spam of apps waking up when a picture is taken putting significant
19062                    // memory pressure on the system at a bad point), while still allowing apps
19063                    // that are already actively running to know about this happening.
19064                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19065                    break;
19066                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19067                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19068                    break;
19069            }
19070        }
19071
19072        // Add to the sticky list if requested.
19073        if (sticky) {
19074            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19075                    callingPid, callingUid)
19076                    != PackageManager.PERMISSION_GRANTED) {
19077                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19078                        + callingPid + ", uid=" + callingUid
19079                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19080                Slog.w(TAG, msg);
19081                throw new SecurityException(msg);
19082            }
19083            if (requiredPermissions != null && requiredPermissions.length > 0) {
19084                Slog.w(TAG, "Can't broadcast sticky intent " + intent
19085                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
19086                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19087            }
19088            if (intent.getComponent() != null) {
19089                throw new SecurityException(
19090                        "Sticky broadcasts can't target a specific component");
19091            }
19092            // We use userId directly here, since the "all" target is maintained
19093            // as a separate set of sticky broadcasts.
19094            if (userId != UserHandle.USER_ALL) {
19095                // But first, if this is not a broadcast to all users, then
19096                // make sure it doesn't conflict with an existing broadcast to
19097                // all users.
19098                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19099                        UserHandle.USER_ALL);
19100                if (stickies != null) {
19101                    ArrayList<Intent> list = stickies.get(intent.getAction());
19102                    if (list != null) {
19103                        int N = list.size();
19104                        int i;
19105                        for (i=0; i<N; i++) {
19106                            if (intent.filterEquals(list.get(i))) {
19107                                throw new IllegalArgumentException(
19108                                        "Sticky broadcast " + intent + " for user "
19109                                        + userId + " conflicts with existing global broadcast");
19110                            }
19111                        }
19112                    }
19113                }
19114            }
19115            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19116            if (stickies == null) {
19117                stickies = new ArrayMap<>();
19118                mStickyBroadcasts.put(userId, stickies);
19119            }
19120            ArrayList<Intent> list = stickies.get(intent.getAction());
19121            if (list == null) {
19122                list = new ArrayList<>();
19123                stickies.put(intent.getAction(), list);
19124            }
19125            final int stickiesCount = list.size();
19126            int i;
19127            for (i = 0; i < stickiesCount; i++) {
19128                if (intent.filterEquals(list.get(i))) {
19129                    // This sticky already exists, replace it.
19130                    list.set(i, new Intent(intent));
19131                    break;
19132                }
19133            }
19134            if (i >= stickiesCount) {
19135                list.add(new Intent(intent));
19136            }
19137        }
19138
19139        int[] users;
19140        if (userId == UserHandle.USER_ALL) {
19141            // Caller wants broadcast to go to all started users.
19142            users = mUserController.getStartedUserArrayLocked();
19143        } else {
19144            // Caller wants broadcast to go to one specific user.
19145            users = new int[] {userId};
19146        }
19147
19148        // Figure out who all will receive this broadcast.
19149        List receivers = null;
19150        List<BroadcastFilter> registeredReceivers = null;
19151        // Need to resolve the intent to interested receivers...
19152        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19153                 == 0) {
19154            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19155        }
19156        if (intent.getComponent() == null) {
19157            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
19158                // Query one target user at a time, excluding shell-restricted users
19159                for (int i = 0; i < users.length; i++) {
19160                    if (mUserController.hasUserRestriction(
19161                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19162                        continue;
19163                    }
19164                    List<BroadcastFilter> registeredReceiversForUser =
19165                            mReceiverResolver.queryIntent(intent,
19166                                    resolvedType, false /*defaultOnly*/, users[i]);
19167                    if (registeredReceivers == null) {
19168                        registeredReceivers = registeredReceiversForUser;
19169                    } else if (registeredReceiversForUser != null) {
19170                        registeredReceivers.addAll(registeredReceiversForUser);
19171                    }
19172                }
19173            } else {
19174                registeredReceivers = mReceiverResolver.queryIntent(intent,
19175                        resolvedType, false /*defaultOnly*/, userId);
19176            }
19177        }
19178
19179        final boolean replacePending =
19180                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19181
19182        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19183                + " replacePending=" + replacePending);
19184
19185        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19186        if (!ordered && NR > 0) {
19187            // If we are not serializing this broadcast, then send the
19188            // registered receivers separately so they don't wait for the
19189            // components to be launched.
19190            if (isCallerSystem) {
19191                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19192                        isProtectedBroadcast, registeredReceivers);
19193            }
19194            final BroadcastQueue queue = broadcastQueueForIntent(intent);
19195            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19196                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19197                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19198                    resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19199            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19200            final boolean replaced = replacePending
19201                    && (queue.replaceParallelBroadcastLocked(r) != null);
19202            // Note: We assume resultTo is null for non-ordered broadcasts.
19203            if (!replaced) {
19204                queue.enqueueParallelBroadcastLocked(r);
19205                queue.scheduleBroadcastsLocked();
19206            }
19207            registeredReceivers = null;
19208            NR = 0;
19209        }
19210
19211        // Merge into one list.
19212        int ir = 0;
19213        if (receivers != null) {
19214            // A special case for PACKAGE_ADDED: do not allow the package
19215            // being added to see this broadcast.  This prevents them from
19216            // using this as a back door to get run as soon as they are
19217            // installed.  Maybe in the future we want to have a special install
19218            // broadcast or such for apps, but we'd like to deliberately make
19219            // this decision.
19220            String skipPackages[] = null;
19221            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19222                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19223                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19224                Uri data = intent.getData();
19225                if (data != null) {
19226                    String pkgName = data.getSchemeSpecificPart();
19227                    if (pkgName != null) {
19228                        skipPackages = new String[] { pkgName };
19229                    }
19230                }
19231            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19232                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19233            }
19234            if (skipPackages != null && (skipPackages.length > 0)) {
19235                for (String skipPackage : skipPackages) {
19236                    if (skipPackage != null) {
19237                        int NT = receivers.size();
19238                        for (int it=0; it<NT; it++) {
19239                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
19240                            if (curt.activityInfo.packageName.equals(skipPackage)) {
19241                                receivers.remove(it);
19242                                it--;
19243                                NT--;
19244                            }
19245                        }
19246                    }
19247                }
19248            }
19249
19250            int NT = receivers != null ? receivers.size() : 0;
19251            int it = 0;
19252            ResolveInfo curt = null;
19253            BroadcastFilter curr = null;
19254            while (it < NT && ir < NR) {
19255                if (curt == null) {
19256                    curt = (ResolveInfo)receivers.get(it);
19257                }
19258                if (curr == null) {
19259                    curr = registeredReceivers.get(ir);
19260                }
19261                if (curr.getPriority() >= curt.priority) {
19262                    // Insert this broadcast record into the final list.
19263                    receivers.add(it, curr);
19264                    ir++;
19265                    curr = null;
19266                    it++;
19267                    NT++;
19268                } else {
19269                    // Skip to the next ResolveInfo in the final list.
19270                    it++;
19271                    curt = null;
19272                }
19273            }
19274        }
19275        while (ir < NR) {
19276            if (receivers == null) {
19277                receivers = new ArrayList();
19278            }
19279            receivers.add(registeredReceivers.get(ir));
19280            ir++;
19281        }
19282
19283        if (isCallerSystem) {
19284            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19285                    isProtectedBroadcast, receivers);
19286        }
19287
19288        if ((receivers != null && receivers.size() > 0)
19289                || resultTo != null) {
19290            BroadcastQueue queue = broadcastQueueForIntent(intent);
19291            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19292                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19293                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19294                    resultData, resultExtras, ordered, sticky, false, userId);
19295
19296            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19297                    + ": prev had " + queue.mOrderedBroadcasts.size());
19298            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19299                    "Enqueueing broadcast " + r.intent.getAction());
19300
19301            final BroadcastRecord oldRecord =
19302                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19303            if (oldRecord != null) {
19304                // Replaced, fire the result-to receiver.
19305                if (oldRecord.resultTo != null) {
19306                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19307                    try {
19308                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19309                                oldRecord.intent,
19310                                Activity.RESULT_CANCELED, null, null,
19311                                false, false, oldRecord.userId);
19312                    } catch (RemoteException e) {
19313                        Slog.w(TAG, "Failure ["
19314                                + queue.mQueueName + "] sending broadcast result of "
19315                                + intent, e);
19316
19317                    }
19318                }
19319            } else {
19320                queue.enqueueOrderedBroadcastLocked(r);
19321                queue.scheduleBroadcastsLocked();
19322            }
19323        } else {
19324            // There was nobody interested in the broadcast, but we still want to record
19325            // that it happened.
19326            if (intent.getComponent() == null && intent.getPackage() == null
19327                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19328                // This was an implicit broadcast... let's record it for posterity.
19329                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19330            }
19331        }
19332
19333        return ActivityManager.BROADCAST_SUCCESS;
19334    }
19335
19336    final void rotateBroadcastStatsIfNeededLocked() {
19337        final long now = SystemClock.elapsedRealtime();
19338        if (mCurBroadcastStats == null ||
19339                (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19340            mLastBroadcastStats = mCurBroadcastStats;
19341            if (mLastBroadcastStats != null) {
19342                mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19343                mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19344            }
19345            mCurBroadcastStats = new BroadcastStats();
19346        }
19347    }
19348
19349    final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19350            int skipCount, long dispatchTime) {
19351        rotateBroadcastStatsIfNeededLocked();
19352        mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19353    }
19354
19355    final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19356        rotateBroadcastStatsIfNeededLocked();
19357        mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19358    }
19359
19360    final Intent verifyBroadcastLocked(Intent intent) {
19361        // Refuse possible leaked file descriptors
19362        if (intent != null && intent.hasFileDescriptors() == true) {
19363            throw new IllegalArgumentException("File descriptors passed in Intent");
19364        }
19365
19366        int flags = intent.getFlags();
19367
19368        if (!mProcessesReady) {
19369            // if the caller really truly claims to know what they're doing, go
19370            // ahead and allow the broadcast without launching any receivers
19371            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19372                // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19373            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19374                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19375                        + " before boot completion");
19376                throw new IllegalStateException("Cannot broadcast before boot completed");
19377            }
19378        }
19379
19380        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19381            throw new IllegalArgumentException(
19382                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19383        }
19384
19385        if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19386            switch (Binder.getCallingUid()) {
19387                case Process.ROOT_UID:
19388                case Process.SHELL_UID:
19389                    break;
19390                default:
19391                    Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19392                            + Binder.getCallingUid());
19393                    intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19394                    break;
19395            }
19396        }
19397
19398        return intent;
19399    }
19400
19401    public final int broadcastIntent(IApplicationThread caller,
19402            Intent intent, String resolvedType, IIntentReceiver resultTo,
19403            int resultCode, String resultData, Bundle resultExtras,
19404            String[] requiredPermissions, int appOp, Bundle bOptions,
19405            boolean serialized, boolean sticky, int userId) {
19406        enforceNotIsolatedCaller("broadcastIntent");
19407        synchronized(this) {
19408            intent = verifyBroadcastLocked(intent);
19409
19410            final ProcessRecord callerApp = getRecordForAppLocked(caller);
19411            final int callingPid = Binder.getCallingPid();
19412            final int callingUid = Binder.getCallingUid();
19413            final long origId = Binder.clearCallingIdentity();
19414            int res = broadcastIntentLocked(callerApp,
19415                    callerApp != null ? callerApp.info.packageName : null,
19416                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19417                    requiredPermissions, appOp, bOptions, serialized, sticky,
19418                    callingPid, callingUid, userId);
19419            Binder.restoreCallingIdentity(origId);
19420            return res;
19421        }
19422    }
19423
19424
19425    int broadcastIntentInPackage(String packageName, int uid,
19426            Intent intent, String resolvedType, IIntentReceiver resultTo,
19427            int resultCode, String resultData, Bundle resultExtras,
19428            String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19429            int userId) {
19430        synchronized(this) {
19431            intent = verifyBroadcastLocked(intent);
19432
19433            final long origId = Binder.clearCallingIdentity();
19434            String[] requiredPermissions = requiredPermission == null ? null
19435                    : new String[] {requiredPermission};
19436            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19437                    resultTo, resultCode, resultData, resultExtras,
19438                    requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19439                    sticky, -1, uid, userId);
19440            Binder.restoreCallingIdentity(origId);
19441            return res;
19442        }
19443    }
19444
19445    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19446        // Refuse possible leaked file descriptors
19447        if (intent != null && intent.hasFileDescriptors() == true) {
19448            throw new IllegalArgumentException("File descriptors passed in Intent");
19449        }
19450
19451        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19452                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19453
19454        synchronized(this) {
19455            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19456                    != PackageManager.PERMISSION_GRANTED) {
19457                String msg = "Permission Denial: unbroadcastIntent() from pid="
19458                        + Binder.getCallingPid()
19459                        + ", uid=" + Binder.getCallingUid()
19460                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19461                Slog.w(TAG, msg);
19462                throw new SecurityException(msg);
19463            }
19464            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19465            if (stickies != null) {
19466                ArrayList<Intent> list = stickies.get(intent.getAction());
19467                if (list != null) {
19468                    int N = list.size();
19469                    int i;
19470                    for (i=0; i<N; i++) {
19471                        if (intent.filterEquals(list.get(i))) {
19472                            list.remove(i);
19473                            break;
19474                        }
19475                    }
19476                    if (list.size() <= 0) {
19477                        stickies.remove(intent.getAction());
19478                    }
19479                }
19480                if (stickies.size() <= 0) {
19481                    mStickyBroadcasts.remove(userId);
19482                }
19483            }
19484        }
19485    }
19486
19487    void backgroundServicesFinishedLocked(int userId) {
19488        for (BroadcastQueue queue : mBroadcastQueues) {
19489            queue.backgroundServicesFinishedLocked(userId);
19490        }
19491    }
19492
19493    public void finishReceiver(IBinder who, int resultCode, String resultData,
19494            Bundle resultExtras, boolean resultAbort, int flags) {
19495        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19496
19497        // Refuse possible leaked file descriptors
19498        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19499            throw new IllegalArgumentException("File descriptors passed in Bundle");
19500        }
19501
19502        final long origId = Binder.clearCallingIdentity();
19503        try {
19504            boolean doNext = false;
19505            BroadcastRecord r;
19506
19507            synchronized(this) {
19508                BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19509                        ? mFgBroadcastQueue : mBgBroadcastQueue;
19510                r = queue.getMatchingOrderedReceiver(who);
19511                if (r != null) {
19512                    doNext = r.queue.finishReceiverLocked(r, resultCode,
19513                        resultData, resultExtras, resultAbort, true);
19514                }
19515            }
19516
19517            if (doNext) {
19518                r.queue.processNextBroadcast(false);
19519            }
19520            trimApplications();
19521        } finally {
19522            Binder.restoreCallingIdentity(origId);
19523        }
19524    }
19525
19526    // =========================================================
19527    // INSTRUMENTATION
19528    // =========================================================
19529
19530    public boolean startInstrumentation(ComponentName className,
19531            String profileFile, int flags, Bundle arguments,
19532            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19533            int userId, String abiOverride) {
19534        enforceNotIsolatedCaller("startInstrumentation");
19535        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19536                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19537        // Refuse possible leaked file descriptors
19538        if (arguments != null && arguments.hasFileDescriptors()) {
19539            throw new IllegalArgumentException("File descriptors passed in Bundle");
19540        }
19541
19542        synchronized(this) {
19543            InstrumentationInfo ii = null;
19544            ApplicationInfo ai = null;
19545            try {
19546                ii = mContext.getPackageManager().getInstrumentationInfo(
19547                    className, STOCK_PM_FLAGS);
19548                ai = AppGlobals.getPackageManager().getApplicationInfo(
19549                        ii.targetPackage, STOCK_PM_FLAGS, userId);
19550            } catch (PackageManager.NameNotFoundException e) {
19551            } catch (RemoteException e) {
19552            }
19553            if (ii == null) {
19554                reportStartInstrumentationFailureLocked(watcher, className,
19555                        "Unable to find instrumentation info for: " + className);
19556                return false;
19557            }
19558            if (ai == null) {
19559                reportStartInstrumentationFailureLocked(watcher, className,
19560                        "Unable to find instrumentation target package: " + ii.targetPackage);
19561                return false;
19562            }
19563            if (!ai.hasCode()) {
19564                reportStartInstrumentationFailureLocked(watcher, className,
19565                        "Instrumentation target has no code: " + ii.targetPackage);
19566                return false;
19567            }
19568
19569            int match = mContext.getPackageManager().checkSignatures(
19570                    ii.targetPackage, ii.packageName);
19571            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19572                String msg = "Permission Denial: starting instrumentation "
19573                        + className + " from pid="
19574                        + Binder.getCallingPid()
19575                        + ", uid=" + Binder.getCallingPid()
19576                        + " not allowed because package " + ii.packageName
19577                        + " does not have a signature matching the target "
19578                        + ii.targetPackage;
19579                reportStartInstrumentationFailureLocked(watcher, className, msg);
19580                throw new SecurityException(msg);
19581            }
19582
19583            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
19584            activeInstr.mClass = className;
19585            String defProcess = ai.processName;;
19586            if (ii.targetProcess == null) {
19587                activeInstr.mTargetProcesses = new String[]{ai.processName};
19588            } else if (ii.targetProcess.equals("*")) {
19589                activeInstr.mTargetProcesses = new String[0];
19590            } else {
19591                activeInstr.mTargetProcesses = ii.targetProcess.split(",");
19592                defProcess = activeInstr.mTargetProcesses[0];
19593            }
19594            activeInstr.mTargetInfo = ai;
19595            activeInstr.mProfileFile = profileFile;
19596            activeInstr.mArguments = arguments;
19597            activeInstr.mWatcher = watcher;
19598            activeInstr.mUiAutomationConnection = uiAutomationConnection;
19599            activeInstr.mResultClass = className;
19600
19601            final long origId = Binder.clearCallingIdentity();
19602            // Instrumentation can kill and relaunch even persistent processes
19603            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
19604                    "start instr");
19605            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
19606            app.instr = activeInstr;
19607            activeInstr.mFinished = false;
19608            activeInstr.mRunningProcesses.add(app);
19609            if (!mActiveInstrumentation.contains(activeInstr)) {
19610                mActiveInstrumentation.add(activeInstr);
19611            }
19612            Binder.restoreCallingIdentity(origId);
19613        }
19614
19615        return true;
19616    }
19617
19618    /**
19619     * Report errors that occur while attempting to start Instrumentation.  Always writes the
19620     * error to the logs, but if somebody is watching, send the report there too.  This enables
19621     * the "am" command to report errors with more information.
19622     *
19623     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
19624     * @param cn The component name of the instrumentation.
19625     * @param report The error report.
19626     */
19627    private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
19628            ComponentName cn, String report) {
19629        Slog.w(TAG, report);
19630        if (watcher != null) {
19631            Bundle results = new Bundle();
19632            results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
19633            results.putString("Error", report);
19634            mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
19635        }
19636    }
19637
19638    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
19639        if (app.instr == null) {
19640            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19641            return;
19642        }
19643
19644        if (!app.instr.mFinished && results != null) {
19645            if (app.instr.mCurResults == null) {
19646                app.instr.mCurResults = new Bundle(results);
19647            } else {
19648                app.instr.mCurResults.putAll(results);
19649            }
19650        }
19651    }
19652
19653    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
19654        int userId = UserHandle.getCallingUserId();
19655        // Refuse possible leaked file descriptors
19656        if (results != null && results.hasFileDescriptors()) {
19657            throw new IllegalArgumentException("File descriptors passed in Intent");
19658        }
19659
19660        synchronized(this) {
19661            ProcessRecord app = getRecordForAppLocked(target);
19662            if (app == null) {
19663                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
19664                return;
19665            }
19666            final long origId = Binder.clearCallingIdentity();
19667            addInstrumentationResultsLocked(app, results);
19668            Binder.restoreCallingIdentity(origId);
19669        }
19670    }
19671
19672    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
19673        if (app.instr == null) {
19674            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
19675            return;
19676        }
19677
19678        if (!app.instr.mFinished) {
19679            if (app.instr.mWatcher != null) {
19680                Bundle finalResults = app.instr.mCurResults;
19681                if (finalResults != null) {
19682                    if (app.instr.mCurResults != null && results != null) {
19683                        finalResults.putAll(results);
19684                    }
19685                } else {
19686                    finalResults = results;
19687                }
19688                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
19689                        app.instr.mClass, resultCode, finalResults);
19690            }
19691
19692            // Can't call out of the system process with a lock held, so post a message.
19693            if (app.instr.mUiAutomationConnection != null) {
19694                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
19695                        app.instr.mUiAutomationConnection).sendToTarget();
19696            }
19697            app.instr.mFinished = true;
19698        }
19699
19700        app.instr.removeProcess(app);
19701        app.instr = null;
19702
19703        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
19704                "finished inst");
19705    }
19706
19707    public void finishInstrumentation(IApplicationThread target,
19708            int resultCode, Bundle results) {
19709        int userId = UserHandle.getCallingUserId();
19710        // Refuse possible leaked file descriptors
19711        if (results != null && results.hasFileDescriptors()) {
19712            throw new IllegalArgumentException("File descriptors passed in Intent");
19713        }
19714
19715        synchronized(this) {
19716            ProcessRecord app = getRecordForAppLocked(target);
19717            if (app == null) {
19718                Slog.w(TAG, "finishInstrumentation: no app for " + target);
19719                return;
19720            }
19721            final long origId = Binder.clearCallingIdentity();
19722            finishInstrumentationLocked(app, resultCode, results);
19723            Binder.restoreCallingIdentity(origId);
19724        }
19725    }
19726
19727    // =========================================================
19728    // CONFIGURATION
19729    // =========================================================
19730
19731    public ConfigurationInfo getDeviceConfigurationInfo() {
19732        ConfigurationInfo config = new ConfigurationInfo();
19733        synchronized (this) {
19734            final Configuration globalConfig = getGlobalConfiguration();
19735            config.reqTouchScreen = globalConfig.touchscreen;
19736            config.reqKeyboardType = globalConfig.keyboard;
19737            config.reqNavigation = globalConfig.navigation;
19738            if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
19739                    || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
19740                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
19741            }
19742            if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
19743                    && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
19744                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
19745            }
19746            config.reqGlEsVersion = GL_ES_VERSION;
19747        }
19748        return config;
19749    }
19750
19751    ActivityStack getFocusedStack() {
19752        return mStackSupervisor.getFocusedStack();
19753    }
19754
19755    @Override
19756    public int getFocusedStackId() throws RemoteException {
19757        ActivityStack focusedStack = getFocusedStack();
19758        if (focusedStack != null) {
19759            return focusedStack.getStackId();
19760        }
19761        return -1;
19762    }
19763
19764    public Configuration getConfiguration() {
19765        Configuration ci;
19766        synchronized(this) {
19767            ci = new Configuration(getGlobalConfiguration());
19768            ci.userSetLocale = false;
19769        }
19770        return ci;
19771    }
19772
19773    @Override
19774    public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
19775        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
19776        synchronized (this) {
19777            mSuppressResizeConfigChanges = suppress;
19778        }
19779    }
19780
19781    @Override
19782    public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
19783        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
19784        if (StackId.isHomeOrRecentsStack(fromStackId)) {
19785            throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
19786        }
19787        synchronized (this) {
19788            final long origId = Binder.clearCallingIdentity();
19789            try {
19790                mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
19791            } finally {
19792                Binder.restoreCallingIdentity(origId);
19793            }
19794        }
19795    }
19796
19797    @Override
19798    public void updatePersistentConfiguration(Configuration values) {
19799        enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
19800        enforceWriteSettingsPermission("updatePersistentConfiguration()");
19801        if (values == null) {
19802            throw new NullPointerException("Configuration must not be null");
19803        }
19804
19805        int userId = UserHandle.getCallingUserId();
19806
19807        synchronized(this) {
19808            updatePersistentConfigurationLocked(values, userId);
19809        }
19810    }
19811
19812    private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
19813        final long origId = Binder.clearCallingIdentity();
19814        try {
19815            updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
19816        } finally {
19817            Binder.restoreCallingIdentity(origId);
19818        }
19819    }
19820
19821    private void updateFontScaleIfNeeded(@UserIdInt int userId) {
19822        final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
19823                FONT_SCALE, 1.0f, userId);
19824
19825        synchronized (this) {
19826            if (getGlobalConfiguration().fontScale == scaleFactor) {
19827                return;
19828            }
19829
19830            final Configuration configuration
19831                    = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19832            configuration.fontScale = scaleFactor;
19833            updatePersistentConfigurationLocked(configuration, userId);
19834        }
19835    }
19836
19837    private void enforceWriteSettingsPermission(String func) {
19838        int uid = Binder.getCallingUid();
19839        if (uid == Process.ROOT_UID) {
19840            return;
19841        }
19842
19843        if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
19844                Settings.getPackageNameForUid(mContext, uid), false)) {
19845            return;
19846        }
19847
19848        String msg = "Permission Denial: " + func + " from pid="
19849                + Binder.getCallingPid()
19850                + ", uid=" + uid
19851                + " requires " + android.Manifest.permission.WRITE_SETTINGS;
19852        Slog.w(TAG, msg);
19853        throw new SecurityException(msg);
19854    }
19855
19856    @Override
19857    public boolean updateConfiguration(Configuration values) {
19858        enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
19859
19860        synchronized(this) {
19861            if (values == null && mWindowManager != null) {
19862                // sentinel: fetch the current configuration from the window manager
19863                values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
19864            }
19865
19866            if (mWindowManager != null) {
19867                // Update OOM levels based on display size.
19868                mProcessList.applyDisplaySize(mWindowManager);
19869            }
19870
19871            final long origId = Binder.clearCallingIdentity();
19872            try {
19873                if (values != null) {
19874                    Settings.System.clearConfiguration(values);
19875                }
19876                updateConfigurationLocked(values, null, false, false /* persistent */,
19877                        UserHandle.USER_NULL, false /* deferResume */,
19878                        mTmpUpdateConfigurationResult);
19879                return mTmpUpdateConfigurationResult.changes != 0;
19880            } finally {
19881                Binder.restoreCallingIdentity(origId);
19882            }
19883        }
19884    }
19885
19886    void updateUserConfigurationLocked() {
19887        final Configuration configuration = new Configuration(getGlobalConfiguration());
19888        final int currentUserId = mUserController.getCurrentUserIdLocked();
19889        Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
19890                currentUserId, Settings.System.canWrite(mContext));
19891        updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
19892                false /* persistent */, currentUserId, false /* deferResume */);
19893    }
19894
19895    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19896            boolean initLocale) {
19897        return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19898    }
19899
19900    boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19901            boolean initLocale, boolean deferResume) {
19902        // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19903        return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19904                UserHandle.USER_NULL, deferResume);
19905    }
19906
19907    // To cache the list of supported system locales
19908    private String[] mSupportedSystemLocales = null;
19909
19910    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19911            boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19912        return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
19913                deferResume, null /* result */);
19914    }
19915
19916    /**
19917     * Do either or both things: (1) change the current configuration, and (2)
19918     * make sure the given activity is running with the (now) current
19919     * configuration.  Returns true if the activity has been left running, or
19920     * false if <var>starting</var> is being destroyed to match the new
19921     * configuration.
19922     *
19923     * @param userId is only used when persistent parameter is set to true to persist configuration
19924     *               for that particular user
19925     */
19926    private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19927            boolean initLocale, boolean persistent, int userId, boolean deferResume,
19928            UpdateConfigurationResult result) {
19929        int changes = 0;
19930        boolean kept = true;
19931
19932        if (mWindowManager != null) {
19933            mWindowManager.deferSurfaceLayout();
19934        }
19935        try {
19936            if (values != null) {
19937                changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
19938                        deferResume);
19939            }
19940
19941            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
19942        } finally {
19943            if (mWindowManager != null) {
19944                mWindowManager.continueSurfaceLayout();
19945            }
19946        }
19947
19948        if (result != null) {
19949            result.changes = changes;
19950            result.activityRelaunched = !kept;
19951        }
19952        return kept;
19953    }
19954
19955    /** Update default (global) configuration and notify listeners about changes. */
19956    private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
19957            boolean persistent, int userId, boolean deferResume) {
19958        mTempConfig.setTo(getGlobalConfiguration());
19959        final int changes = mTempConfig.updateFrom(values);
19960        if (changes == 0) {
19961            return 0;
19962        }
19963
19964        if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19965                "Updating global configuration to: " + values);
19966
19967        EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19968
19969        if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19970            final LocaleList locales = values.getLocales();
19971            int bestLocaleIndex = 0;
19972            if (locales.size() > 1) {
19973                if (mSupportedSystemLocales == null) {
19974                    mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
19975                }
19976                bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
19977            }
19978            SystemProperties.set("persist.sys.locale",
19979                    locales.get(bestLocaleIndex).toLanguageTag());
19980            LocaleList.setDefault(locales, bestLocaleIndex);
19981            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19982                    locales.get(bestLocaleIndex)));
19983        }
19984
19985        mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
19986        mTempConfig.seq = mConfigurationSeq;
19987
19988        // Update stored global config and notify everyone about the change.
19989        mStackSupervisor.onConfigurationChanged(mTempConfig);
19990
19991        Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
19992        // TODO(multi-display): Update UsageEvents#Event to include displayId.
19993        mUsageStatsService.reportConfigurationChange(mTempConfig,
19994                mUserController.getCurrentUserIdLocked());
19995
19996        // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
19997        mShowDialogs = shouldShowDialogs(mTempConfig, mVrState != NON_VR_MODE);
19998
19999        AttributeCache ac = AttributeCache.instance();
20000        if (ac != null) {
20001            ac.updateConfiguration(mTempConfig);
20002        }
20003
20004        // Make sure all resources in our process are updated right now, so that anyone who is going
20005        // to retrieve resource values after we return will be sure to get the new ones. This is
20006        // especially important during boot, where the first config change needs to guarantee all
20007        // resources have that config before following boot code is executed.
20008        mSystemThread.applyConfigurationToResources(mTempConfig);
20009
20010        // We need another copy of global config because we're scheduling some calls instead of
20011        // running them in place. We need to be sure that object we send will be handled unchanged.
20012        final Configuration configCopy = new Configuration(mTempConfig);
20013        if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20014            Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20015            msg.obj = configCopy;
20016            msg.arg1 = userId;
20017            mHandler.sendMessage(msg);
20018        }
20019
20020        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20021            ProcessRecord app = mLruProcesses.get(i);
20022            try {
20023                if (app.thread != null) {
20024                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20025                            + app.processName + " new config " + configCopy);
20026                    app.thread.scheduleConfigurationChanged(configCopy);
20027                }
20028            } catch (Exception e) {
20029            }
20030        }
20031
20032        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20033        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20034                | Intent.FLAG_RECEIVER_FOREGROUND
20035                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20036        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20037                AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
20038                UserHandle.USER_ALL);
20039        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20040            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20041            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20042                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20043                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20044            if (initLocale || !mProcessesReady) {
20045                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20046            }
20047            broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20048                    AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
20049                    UserHandle.USER_ALL);
20050        }
20051
20052        // Override configuration of the default display duplicates global config, so we need to
20053        // update it also. This will also notify WindowManager about changes.
20054        performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20055                DEFAULT_DISPLAY);
20056
20057        return changes;
20058    }
20059
20060    @Override
20061    public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20062        enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20063
20064        synchronized (this) {
20065            // Check if display is initialized in AM.
20066            if (!mStackSupervisor.isDisplayAdded(displayId)) {
20067                // Call might come when display is not yet added or has already been removed.
20068                if (DEBUG_CONFIGURATION) {
20069                    Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20070                            + displayId);
20071                }
20072                return false;
20073            }
20074
20075            if (values == null && mWindowManager != null) {
20076                // sentinel: fetch the current configuration from the window manager
20077                values = mWindowManager.computeNewConfiguration(displayId);
20078            }
20079
20080            if (mWindowManager != null) {
20081                // Update OOM levels based on display size.
20082                mProcessList.applyDisplaySize(mWindowManager);
20083            }
20084
20085            final long origId = Binder.clearCallingIdentity();
20086            try {
20087                if (values != null) {
20088                    Settings.System.clearConfiguration(values);
20089                }
20090                updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20091                        false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20092                return mTmpUpdateConfigurationResult.changes != 0;
20093            } finally {
20094                Binder.restoreCallingIdentity(origId);
20095            }
20096        }
20097    }
20098
20099    boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20100            boolean deferResume, int displayId) {
20101        return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20102                displayId, null /* result */);
20103    }
20104
20105    /**
20106     * Updates override configuration specific for the selected display. If no config is provided,
20107     * new one will be computed in WM based on current display info.
20108     */
20109    private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20110            ActivityRecord starting, boolean deferResume, int displayId,
20111            UpdateConfigurationResult result) {
20112        int changes = 0;
20113        boolean kept = true;
20114
20115        if (mWindowManager != null) {
20116            mWindowManager.deferSurfaceLayout();
20117        }
20118        try {
20119            if (values != null) {
20120                if (displayId == DEFAULT_DISPLAY) {
20121                    // Override configuration of the default display duplicates global config, so
20122                    // we're calling global config update instead for default display. It will also
20123                    // apply the correct override config.
20124                    changes = updateGlobalConfiguration(values, false /* initLocale */,
20125                            false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20126                } else {
20127                    changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20128                }
20129            }
20130
20131            kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20132        } finally {
20133            if (mWindowManager != null) {
20134                mWindowManager.continueSurfaceLayout();
20135            }
20136        }
20137
20138        if (result != null) {
20139            result.changes = changes;
20140            result.activityRelaunched = !kept;
20141        }
20142        return kept;
20143    }
20144
20145    private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20146            int displayId) {
20147        mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20148        final int changes = mTempConfig.updateFrom(values);
20149        if (changes == 0) {
20150            return 0;
20151        }
20152
20153        Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + mTempConfig
20154                + " for displayId=" + displayId);
20155        mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20156
20157        final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20158        if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20159            // Reset the unsupported display size dialog.
20160            mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20161
20162            killAllBackgroundProcessesExcept(N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20163        }
20164
20165        // Update the configuration with WM first and check if any of the stacks need to be resized
20166        // due to the configuration change. If so, resize the stacks now and do any relaunches if
20167        // necessary. This way we don't need to relaunch again afterwards in
20168        // ensureActivityConfigurationLocked().
20169        if (mWindowManager != null) {
20170            final int[] resizedStacks =
20171                    mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20172            if (resizedStacks != null) {
20173                for (int stackId : resizedStacks) {
20174                    resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20175                }
20176            }
20177        }
20178
20179        return changes;
20180    }
20181
20182    /** Applies latest configuration and/or visibility updates if needed. */
20183    private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20184        boolean kept = true;
20185        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20186        // mainStack is null during startup.
20187        if (mainStack != null) {
20188            if (changes != 0 && starting == null) {
20189                // If the configuration changed, and the caller is not already
20190                // in the process of starting an activity, then find the top
20191                // activity to check if its configuration needs to change.
20192                starting = mainStack.topRunningActivityLocked();
20193            }
20194
20195            if (starting != null) {
20196                kept = starting.ensureActivityConfigurationLocked(changes,
20197                        false /* preserveWindow */);
20198                // And we need to make sure at this point that all other activities
20199                // are made visible with the correct configuration.
20200                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20201                        !PRESERVE_WINDOWS);
20202            }
20203        }
20204
20205        return kept;
20206    }
20207
20208    /** Helper method that requests bounds from WM and applies them to stack. */
20209    private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20210        final Rect newStackBounds = new Rect();
20211        mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20212        mStackSupervisor.resizeStackLocked(
20213                stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20214                null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20215                false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20216    }
20217
20218    /**
20219     * Decide based on the configuration whether we should show the ANR,
20220     * crash, etc dialogs.  The idea is that if there is no affordance to
20221     * press the on-screen buttons, or the user experience would be more
20222     * greatly impacted than the crash itself, we shouldn't show the dialog.
20223     *
20224     * A thought: SystemUI might also want to get told about this, the Power
20225     * dialog / global actions also might want different behaviors.
20226     */
20227    private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
20228        final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20229                                   && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20230                                   && config.navigation == Configuration.NAVIGATION_NONAV);
20231        int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20232        final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20233                && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE))
20234                && modeType != Configuration.UI_MODE_TYPE_TELEVISION);
20235        return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
20236    }
20237
20238    @Override
20239    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20240        synchronized (this) {
20241            ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20242            if (srec != null) {
20243                return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20244            }
20245        }
20246        return false;
20247    }
20248
20249    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20250            Intent resultData) {
20251
20252        synchronized (this) {
20253            final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20254            if (r != null) {
20255                return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20256            }
20257            return false;
20258        }
20259    }
20260
20261    public int getLaunchedFromUid(IBinder activityToken) {
20262        ActivityRecord srec;
20263        synchronized (this) {
20264            srec = ActivityRecord.forTokenLocked(activityToken);
20265        }
20266        if (srec == null) {
20267            return -1;
20268        }
20269        return srec.launchedFromUid;
20270    }
20271
20272    public String getLaunchedFromPackage(IBinder activityToken) {
20273        ActivityRecord srec;
20274        synchronized (this) {
20275            srec = ActivityRecord.forTokenLocked(activityToken);
20276        }
20277        if (srec == null) {
20278            return null;
20279        }
20280        return srec.launchedFromPackage;
20281    }
20282
20283    // =========================================================
20284    // LIFETIME MANAGEMENT
20285    // =========================================================
20286
20287    // Returns whether the app is receiving broadcast.
20288    // If receiving, fetch all broadcast queues which the app is
20289    // the current [or imminent] receiver on.
20290    private boolean isReceivingBroadcastLocked(ProcessRecord app,
20291            ArraySet<BroadcastQueue> receivingQueues) {
20292        if (!app.curReceivers.isEmpty()) {
20293            for (BroadcastRecord r : app.curReceivers) {
20294                receivingQueues.add(r.queue);
20295            }
20296            return true;
20297        }
20298
20299        // It's not the current receiver, but it might be starting up to become one
20300        for (BroadcastQueue queue : mBroadcastQueues) {
20301            final BroadcastRecord r = queue.mPendingBroadcast;
20302            if (r != null && r.curApp == app) {
20303                // found it; report which queue it's in
20304                receivingQueues.add(queue);
20305            }
20306        }
20307
20308        return !receivingQueues.isEmpty();
20309    }
20310
20311    Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20312            int targetUid, ComponentName targetComponent, String targetProcess) {
20313        if (!mTrackingAssociations) {
20314            return null;
20315        }
20316        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20317                = mAssociations.get(targetUid);
20318        if (components == null) {
20319            components = new ArrayMap<>();
20320            mAssociations.put(targetUid, components);
20321        }
20322        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20323        if (sourceUids == null) {
20324            sourceUids = new SparseArray<>();
20325            components.put(targetComponent, sourceUids);
20326        }
20327        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20328        if (sourceProcesses == null) {
20329            sourceProcesses = new ArrayMap<>();
20330            sourceUids.put(sourceUid, sourceProcesses);
20331        }
20332        Association ass = sourceProcesses.get(sourceProcess);
20333        if (ass == null) {
20334            ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20335                    targetProcess);
20336            sourceProcesses.put(sourceProcess, ass);
20337        }
20338        ass.mCount++;
20339        ass.mNesting++;
20340        if (ass.mNesting == 1) {
20341            ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20342            ass.mLastState = sourceState;
20343        }
20344        return ass;
20345    }
20346
20347    void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20348            ComponentName targetComponent) {
20349        if (!mTrackingAssociations) {
20350            return;
20351        }
20352        ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20353                = mAssociations.get(targetUid);
20354        if (components == null) {
20355            return;
20356        }
20357        SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20358        if (sourceUids == null) {
20359            return;
20360        }
20361        ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20362        if (sourceProcesses == null) {
20363            return;
20364        }
20365        Association ass = sourceProcesses.get(sourceProcess);
20366        if (ass == null || ass.mNesting <= 0) {
20367            return;
20368        }
20369        ass.mNesting--;
20370        if (ass.mNesting == 0) {
20371            long uptime = SystemClock.uptimeMillis();
20372            ass.mTime += uptime - ass.mStartTime;
20373            ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20374                    += uptime - ass.mLastStateUptime;
20375            ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20376        }
20377    }
20378
20379    private void noteUidProcessState(final int uid, final int state) {
20380        mBatteryStatsService.noteUidProcessState(uid, state);
20381        if (mTrackingAssociations) {
20382            for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20383                ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20384                        = mAssociations.valueAt(i1);
20385                for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20386                    SparseArray<ArrayMap<String, Association>> sourceUids
20387                            = targetComponents.valueAt(i2);
20388                    ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20389                    if (sourceProcesses != null) {
20390                        for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20391                            Association ass = sourceProcesses.valueAt(i4);
20392                            if (ass.mNesting >= 1) {
20393                                // currently associated
20394                                long uptime = SystemClock.uptimeMillis();
20395                                ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20396                                        += uptime - ass.mLastStateUptime;
20397                                ass.mLastState = state;
20398                                ass.mLastStateUptime = uptime;
20399                            }
20400                        }
20401                    }
20402                }
20403            }
20404        }
20405    }
20406
20407    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20408            boolean doingAll, long now) {
20409        if (mAdjSeq == app.adjSeq) {
20410            // This adjustment has already been computed.
20411            return app.curRawAdj;
20412        }
20413
20414        if (app.thread == null) {
20415            app.adjSeq = mAdjSeq;
20416            app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20417            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20418            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20419        }
20420
20421        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20422        app.adjSource = null;
20423        app.adjTarget = null;
20424        app.empty = false;
20425        app.cached = false;
20426
20427        final int activitiesSize = app.activities.size();
20428
20429        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20430            // The max adjustment doesn't allow this app to be anything
20431            // below foreground, so it is not worth doing work for it.
20432            app.adjType = "fixed";
20433            app.adjSeq = mAdjSeq;
20434            app.curRawAdj = app.maxAdj;
20435            app.foregroundActivities = false;
20436            app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20437            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20438            // System processes can do UI, and when they do we want to have
20439            // them trim their memory after the user leaves the UI.  To
20440            // facilitate this, here we need to determine whether or not it
20441            // is currently showing UI.
20442            app.systemNoUi = true;
20443            if (app == TOP_APP) {
20444                app.systemNoUi = false;
20445                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20446                app.adjType = "pers-top-activity";
20447            } else if (app.hasTopUi) {
20448                app.systemNoUi = false;
20449                app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20450                app.adjType = "pers-top-ui";
20451            } else if (activitiesSize > 0) {
20452                for (int j = 0; j < activitiesSize; j++) {
20453                    final ActivityRecord r = app.activities.get(j);
20454                    if (r.visible) {
20455                        app.systemNoUi = false;
20456                    }
20457                }
20458            }
20459            if (!app.systemNoUi) {
20460                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20461            }
20462            return (app.curAdj=app.maxAdj);
20463        }
20464
20465        app.systemNoUi = false;
20466
20467        final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20468
20469        // Determine the importance of the process, starting with most
20470        // important to least, and assign an appropriate OOM adjustment.
20471        int adj;
20472        int schedGroup;
20473        int procState;
20474        boolean foregroundActivities = false;
20475        mTmpBroadcastQueue.clear();
20476        if (app == TOP_APP) {
20477            // The last app on the list is the foreground app.
20478            adj = ProcessList.FOREGROUND_APP_ADJ;
20479            schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20480            app.adjType = "top-activity";
20481            foregroundActivities = true;
20482            procState = PROCESS_STATE_CUR_TOP;
20483        } else if (app.instr != null) {
20484            // Don't want to kill running instrumentation.
20485            adj = ProcessList.FOREGROUND_APP_ADJ;
20486            schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20487            app.adjType = "instrumentation";
20488            procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20489        } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20490            // An app that is currently receiving a broadcast also
20491            // counts as being in the foreground for OOM killer purposes.
20492            // It's placed in a sched group based on the nature of the
20493            // broadcast as reflected by which queue it's active in.
20494            adj = ProcessList.FOREGROUND_APP_ADJ;
20495            schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20496                    ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20497            app.adjType = "broadcast";
20498            procState = ActivityManager.PROCESS_STATE_RECEIVER;
20499        } else if (app.executingServices.size() > 0) {
20500            // An app that is currently executing a service callback also
20501            // counts as being in the foreground.
20502            adj = ProcessList.FOREGROUND_APP_ADJ;
20503            schedGroup = app.execServicesFg ?
20504                    ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20505            app.adjType = "exec-service";
20506            procState = ActivityManager.PROCESS_STATE_SERVICE;
20507            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20508        } else {
20509            // As far as we know the process is empty.  We may change our mind later.
20510            schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20511            // At this point we don't actually know the adjustment.  Use the cached adj
20512            // value that the caller wants us to.
20513            adj = cachedAdj;
20514            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20515            app.cached = true;
20516            app.empty = true;
20517            app.adjType = "cch-empty";
20518        }
20519
20520        // Examine all activities if not already foreground.
20521        if (!foregroundActivities && activitiesSize > 0) {
20522            int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20523            for (int j = 0; j < activitiesSize; j++) {
20524                final ActivityRecord r = app.activities.get(j);
20525                if (r.app != app) {
20526                    Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20527                            + " instead of expected " + app);
20528                    if (r.app == null || (r.app.uid == app.uid)) {
20529                        // Only fix things up when they look sane
20530                        r.app = app;
20531                    } else {
20532                        continue;
20533                    }
20534                }
20535                if (r.visible) {
20536                    // App has a visible activity; only upgrade adjustment.
20537                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20538                        adj = ProcessList.VISIBLE_APP_ADJ;
20539                        app.adjType = "visible";
20540                    }
20541                    if (procState > PROCESS_STATE_CUR_TOP) {
20542                        procState = PROCESS_STATE_CUR_TOP;
20543                    }
20544                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20545                    app.cached = false;
20546                    app.empty = false;
20547                    foregroundActivities = true;
20548                    if (r.task != null && minLayer > 0) {
20549                        final int layer = r.task.mLayerRank;
20550                        if (layer >= 0 && minLayer > layer) {
20551                            minLayer = layer;
20552                        }
20553                    }
20554                    break;
20555                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
20556                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20557                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20558                        app.adjType = "pausing";
20559                    }
20560                    if (procState > PROCESS_STATE_CUR_TOP) {
20561                        procState = PROCESS_STATE_CUR_TOP;
20562                    }
20563                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20564                    app.cached = false;
20565                    app.empty = false;
20566                    foregroundActivities = true;
20567                } else if (r.state == ActivityState.STOPPING) {
20568                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20569                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20570                        app.adjType = "stopping";
20571                    }
20572                    // For the process state, we will at this point consider the
20573                    // process to be cached.  It will be cached either as an activity
20574                    // or empty depending on whether the activity is finishing.  We do
20575                    // this so that we can treat the process as cached for purposes of
20576                    // memory trimming (determing current memory level, trim command to
20577                    // send to process) since there can be an arbitrary number of stopping
20578                    // processes and they should soon all go into the cached state.
20579                    if (!r.finishing) {
20580                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20581                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20582                        }
20583                    }
20584                    app.cached = false;
20585                    app.empty = false;
20586                    foregroundActivities = true;
20587                } else {
20588                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20589                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20590                        app.adjType = "cch-act";
20591                    }
20592                }
20593            }
20594            if (adj == ProcessList.VISIBLE_APP_ADJ) {
20595                adj += minLayer;
20596            }
20597        }
20598
20599        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
20600                || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
20601            if (app.foregroundServices) {
20602                // The user is aware of this app, so make it visible.
20603                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20604                procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20605                app.cached = false;
20606                app.adjType = "fg-service";
20607                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20608            } else if (app.forcingToForeground != null) {
20609                // The user is aware of this app, so make it visible.
20610                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20611                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20612                app.cached = false;
20613                app.adjType = "force-fg";
20614                app.adjSource = app.forcingToForeground;
20615                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20616            } else if (app.hasOverlayUi) {
20617                // The process is display an overlay UI.
20618                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20619                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20620                app.cached = false;
20621                app.adjType = "has-overlay-ui";
20622                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20623            }
20624        }
20625
20626        if (app == mHeavyWeightProcess) {
20627            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
20628                // We don't want to kill the current heavy-weight process.
20629                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
20630                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20631                app.cached = false;
20632                app.adjType = "heavy";
20633            }
20634            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20635                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
20636            }
20637        }
20638
20639        if (app == mHomeProcess) {
20640            if (adj > ProcessList.HOME_APP_ADJ) {
20641                // This process is hosting what we currently consider to be the
20642                // home app, so we don't want to let it go into the background.
20643                adj = ProcessList.HOME_APP_ADJ;
20644                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20645                app.cached = false;
20646                app.adjType = "home";
20647            }
20648            if (procState > ActivityManager.PROCESS_STATE_HOME) {
20649                procState = ActivityManager.PROCESS_STATE_HOME;
20650            }
20651        }
20652
20653        if (app == mPreviousProcess && app.activities.size() > 0) {
20654            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
20655                // This was the previous process that showed UI to the user.
20656                // We want to try to keep it around more aggressively, to give
20657                // a good experience around switching between two apps.
20658                adj = ProcessList.PREVIOUS_APP_ADJ;
20659                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20660                app.cached = false;
20661                app.adjType = "previous";
20662            }
20663            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
20664                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
20665            }
20666        }
20667
20668        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
20669                + " reason=" + app.adjType);
20670
20671        // By default, we use the computed adjustment.  It may be changed if
20672        // there are applications dependent on our services or providers, but
20673        // this gives us a baseline and makes sure we don't get into an
20674        // infinite recursion.
20675        app.adjSeq = mAdjSeq;
20676        app.curRawAdj = adj;
20677        app.hasStartedServices = false;
20678
20679        if (mBackupTarget != null && app == mBackupTarget.app) {
20680            // If possible we want to avoid killing apps while they're being backed up
20681            if (adj > ProcessList.BACKUP_APP_ADJ) {
20682                if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
20683                adj = ProcessList.BACKUP_APP_ADJ;
20684                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20685                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20686                }
20687                app.adjType = "backup";
20688                app.cached = false;
20689            }
20690            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
20691                procState = ActivityManager.PROCESS_STATE_BACKUP;
20692            }
20693        }
20694
20695        boolean mayBeTop = false;
20696
20697        for (int is = app.services.size()-1;
20698                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20699                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20700                        || procState > ActivityManager.PROCESS_STATE_TOP);
20701                is--) {
20702            ServiceRecord s = app.services.valueAt(is);
20703            if (s.startRequested) {
20704                app.hasStartedServices = true;
20705                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
20706                    procState = ActivityManager.PROCESS_STATE_SERVICE;
20707                }
20708                if (app.hasShownUi && app != mHomeProcess) {
20709                    // If this process has shown some UI, let it immediately
20710                    // go to the LRU list because it may be pretty heavy with
20711                    // UI stuff.  We'll tag it with a label just to help
20712                    // debug and understand what is going on.
20713                    if (adj > ProcessList.SERVICE_ADJ) {
20714                        app.adjType = "cch-started-ui-services";
20715                    }
20716                } else {
20717                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20718                        // This service has seen some activity within
20719                        // recent memory, so we will keep its process ahead
20720                        // of the background processes.
20721                        if (adj > ProcessList.SERVICE_ADJ) {
20722                            adj = ProcessList.SERVICE_ADJ;
20723                            app.adjType = "started-services";
20724                            app.cached = false;
20725                        }
20726                    }
20727                    // If we have let the service slide into the background
20728                    // state, still have some text describing what it is doing
20729                    // even though the service no longer has an impact.
20730                    if (adj > ProcessList.SERVICE_ADJ) {
20731                        app.adjType = "cch-started-services";
20732                    }
20733                }
20734            }
20735
20736            for (int conni = s.connections.size()-1;
20737                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20738                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20739                            || procState > ActivityManager.PROCESS_STATE_TOP);
20740                    conni--) {
20741                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
20742                for (int i = 0;
20743                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
20744                                || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20745                                || procState > ActivityManager.PROCESS_STATE_TOP);
20746                        i++) {
20747                    // XXX should compute this based on the max of
20748                    // all connected clients.
20749                    ConnectionRecord cr = clist.get(i);
20750                    if (cr.binding.client == app) {
20751                        // Binding to ourself is not interesting.
20752                        continue;
20753                    }
20754
20755                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
20756                        ProcessRecord client = cr.binding.client;
20757                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
20758                                TOP_APP, doingAll, now);
20759                        int clientProcState = client.curProcState;
20760                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20761                            // If the other app is cached for any reason, for purposes here
20762                            // we are going to consider it empty.  The specific cached state
20763                            // doesn't propagate except under certain conditions.
20764                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20765                        }
20766                        String adjType = null;
20767                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
20768                            // Not doing bind OOM management, so treat
20769                            // this guy more like a started service.
20770                            if (app.hasShownUi && app != mHomeProcess) {
20771                                // If this process has shown some UI, let it immediately
20772                                // go to the LRU list because it may be pretty heavy with
20773                                // UI stuff.  We'll tag it with a label just to help
20774                                // debug and understand what is going on.
20775                                if (adj > clientAdj) {
20776                                    adjType = "cch-bound-ui-services";
20777                                }
20778                                app.cached = false;
20779                                clientAdj = adj;
20780                                clientProcState = procState;
20781                            } else {
20782                                if (now >= (s.lastActivity
20783                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
20784                                    // This service has not seen activity within
20785                                    // recent memory, so allow it to drop to the
20786                                    // LRU list if there is no other reason to keep
20787                                    // it around.  We'll also tag it with a label just
20788                                    // to help debug and undertand what is going on.
20789                                    if (adj > clientAdj) {
20790                                        adjType = "cch-bound-services";
20791                                    }
20792                                    clientAdj = adj;
20793                                }
20794                            }
20795                        }
20796                        if (adj > clientAdj) {
20797                            // If this process has recently shown UI, and
20798                            // the process that is binding to it is less
20799                            // important than being visible, then we don't
20800                            // care about the binding as much as we care
20801                            // about letting this process get into the LRU
20802                            // list to be killed and restarted if needed for
20803                            // memory.
20804                            if (app.hasShownUi && app != mHomeProcess
20805                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20806                                adjType = "cch-bound-ui-services";
20807                            } else {
20808                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
20809                                        |Context.BIND_IMPORTANT)) != 0) {
20810                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
20811                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
20812                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
20813                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
20814                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20815                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
20816                                } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
20817                                    adj = clientAdj;
20818                                } else {
20819                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
20820                                        adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
20821                                    }
20822                                }
20823                                if (!client.cached) {
20824                                    app.cached = false;
20825                                }
20826                                adjType = "service";
20827                            }
20828                        }
20829                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20830                            // This will treat important bound services identically to
20831                            // the top app, which may behave differently than generic
20832                            // foreground work.
20833                            if (client.curSchedGroup > schedGroup) {
20834                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20835                                    schedGroup = client.curSchedGroup;
20836                                } else {
20837                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20838                                }
20839                            }
20840                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20841                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20842                                    // Special handling of clients who are in the top state.
20843                                    // We *may* want to consider this process to be in the
20844                                    // top state as well, but only if there is not another
20845                                    // reason for it to be running.  Being on the top is a
20846                                    // special state, meaning you are specifically running
20847                                    // for the current top app.  If the process is already
20848                                    // running in the background for some other reason, it
20849                                    // is more important to continue considering it to be
20850                                    // in the background state.
20851                                    mayBeTop = true;
20852                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20853                                } else {
20854                                    // Special handling for above-top states (persistent
20855                                    // processes).  These should not bring the current process
20856                                    // into the top state, since they are not on top.  Instead
20857                                    // give them the best state after that.
20858                                    if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
20859                                        clientProcState =
20860                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20861                                    } else if (mWakefulness
20862                                                    == PowerManagerInternal.WAKEFULNESS_AWAKE &&
20863                                            (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
20864                                                    != 0) {
20865                                        clientProcState =
20866                                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20867                                    } else {
20868                                        clientProcState =
20869                                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20870                                    }
20871                                }
20872                            }
20873                        } else {
20874                            if (clientProcState <
20875                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
20876                                clientProcState =
20877                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
20878                            }
20879                        }
20880                        if (procState > clientProcState) {
20881                            procState = clientProcState;
20882                        }
20883                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20884                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
20885                            app.pendingUiClean = true;
20886                        }
20887                        if (adjType != null) {
20888                            app.adjType = adjType;
20889                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20890                                    .REASON_SERVICE_IN_USE;
20891                            app.adjSource = cr.binding.client;
20892                            app.adjSourceProcState = clientProcState;
20893                            app.adjTarget = s.name;
20894                        }
20895                    }
20896                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
20897                        app.treatLikeActivity = true;
20898                    }
20899                    final ActivityRecord a = cr.activity;
20900                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
20901                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
20902                            (a.visible || a.state == ActivityState.RESUMED ||
20903                             a.state == ActivityState.PAUSING)) {
20904                            adj = ProcessList.FOREGROUND_APP_ADJ;
20905                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
20906                                if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
20907                                    schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
20908                                } else {
20909                                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20910                                }
20911                            }
20912                            app.cached = false;
20913                            app.adjType = "service";
20914                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20915                                    .REASON_SERVICE_IN_USE;
20916                            app.adjSource = a;
20917                            app.adjSourceProcState = procState;
20918                            app.adjTarget = s.name;
20919                        }
20920                    }
20921                }
20922            }
20923        }
20924
20925        for (int provi = app.pubProviders.size()-1;
20926                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20927                        || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20928                        || procState > ActivityManager.PROCESS_STATE_TOP);
20929                provi--) {
20930            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
20931            for (int i = cpr.connections.size()-1;
20932                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
20933                            || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
20934                            || procState > ActivityManager.PROCESS_STATE_TOP);
20935                    i--) {
20936                ContentProviderConnection conn = cpr.connections.get(i);
20937                ProcessRecord client = conn.client;
20938                if (client == app) {
20939                    // Being our own client is not interesting.
20940                    continue;
20941                }
20942                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
20943                int clientProcState = client.curProcState;
20944                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
20945                    // If the other app is cached for any reason, for purposes here
20946                    // we are going to consider it empty.
20947                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20948                }
20949                if (adj > clientAdj) {
20950                    if (app.hasShownUi && app != mHomeProcess
20951                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
20952                        app.adjType = "cch-ui-provider";
20953                    } else {
20954                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
20955                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
20956                        app.adjType = "provider";
20957                    }
20958                    app.cached &= client.cached;
20959                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
20960                            .REASON_PROVIDER_IN_USE;
20961                    app.adjSource = client;
20962                    app.adjSourceProcState = clientProcState;
20963                    app.adjTarget = cpr.name;
20964                }
20965                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
20966                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
20967                        // Special handling of clients who are in the top state.
20968                        // We *may* want to consider this process to be in the
20969                        // top state as well, but only if there is not another
20970                        // reason for it to be running.  Being on the top is a
20971                        // special state, meaning you are specifically running
20972                        // for the current top app.  If the process is already
20973                        // running in the background for some other reason, it
20974                        // is more important to continue considering it to be
20975                        // in the background state.
20976                        mayBeTop = true;
20977                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20978                    } else {
20979                        // Special handling for above-top states (persistent
20980                        // processes).  These should not bring the current process
20981                        // into the top state, since they are not on top.  Instead
20982                        // give them the best state after that.
20983                        clientProcState =
20984                                ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20985                    }
20986                }
20987                if (procState > clientProcState) {
20988                    procState = clientProcState;
20989                }
20990                if (client.curSchedGroup > schedGroup) {
20991                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20992                }
20993            }
20994            // If the provider has external (non-framework) process
20995            // dependencies, ensure that its adjustment is at least
20996            // FOREGROUND_APP_ADJ.
20997            if (cpr.hasExternalProcessHandles()) {
20998                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
20999                    adj = ProcessList.FOREGROUND_APP_ADJ;
21000                    schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21001                    app.cached = false;
21002                    app.adjType = "provider";
21003                    app.adjTarget = cpr.name;
21004                }
21005                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21006                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21007                }
21008            }
21009        }
21010
21011        if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
21012            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21013                adj = ProcessList.PREVIOUS_APP_ADJ;
21014                schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21015                app.cached = false;
21016                app.adjType = "provider";
21017            }
21018            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21019                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21020            }
21021        }
21022
21023        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21024            // A client of one of our services or providers is in the top state.  We
21025            // *may* want to be in the top state, but not if we are already running in
21026            // the background for some other reason.  For the decision here, we are going
21027            // to pick out a few specific states that we want to remain in when a client
21028            // is top (states that tend to be longer-term) and otherwise allow it to go
21029            // to the top state.
21030            switch (procState) {
21031                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21032                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21033                case ActivityManager.PROCESS_STATE_SERVICE:
21034                    // These all are longer-term states, so pull them up to the top
21035                    // of the background states, but not all the way to the top state.
21036                    procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21037                    break;
21038                default:
21039                    // Otherwise, top is a better choice, so take it.
21040                    procState = ActivityManager.PROCESS_STATE_TOP;
21041                    break;
21042            }
21043        }
21044
21045        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21046            if (app.hasClientActivities) {
21047                // This is a cached process, but with client activities.  Mark it so.
21048                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21049                app.adjType = "cch-client-act";
21050            } else if (app.treatLikeActivity) {
21051                // This is a cached process, but somebody wants us to treat it like it has
21052                // an activity, okay!
21053                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21054                app.adjType = "cch-as-act";
21055            }
21056        }
21057
21058        if (adj == ProcessList.SERVICE_ADJ) {
21059            if (doingAll) {
21060                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21061                mNewNumServiceProcs++;
21062                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21063                if (!app.serviceb) {
21064                    // This service isn't far enough down on the LRU list to
21065                    // normally be a B service, but if we are low on RAM and it
21066                    // is large we want to force it down since we would prefer to
21067                    // keep launcher over it.
21068                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21069                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21070                        app.serviceHighRam = true;
21071                        app.serviceb = true;
21072                        //Slog.i(TAG, "ADJ " + app + " high ram!");
21073                    } else {
21074                        mNewNumAServiceProcs++;
21075                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
21076                    }
21077                } else {
21078                    app.serviceHighRam = false;
21079                }
21080            }
21081            if (app.serviceb) {
21082                adj = ProcessList.SERVICE_B_ADJ;
21083            }
21084        }
21085
21086        app.curRawAdj = adj;
21087
21088        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21089        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21090        if (adj > app.maxAdj) {
21091            adj = app.maxAdj;
21092            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21093                schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21094            }
21095        }
21096
21097        // Do final modification to adj.  Everything we do between here and applying
21098        // the final setAdj must be done in this function, because we will also use
21099        // it when computing the final cached adj later.  Note that we don't need to
21100        // worry about this for max adj above, since max adj will always be used to
21101        // keep it out of the cached vaues.
21102        app.curAdj = app.modifyRawOomAdj(adj);
21103        app.curSchedGroup = schedGroup;
21104        app.curProcState = procState;
21105        app.foregroundActivities = foregroundActivities;
21106
21107        return app.curRawAdj;
21108    }
21109
21110    /**
21111     * Record new PSS sample for a process.
21112     */
21113    void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21114            long now) {
21115        EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21116                swapPss * 1024);
21117        proc.lastPssTime = now;
21118        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21119        if (DEBUG_PSS) Slog.d(TAG_PSS,
21120                "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21121                + " state=" + ProcessList.makeProcStateString(procState));
21122        if (proc.initialIdlePss == 0) {
21123            proc.initialIdlePss = pss;
21124        }
21125        proc.lastPss = pss;
21126        proc.lastSwapPss = swapPss;
21127        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21128            proc.lastCachedPss = pss;
21129            proc.lastCachedSwapPss = swapPss;
21130        }
21131
21132        final SparseArray<Pair<Long, String>> watchUids
21133                = mMemWatchProcesses.getMap().get(proc.processName);
21134        Long check = null;
21135        if (watchUids != null) {
21136            Pair<Long, String> val = watchUids.get(proc.uid);
21137            if (val == null) {
21138                val = watchUids.get(0);
21139            }
21140            if (val != null) {
21141                check = val.first;
21142            }
21143        }
21144        if (check != null) {
21145            if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21146                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21147                if (!isDebuggable) {
21148                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21149                        isDebuggable = true;
21150                    }
21151                }
21152                if (isDebuggable) {
21153                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21154                    final ProcessRecord myProc = proc;
21155                    final File heapdumpFile = DumpHeapProvider.getJavaFile();
21156                    mMemWatchDumpProcName = proc.processName;
21157                    mMemWatchDumpFile = heapdumpFile.toString();
21158                    mMemWatchDumpPid = proc.pid;
21159                    mMemWatchDumpUid = proc.uid;
21160                    BackgroundThread.getHandler().post(new Runnable() {
21161                        @Override
21162                        public void run() {
21163                            revokeUriPermission(ActivityThread.currentActivityThread()
21164                                            .getApplicationThread(),
21165                                    DumpHeapActivity.JAVA_URI,
21166                                    Intent.FLAG_GRANT_READ_URI_PERMISSION
21167                                            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21168                                    UserHandle.myUserId());
21169                            ParcelFileDescriptor fd = null;
21170                            try {
21171                                heapdumpFile.delete();
21172                                fd = ParcelFileDescriptor.open(heapdumpFile,
21173                                        ParcelFileDescriptor.MODE_CREATE |
21174                                                ParcelFileDescriptor.MODE_TRUNCATE |
21175                                                ParcelFileDescriptor.MODE_WRITE_ONLY |
21176                                                ParcelFileDescriptor.MODE_APPEND);
21177                                IApplicationThread thread = myProc.thread;
21178                                if (thread != null) {
21179                                    try {
21180                                        if (DEBUG_PSS) Slog.d(TAG_PSS,
21181                                                "Requesting dump heap from "
21182                                                + myProc + " to " + heapdumpFile);
21183                                        thread.dumpHeap(true, heapdumpFile.toString(), fd);
21184                                    } catch (RemoteException e) {
21185                                    }
21186                                }
21187                            } catch (FileNotFoundException e) {
21188                                e.printStackTrace();
21189                            } finally {
21190                                if (fd != null) {
21191                                    try {
21192                                        fd.close();
21193                                    } catch (IOException e) {
21194                                    }
21195                                }
21196                            }
21197                        }
21198                    });
21199                } else {
21200                    Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21201                            + ", but debugging not enabled");
21202                }
21203            }
21204        }
21205    }
21206
21207    /**
21208     * Schedule PSS collection of a process.
21209     */
21210    void requestPssLocked(ProcessRecord proc, int procState) {
21211        if (mPendingPssProcesses.contains(proc)) {
21212            return;
21213        }
21214        if (mPendingPssProcesses.size() == 0) {
21215            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21216        }
21217        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21218        proc.pssProcState = procState;
21219        mPendingPssProcesses.add(proc);
21220    }
21221
21222    /**
21223     * Schedule PSS collection of all processes.
21224     */
21225    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21226        if (!always) {
21227            if (now < (mLastFullPssTime +
21228                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
21229                return;
21230            }
21231        }
21232        if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21233        mLastFullPssTime = now;
21234        mFullPssPending = true;
21235        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21236        mPendingPssProcesses.clear();
21237        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21238            ProcessRecord app = mLruProcesses.get(i);
21239            if (app.thread == null
21240                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21241                continue;
21242            }
21243            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21244                app.pssProcState = app.setProcState;
21245                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21246                        mTestPssMode, isSleepingLocked(), now);
21247                mPendingPssProcesses.add(app);
21248            }
21249        }
21250        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21251    }
21252
21253    public void setTestPssMode(boolean enabled) {
21254        synchronized (this) {
21255            mTestPssMode = enabled;
21256            if (enabled) {
21257                // Whenever we enable the mode, we want to take a snapshot all of current
21258                // process mem use.
21259                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21260            }
21261        }
21262    }
21263
21264    /**
21265     * Ask a given process to GC right now.
21266     */
21267    final void performAppGcLocked(ProcessRecord app) {
21268        try {
21269            app.lastRequestedGc = SystemClock.uptimeMillis();
21270            if (app.thread != null) {
21271                if (app.reportLowMemory) {
21272                    app.reportLowMemory = false;
21273                    app.thread.scheduleLowMemory();
21274                } else {
21275                    app.thread.processInBackground();
21276                }
21277            }
21278        } catch (Exception e) {
21279            // whatever.
21280        }
21281    }
21282
21283    /**
21284     * Returns true if things are idle enough to perform GCs.
21285     */
21286    private final boolean canGcNowLocked() {
21287        boolean processingBroadcasts = false;
21288        for (BroadcastQueue q : mBroadcastQueues) {
21289            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21290                processingBroadcasts = true;
21291            }
21292        }
21293        return !processingBroadcasts
21294                && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21295    }
21296
21297    /**
21298     * Perform GCs on all processes that are waiting for it, but only
21299     * if things are idle.
21300     */
21301    final void performAppGcsLocked() {
21302        final int N = mProcessesToGc.size();
21303        if (N <= 0) {
21304            return;
21305        }
21306        if (canGcNowLocked()) {
21307            while (mProcessesToGc.size() > 0) {
21308                ProcessRecord proc = mProcessesToGc.remove(0);
21309                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21310                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
21311                            <= SystemClock.uptimeMillis()) {
21312                        // To avoid spamming the system, we will GC processes one
21313                        // at a time, waiting a few seconds between each.
21314                        performAppGcLocked(proc);
21315                        scheduleAppGcsLocked();
21316                        return;
21317                    } else {
21318                        // It hasn't been long enough since we last GCed this
21319                        // process...  put it in the list to wait for its time.
21320                        addProcessToGcListLocked(proc);
21321                        break;
21322                    }
21323                }
21324            }
21325
21326            scheduleAppGcsLocked();
21327        }
21328    }
21329
21330    /**
21331     * If all looks good, perform GCs on all processes waiting for them.
21332     */
21333    final void performAppGcsIfAppropriateLocked() {
21334        if (canGcNowLocked()) {
21335            performAppGcsLocked();
21336            return;
21337        }
21338        // Still not idle, wait some more.
21339        scheduleAppGcsLocked();
21340    }
21341
21342    /**
21343     * Schedule the execution of all pending app GCs.
21344     */
21345    final void scheduleAppGcsLocked() {
21346        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21347
21348        if (mProcessesToGc.size() > 0) {
21349            // Schedule a GC for the time to the next process.
21350            ProcessRecord proc = mProcessesToGc.get(0);
21351            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21352
21353            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
21354            long now = SystemClock.uptimeMillis();
21355            if (when < (now+GC_TIMEOUT)) {
21356                when = now + GC_TIMEOUT;
21357            }
21358            mHandler.sendMessageAtTime(msg, when);
21359        }
21360    }
21361
21362    /**
21363     * Add a process to the array of processes waiting to be GCed.  Keeps the
21364     * list in sorted order by the last GC time.  The process can't already be
21365     * on the list.
21366     */
21367    final void addProcessToGcListLocked(ProcessRecord proc) {
21368        boolean added = false;
21369        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21370            if (mProcessesToGc.get(i).lastRequestedGc <
21371                    proc.lastRequestedGc) {
21372                added = true;
21373                mProcessesToGc.add(i+1, proc);
21374                break;
21375            }
21376        }
21377        if (!added) {
21378            mProcessesToGc.add(0, proc);
21379        }
21380    }
21381
21382    /**
21383     * Set up to ask a process to GC itself.  This will either do it
21384     * immediately, or put it on the list of processes to gc the next
21385     * time things are idle.
21386     */
21387    final void scheduleAppGcLocked(ProcessRecord app) {
21388        long now = SystemClock.uptimeMillis();
21389        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
21390            return;
21391        }
21392        if (!mProcessesToGc.contains(app)) {
21393            addProcessToGcListLocked(app);
21394            scheduleAppGcsLocked();
21395        }
21396    }
21397
21398    final void checkExcessivePowerUsageLocked(boolean doKills) {
21399        updateCpuStatsNow();
21400
21401        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21402        boolean doWakeKills = doKills;
21403        boolean doCpuKills = doKills;
21404        if (mLastPowerCheckRealtime == 0) {
21405            doWakeKills = false;
21406        }
21407        if (mLastPowerCheckUptime == 0) {
21408            doCpuKills = false;
21409        }
21410        if (stats.isScreenOn()) {
21411            doWakeKills = false;
21412        }
21413        final long curRealtime = SystemClock.elapsedRealtime();
21414        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
21415        final long curUptime = SystemClock.uptimeMillis();
21416        final long uptimeSince = curUptime - mLastPowerCheckUptime;
21417        mLastPowerCheckRealtime = curRealtime;
21418        mLastPowerCheckUptime = curUptime;
21419        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
21420            doWakeKills = false;
21421        }
21422        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
21423            doCpuKills = false;
21424        }
21425        int i = mLruProcesses.size();
21426        while (i > 0) {
21427            i--;
21428            ProcessRecord app = mLruProcesses.get(i);
21429            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21430                long wtime;
21431                synchronized (stats) {
21432                    wtime = stats.getProcessWakeTime(app.info.uid,
21433                            app.pid, curRealtime);
21434                }
21435                long wtimeUsed = wtime - app.lastWakeTime;
21436                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21437                if (DEBUG_POWER) {
21438                    StringBuilder sb = new StringBuilder(128);
21439                    sb.append("Wake for ");
21440                    app.toShortString(sb);
21441                    sb.append(": over ");
21442                    TimeUtils.formatDuration(realtimeSince, sb);
21443                    sb.append(" used ");
21444                    TimeUtils.formatDuration(wtimeUsed, sb);
21445                    sb.append(" (");
21446                    sb.append((wtimeUsed*100)/realtimeSince);
21447                    sb.append("%)");
21448                    Slog.i(TAG_POWER, sb.toString());
21449                    sb.setLength(0);
21450                    sb.append("CPU for ");
21451                    app.toShortString(sb);
21452                    sb.append(": over ");
21453                    TimeUtils.formatDuration(uptimeSince, sb);
21454                    sb.append(" used ");
21455                    TimeUtils.formatDuration(cputimeUsed, sb);
21456                    sb.append(" (");
21457                    sb.append((cputimeUsed*100)/uptimeSince);
21458                    sb.append("%)");
21459                    Slog.i(TAG_POWER, sb.toString());
21460                }
21461                // If a process has held a wake lock for more
21462                // than 50% of the time during this period,
21463                // that sounds bad.  Kill!
21464                if (doWakeKills && realtimeSince > 0
21465                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
21466                    synchronized (stats) {
21467                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
21468                                realtimeSince, wtimeUsed);
21469                    }
21470                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
21471                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
21472                } else if (doCpuKills && uptimeSince > 0
21473                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
21474                    synchronized (stats) {
21475                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21476                                uptimeSince, cputimeUsed);
21477                    }
21478                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
21479                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21480                } else {
21481                    app.lastWakeTime = wtime;
21482                    app.lastCpuTime = app.curCpuTime;
21483                }
21484            }
21485        }
21486    }
21487
21488    private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
21489            long nowElapsed) {
21490        boolean success = true;
21491
21492        if (app.curRawAdj != app.setRawAdj) {
21493            app.setRawAdj = app.curRawAdj;
21494        }
21495
21496        int changes = 0;
21497
21498        if (app.curAdj != app.setAdj) {
21499            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
21500            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21501                    "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
21502                    + app.adjType);
21503            app.setAdj = app.curAdj;
21504            app.verifiedAdj = ProcessList.INVALID_ADJ;
21505        }
21506
21507        if (app.setSchedGroup != app.curSchedGroup) {
21508            int oldSchedGroup = app.setSchedGroup;
21509            app.setSchedGroup = app.curSchedGroup;
21510            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21511                    "Setting sched group of " + app.processName
21512                    + " to " + app.curSchedGroup);
21513            if (app.waitingToKill != null && app.curReceivers.isEmpty()
21514                    && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
21515                app.kill(app.waitingToKill, true);
21516                success = false;
21517            } else {
21518                int processGroup;
21519                switch (app.curSchedGroup) {
21520                    case ProcessList.SCHED_GROUP_BACKGROUND:
21521                        processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
21522                        break;
21523                    case ProcessList.SCHED_GROUP_TOP_APP:
21524                    case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
21525                        processGroup = Process.THREAD_GROUP_TOP_APP;
21526                        break;
21527                    default:
21528                        processGroup = Process.THREAD_GROUP_DEFAULT;
21529                        break;
21530                }
21531                long oldId = Binder.clearCallingIdentity();
21532                try {
21533                    Process.setProcessGroup(app.pid, processGroup);
21534                    if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
21535                        // do nothing if we already switched to RT
21536                        if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21537                            // Switch VR thread for app to SCHED_FIFO
21538                            if (mVrState == VR_MODE && app.vrThreadTid != 0) {
21539                                try {
21540                                    Process.setThreadScheduler(app.vrThreadTid,
21541                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
21542                                    mTopAppVrThreadTid = app.vrThreadTid;
21543                                } catch (IllegalArgumentException e) {
21544                                    // thread died, ignore
21545                                }
21546                            }
21547                            if (mUseFifoUiScheduling) {
21548                                // Switch UI pipeline for app to SCHED_FIFO
21549                                app.savedPriority = Process.getThreadPriority(app.pid);
21550                                try {
21551                                    Process.setThreadScheduler(app.pid,
21552                                        Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
21553                                } catch (IllegalArgumentException e) {
21554                                    // thread died, ignore
21555                                }
21556                                if (app.renderThreadTid != 0) {
21557                                    try {
21558                                        Process.setThreadScheduler(app.renderThreadTid,
21559                                            Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
21560                                    } catch (IllegalArgumentException e) {
21561                                        // thread died, ignore
21562                                    }
21563                                    if (DEBUG_OOM_ADJ) {
21564                                        Slog.d("UI_FIFO", "Set RenderThread (TID " +
21565                                            app.renderThreadTid + ") to FIFO");
21566                                    }
21567                                } else {
21568                                    if (DEBUG_OOM_ADJ) {
21569                                        Slog.d("UI_FIFO", "Not setting RenderThread TID");
21570                                    }
21571                                }
21572                            } else {
21573                                // Boost priority for top app UI and render threads
21574                                Process.setThreadPriority(app.pid, -10);
21575                                if (app.renderThreadTid != 0) {
21576                                    try {
21577                                        Process.setThreadPriority(app.renderThreadTid, -10);
21578                                    } catch (IllegalArgumentException e) {
21579                                        // thread died, ignore
21580                                    }
21581                                }
21582                            }
21583                        }
21584                    } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
21585                               app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
21586                        // Reset VR thread to SCHED_OTHER
21587                        // Safe to do even if we're not in VR mode
21588                        if (app.vrThreadTid != 0) {
21589                            Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
21590                            mTopAppVrThreadTid = 0;
21591                        }
21592                        if (mUseFifoUiScheduling) {
21593                            // Reset UI pipeline to SCHED_OTHER
21594                            Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
21595                            Process.setThreadPriority(app.pid, app.savedPriority);
21596                            if (app.renderThreadTid != 0) {
21597                                Process.setThreadScheduler(app.renderThreadTid,
21598                                    Process.SCHED_OTHER, 0);
21599                                Process.setThreadPriority(app.renderThreadTid, -4);
21600                            }
21601                        } else {
21602                            // Reset priority for top app UI and render threads
21603                            Process.setThreadPriority(app.pid, 0);
21604                            if (app.renderThreadTid != 0) {
21605                                Process.setThreadPriority(app.renderThreadTid, 0);
21606                            }
21607                        }
21608                    }
21609                } catch (Exception e) {
21610                    Slog.w(TAG, "Failed setting process group of " + app.pid
21611                            + " to " + app.curSchedGroup);
21612                    e.printStackTrace();
21613                } finally {
21614                    Binder.restoreCallingIdentity(oldId);
21615                }
21616            }
21617        }
21618        if (app.repForegroundActivities != app.foregroundActivities) {
21619            app.repForegroundActivities = app.foregroundActivities;
21620            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
21621        }
21622        if (app.repProcState != app.curProcState) {
21623            app.repProcState = app.curProcState;
21624            if (app.thread != null) {
21625                try {
21626                    if (false) {
21627                        //RuntimeException h = new RuntimeException("here");
21628                        Slog.i(TAG, "Sending new process state " + app.repProcState
21629                                + " to " + app /*, h*/);
21630                    }
21631                    app.thread.setProcessState(app.repProcState);
21632                } catch (RemoteException e) {
21633                }
21634            }
21635        }
21636        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
21637                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
21638            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
21639                // Experimental code to more aggressively collect pss while
21640                // running test...  the problem is that this tends to collect
21641                // the data right when a process is transitioning between process
21642                // states, which well tend to give noisy data.
21643                long start = SystemClock.uptimeMillis();
21644                long pss = Debug.getPss(app.pid, mTmpLong, null);
21645                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
21646                mPendingPssProcesses.remove(app);
21647                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
21648                        + " to " + app.curProcState + ": "
21649                        + (SystemClock.uptimeMillis()-start) + "ms");
21650            }
21651            app.lastStateTime = now;
21652            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21653                    mTestPssMode, isSleepingLocked(), now);
21654            if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
21655                    + ProcessList.makeProcStateString(app.setProcState) + " to "
21656                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
21657                    + (app.nextPssTime-now) + ": " + app);
21658        } else {
21659            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
21660                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
21661                    mTestPssMode)))) {
21662                requestPssLocked(app, app.setProcState);
21663                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
21664                        mTestPssMode, isSleepingLocked(), now);
21665            } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
21666                    "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
21667        }
21668        if (app.setProcState != app.curProcState) {
21669            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21670                    "Proc state change of " + app.processName
21671                            + " to " + app.curProcState);
21672            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
21673            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
21674            if (setImportant && !curImportant) {
21675                // This app is no longer something we consider important enough to allow to
21676                // use arbitrary amounts of battery power.  Note
21677                // its current wake lock time to later know to kill it if
21678                // it is not behaving well.
21679                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21680                synchronized (stats) {
21681                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
21682                            app.pid, nowElapsed);
21683                }
21684                app.lastCpuTime = app.curCpuTime;
21685
21686            }
21687            // Inform UsageStats of important process state change
21688            // Must be called before updating setProcState
21689            maybeUpdateUsageStatsLocked(app, nowElapsed);
21690
21691            app.setProcState = app.curProcState;
21692            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21693                app.notCachedSinceIdle = false;
21694            }
21695            if (!doingAll) {
21696                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
21697            } else {
21698                app.procStateChanged = true;
21699            }
21700        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
21701                > USAGE_STATS_INTERACTION_INTERVAL) {
21702            // For apps that sit around for a long time in the interactive state, we need
21703            // to report this at least once a day so they don't go idle.
21704            maybeUpdateUsageStatsLocked(app, nowElapsed);
21705        }
21706
21707        if (changes != 0) {
21708            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21709                    "Changes in " + app + ": " + changes);
21710            int i = mPendingProcessChanges.size()-1;
21711            ProcessChangeItem item = null;
21712            while (i >= 0) {
21713                item = mPendingProcessChanges.get(i);
21714                if (item.pid == app.pid) {
21715                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21716                            "Re-using existing item: " + item);
21717                    break;
21718                }
21719                i--;
21720            }
21721            if (i < 0) {
21722                // No existing item in pending changes; need a new one.
21723                final int NA = mAvailProcessChanges.size();
21724                if (NA > 0) {
21725                    item = mAvailProcessChanges.remove(NA-1);
21726                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21727                            "Retrieving available item: " + item);
21728                } else {
21729                    item = new ProcessChangeItem();
21730                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21731                            "Allocating new item: " + item);
21732                }
21733                item.changes = 0;
21734                item.pid = app.pid;
21735                item.uid = app.info.uid;
21736                if (mPendingProcessChanges.size() == 0) {
21737                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21738                            "*** Enqueueing dispatch processes changed!");
21739                    mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
21740                }
21741                mPendingProcessChanges.add(item);
21742            }
21743            item.changes |= changes;
21744            item.foregroundActivities = app.repForegroundActivities;
21745            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
21746                    "Item " + Integer.toHexString(System.identityHashCode(item))
21747                    + " " + app.toShortString() + ": changes=" + item.changes
21748                    + " foreground=" + item.foregroundActivities
21749                    + " type=" + app.adjType + " source=" + app.adjSource
21750                    + " target=" + app.adjTarget);
21751        }
21752
21753        return success;
21754    }
21755
21756    private boolean isEphemeralLocked(int uid) {
21757        String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
21758        if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
21759            return false;
21760        }
21761        return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
21762                packages[0]);
21763    }
21764
21765    @VisibleForTesting
21766    final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
21767        final UidRecord.ChangeItem pendingChange;
21768        if (uidRec == null || uidRec.pendingChange == null) {
21769            if (mPendingUidChanges.size() == 0) {
21770                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21771                        "*** Enqueueing dispatch uid changed!");
21772                mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
21773            }
21774            final int NA = mAvailUidChanges.size();
21775            if (NA > 0) {
21776                pendingChange = mAvailUidChanges.remove(NA-1);
21777                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21778                        "Retrieving available item: " + pendingChange);
21779            } else {
21780                pendingChange = new UidRecord.ChangeItem();
21781                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21782                        "Allocating new item: " + pendingChange);
21783            }
21784            if (uidRec != null) {
21785                uidRec.pendingChange = pendingChange;
21786                if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
21787                    // If this uid is going away, and we haven't yet reported it is gone,
21788                    // then do so now.
21789                    change = UidRecord.CHANGE_GONE_IDLE;
21790                }
21791            } else if (uid < 0) {
21792                throw new IllegalArgumentException("No UidRecord or uid");
21793            }
21794            pendingChange.uidRecord = uidRec;
21795            pendingChange.uid = uidRec != null ? uidRec.uid : uid;
21796            mPendingUidChanges.add(pendingChange);
21797        } else {
21798            pendingChange = uidRec.pendingChange;
21799            if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
21800                change = UidRecord.CHANGE_GONE_IDLE;
21801            }
21802        }
21803        pendingChange.change = change;
21804        pendingChange.processState = uidRec != null
21805                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
21806        pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
21807        pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
21808        if (uidRec != null) {
21809            uidRec.updateLastDispatchedProcStateSeq(change);
21810        }
21811
21812        // Directly update the power manager, since we sit on top of it and it is critical
21813        // it be kept in sync (so wake locks will be held as soon as appropriate).
21814        if (mLocalPowerManager != null) {
21815            switch (change) {
21816                case UidRecord.CHANGE_GONE:
21817                case UidRecord.CHANGE_GONE_IDLE:
21818                    mLocalPowerManager.uidGone(pendingChange.uid);
21819                    break;
21820                case UidRecord.CHANGE_IDLE:
21821                    mLocalPowerManager.uidIdle(pendingChange.uid);
21822                    break;
21823                case UidRecord.CHANGE_ACTIVE:
21824                    mLocalPowerManager.uidActive(pendingChange.uid);
21825                    break;
21826                default:
21827                    mLocalPowerManager.updateUidProcState(pendingChange.uid,
21828                            pendingChange.processState);
21829                    break;
21830            }
21831        }
21832    }
21833
21834    private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
21835            String authority) {
21836        if (app == null) return;
21837        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21838            UserState userState = mUserController.getStartedUserStateLocked(app.userId);
21839            if (userState == null) return;
21840            final long now = SystemClock.elapsedRealtime();
21841            Long lastReported = userState.mProviderLastReportedFg.get(authority);
21842            if (lastReported == null || lastReported < now - 60 * 1000L) {
21843                if (mSystemReady) {
21844                    // Cannot touch the user stats if not system ready
21845                    mUsageStatsService.reportContentProviderUsage(
21846                            authority, providerPkgName, app.userId);
21847                }
21848                userState.mProviderLastReportedFg.put(authority, now);
21849            }
21850        }
21851    }
21852
21853    private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
21854        if (DEBUG_USAGE_STATS) {
21855            Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
21856                    + "] state changes: old = " + app.setProcState + ", new = "
21857                    + app.curProcState);
21858        }
21859        if (mUsageStatsService == null) {
21860            return;
21861        }
21862        boolean isInteraction;
21863        // To avoid some abuse patterns, we are going to be careful about what we consider
21864        // to be an app interaction.  Being the top activity doesn't count while the display
21865        // is sleeping, nor do short foreground services.
21866        if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
21867            isInteraction = true;
21868            app.fgInteractionTime = 0;
21869        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
21870            if (app.fgInteractionTime == 0) {
21871                app.fgInteractionTime = nowElapsed;
21872                isInteraction = false;
21873            } else {
21874                isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
21875            }
21876        } else {
21877            // If the app was being forced to the foreground, by say a Toast, then
21878            // no need to treat it as an interaction
21879            isInteraction = app.forcingToForeground == null
21880                    && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21881            app.fgInteractionTime = 0;
21882        }
21883        if (isInteraction && (!app.reportedInteraction
21884                || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
21885            app.interactionEventTime = nowElapsed;
21886            String[] packages = app.getPackageList();
21887            if (packages != null) {
21888                for (int i = 0; i < packages.length; i++) {
21889                    mUsageStatsService.reportEvent(packages[i], app.userId,
21890                            UsageEvents.Event.SYSTEM_INTERACTION);
21891                }
21892            }
21893        }
21894        app.reportedInteraction = isInteraction;
21895        if (!isInteraction) {
21896            app.interactionEventTime = 0;
21897        }
21898    }
21899
21900    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
21901        if (proc.thread != null) {
21902            if (proc.baseProcessTracker != null) {
21903                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
21904            }
21905        }
21906    }
21907
21908    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
21909            ProcessRecord TOP_APP, boolean doingAll, long now) {
21910        if (app.thread == null) {
21911            return false;
21912        }
21913
21914        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
21915
21916        return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
21917    }
21918
21919    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
21920            boolean oomAdj) {
21921        if (isForeground != proc.foregroundServices) {
21922            proc.foregroundServices = isForeground;
21923            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
21924                    proc.info.uid);
21925            if (isForeground) {
21926                if (curProcs == null) {
21927                    curProcs = new ArrayList<ProcessRecord>();
21928                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
21929                }
21930                if (!curProcs.contains(proc)) {
21931                    curProcs.add(proc);
21932                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
21933                            proc.info.packageName, proc.info.uid);
21934                }
21935            } else {
21936                if (curProcs != null) {
21937                    if (curProcs.remove(proc)) {
21938                        mBatteryStatsService.noteEvent(
21939                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
21940                                proc.info.packageName, proc.info.uid);
21941                        if (curProcs.size() <= 0) {
21942                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
21943                        }
21944                    }
21945                }
21946            }
21947            if (oomAdj) {
21948                updateOomAdjLocked();
21949            }
21950        }
21951    }
21952
21953    private final ActivityRecord resumedAppLocked() {
21954        ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
21955        String pkg;
21956        int uid;
21957        if (act != null) {
21958            pkg = act.packageName;
21959            uid = act.info.applicationInfo.uid;
21960        } else {
21961            pkg = null;
21962            uid = -1;
21963        }
21964        // Has the UID or resumed package name changed?
21965        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
21966                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
21967            if (mCurResumedPackage != null) {
21968                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
21969                        mCurResumedPackage, mCurResumedUid);
21970            }
21971            mCurResumedPackage = pkg;
21972            mCurResumedUid = uid;
21973            if (mCurResumedPackage != null) {
21974                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
21975                        mCurResumedPackage, mCurResumedUid);
21976            }
21977        }
21978        return act;
21979    }
21980
21981    final boolean updateOomAdjLocked(ProcessRecord app) {
21982        final ActivityRecord TOP_ACT = resumedAppLocked();
21983        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
21984        final boolean wasCached = app.cached;
21985
21986        mAdjSeq++;
21987
21988        // This is the desired cached adjusment we want to tell it to use.
21989        // If our app is currently cached, we know it, and that is it.  Otherwise,
21990        // we don't know it yet, and it needs to now be cached we will then
21991        // need to do a complete oom adj.
21992        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
21993                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
21994        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
21995                SystemClock.uptimeMillis());
21996        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
21997            // Changed to/from cached state, so apps after it in the LRU
21998            // list may also be changed.
21999            updateOomAdjLocked();
22000        }
22001        return success;
22002    }
22003
22004    final void updateOomAdjLocked() {
22005        final ActivityRecord TOP_ACT = resumedAppLocked();
22006        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22007        final long now = SystemClock.uptimeMillis();
22008        final long nowElapsed = SystemClock.elapsedRealtime();
22009        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22010        final int N = mLruProcesses.size();
22011
22012        if (false) {
22013            RuntimeException e = new RuntimeException();
22014            e.fillInStackTrace();
22015            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22016        }
22017
22018        // Reset state in all uid records.
22019        for (int i=mActiveUids.size()-1; i>=0; i--) {
22020            final UidRecord uidRec = mActiveUids.valueAt(i);
22021            if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22022                    "Starting update of " + uidRec);
22023            uidRec.reset();
22024        }
22025
22026        mStackSupervisor.rankTaskLayersIfNeeded();
22027
22028        mAdjSeq++;
22029        mNewNumServiceProcs = 0;
22030        mNewNumAServiceProcs = 0;
22031
22032        final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22033        final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22034
22035        // Let's determine how many processes we have running vs.
22036        // how many slots we have for background processes; we may want
22037        // to put multiple processes in a slot of there are enough of
22038        // them.
22039        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22040                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22041        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22042        if (numEmptyProcs > cachedProcessLimit) {
22043            // If there are more empty processes than our limit on cached
22044            // processes, then use the cached process limit for the factor.
22045            // This ensures that the really old empty processes get pushed
22046            // down to the bottom, so if we are running low on memory we will
22047            // have a better chance at keeping around more cached processes
22048            // instead of a gazillion empty processes.
22049            numEmptyProcs = cachedProcessLimit;
22050        }
22051        int emptyFactor = numEmptyProcs/numSlots;
22052        if (emptyFactor < 1) emptyFactor = 1;
22053        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22054        if (cachedFactor < 1) cachedFactor = 1;
22055        int stepCached = 0;
22056        int stepEmpty = 0;
22057        int numCached = 0;
22058        int numEmpty = 0;
22059        int numTrimming = 0;
22060
22061        mNumNonCachedProcs = 0;
22062        mNumCachedHiddenProcs = 0;
22063
22064        // First update the OOM adjustment for each of the
22065        // application processes based on their current state.
22066        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22067        int nextCachedAdj = curCachedAdj+1;
22068        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22069        int nextEmptyAdj = curEmptyAdj+2;
22070        for (int i=N-1; i>=0; i--) {
22071            ProcessRecord app = mLruProcesses.get(i);
22072            if (!app.killedByAm && app.thread != null) {
22073                app.procStateChanged = false;
22074                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22075
22076                // If we haven't yet assigned the final cached adj
22077                // to the process, do that now.
22078                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22079                    switch (app.curProcState) {
22080                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22081                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22082                            // This process is a cached process holding activities...
22083                            // assign it the next cached value for that type, and then
22084                            // step that cached level.
22085                            app.curRawAdj = curCachedAdj;
22086                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22087                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22088                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22089                                    + ")");
22090                            if (curCachedAdj != nextCachedAdj) {
22091                                stepCached++;
22092                                if (stepCached >= cachedFactor) {
22093                                    stepCached = 0;
22094                                    curCachedAdj = nextCachedAdj;
22095                                    nextCachedAdj += 2;
22096                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22097                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22098                                    }
22099                                }
22100                            }
22101                            break;
22102                        default:
22103                            // For everything else, assign next empty cached process
22104                            // level and bump that up.  Note that this means that
22105                            // long-running services that have dropped down to the
22106                            // cached level will be treated as empty (since their process
22107                            // state is still as a service), which is what we want.
22108                            app.curRawAdj = curEmptyAdj;
22109                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22110                            if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22111                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22112                                    + ")");
22113                            if (curEmptyAdj != nextEmptyAdj) {
22114                                stepEmpty++;
22115                                if (stepEmpty >= emptyFactor) {
22116                                    stepEmpty = 0;
22117                                    curEmptyAdj = nextEmptyAdj;
22118                                    nextEmptyAdj += 2;
22119                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22120                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22121                                    }
22122                                }
22123                            }
22124                            break;
22125                    }
22126                }
22127
22128                applyOomAdjLocked(app, true, now, nowElapsed);
22129
22130                // Count the number of process types.
22131                switch (app.curProcState) {
22132                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22133                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22134                        mNumCachedHiddenProcs++;
22135                        numCached++;
22136                        if (numCached > cachedProcessLimit) {
22137                            app.kill("cached #" + numCached, true);
22138                        }
22139                        break;
22140                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22141                        if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22142                                && app.lastActivityTime < oldTime) {
22143                            app.kill("empty for "
22144                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22145                                    / 1000) + "s", true);
22146                        } else {
22147                            numEmpty++;
22148                            if (numEmpty > emptyProcessLimit) {
22149                                app.kill("empty #" + numEmpty, true);
22150                            }
22151                        }
22152                        break;
22153                    default:
22154                        mNumNonCachedProcs++;
22155                        break;
22156                }
22157
22158                if (app.isolated && app.services.size() <= 0) {
22159                    // If this is an isolated process, and there are no
22160                    // services running in it, then the process is no longer
22161                    // needed.  We agressively kill these because we can by
22162                    // definition not re-use the same process again, and it is
22163                    // good to avoid having whatever code was running in them
22164                    // left sitting around after no longer needed.
22165                    app.kill("isolated not needed", true);
22166                } else {
22167                    // Keeping this process, update its uid.
22168                    final UidRecord uidRec = app.uidRecord;
22169                    if (uidRec != null) {
22170                        uidRec.ephemeral = app.info.isInstantApp();
22171                        if (uidRec.curProcState > app.curProcState) {
22172                            uidRec.curProcState = app.curProcState;
22173                        }
22174                    }
22175                }
22176
22177                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22178                        && !app.killedByAm) {
22179                    numTrimming++;
22180                }
22181            }
22182        }
22183
22184        incrementProcStateSeqAndNotifyAppsLocked();
22185
22186        mNumServiceProcs = mNewNumServiceProcs;
22187
22188        // Now determine the memory trimming level of background processes.
22189        // Unfortunately we need to start at the back of the list to do this
22190        // properly.  We only do this if the number of background apps we
22191        // are managing to keep around is less than half the maximum we desire;
22192        // if we are keeping a good number around, we'll let them use whatever
22193        // memory they want.
22194        final int numCachedAndEmpty = numCached + numEmpty;
22195        int memFactor;
22196        if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22197                && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22198            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22199                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22200            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22201                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22202            } else {
22203                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22204            }
22205        } else {
22206            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22207        }
22208        // We always allow the memory level to go up (better).  We only allow it to go
22209        // down if we are in a state where that is allowed, *and* the total number of processes
22210        // has gone down since last time.
22211        if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22212                + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22213                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22214        if (memFactor > mLastMemoryLevel) {
22215            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22216                memFactor = mLastMemoryLevel;
22217                if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22218            }
22219        }
22220        if (memFactor != mLastMemoryLevel) {
22221            EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22222        }
22223        mLastMemoryLevel = memFactor;
22224        mLastNumProcesses = mLruProcesses.size();
22225        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22226        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22227        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22228            if (mLowRamStartTime == 0) {
22229                mLowRamStartTime = now;
22230            }
22231            int step = 0;
22232            int fgTrimLevel;
22233            switch (memFactor) {
22234                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22235                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22236                    break;
22237                case ProcessStats.ADJ_MEM_FACTOR_LOW:
22238                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22239                    break;
22240                default:
22241                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22242                    break;
22243            }
22244            int factor = numTrimming/3;
22245            int minFactor = 2;
22246            if (mHomeProcess != null) minFactor++;
22247            if (mPreviousProcess != null) minFactor++;
22248            if (factor < minFactor) factor = minFactor;
22249            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22250            for (int i=N-1; i>=0; i--) {
22251                ProcessRecord app = mLruProcesses.get(i);
22252                if (allChanged || app.procStateChanged) {
22253                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22254                    app.procStateChanged = false;
22255                }
22256                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22257                        && !app.killedByAm) {
22258                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
22259                        try {
22260                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22261                                    "Trimming memory of " + app.processName + " to " + curLevel);
22262                            app.thread.scheduleTrimMemory(curLevel);
22263                        } catch (RemoteException e) {
22264                        }
22265                        if (false) {
22266                            // For now we won't do this; our memory trimming seems
22267                            // to be good enough at this point that destroying
22268                            // activities causes more harm than good.
22269                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22270                                    && app != mHomeProcess && app != mPreviousProcess) {
22271                                // Need to do this on its own message because the stack may not
22272                                // be in a consistent state at this point.
22273                                // For these apps we will also finish their activities
22274                                // to help them free memory.
22275                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22276                            }
22277                        }
22278                    }
22279                    app.trimMemoryLevel = curLevel;
22280                    step++;
22281                    if (step >= factor) {
22282                        step = 0;
22283                        switch (curLevel) {
22284                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22285                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22286                                break;
22287                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22288                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22289                                break;
22290                        }
22291                    }
22292                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22293                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22294                            && app.thread != null) {
22295                        try {
22296                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22297                                    "Trimming memory of heavy-weight " + app.processName
22298                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22299                            app.thread.scheduleTrimMemory(
22300                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22301                        } catch (RemoteException e) {
22302                        }
22303                    }
22304                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22305                } else {
22306                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22307                            || app.systemNoUi) && app.pendingUiClean) {
22308                        // If this application is now in the background and it
22309                        // had done UI, then give it the special trim level to
22310                        // have it free UI resources.
22311                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22312                        if (app.trimMemoryLevel < level && app.thread != null) {
22313                            try {
22314                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22315                                        "Trimming memory of bg-ui " + app.processName
22316                                        + " to " + level);
22317                                app.thread.scheduleTrimMemory(level);
22318                            } catch (RemoteException e) {
22319                            }
22320                        }
22321                        app.pendingUiClean = false;
22322                    }
22323                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22324                        try {
22325                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22326                                    "Trimming memory of fg " + app.processName
22327                                    + " to " + fgTrimLevel);
22328                            app.thread.scheduleTrimMemory(fgTrimLevel);
22329                        } catch (RemoteException e) {
22330                        }
22331                    }
22332                    app.trimMemoryLevel = fgTrimLevel;
22333                }
22334            }
22335        } else {
22336            if (mLowRamStartTime != 0) {
22337                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22338                mLowRamStartTime = 0;
22339            }
22340            for (int i=N-1; i>=0; i--) {
22341                ProcessRecord app = mLruProcesses.get(i);
22342                if (allChanged || app.procStateChanged) {
22343                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
22344                    app.procStateChanged = false;
22345                }
22346                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22347                        || app.systemNoUi) && app.pendingUiClean) {
22348                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22349                            && app.thread != null) {
22350                        try {
22351                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22352                                    "Trimming memory of ui hidden " + app.processName
22353                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22354                            app.thread.scheduleTrimMemory(
22355                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22356                        } catch (RemoteException e) {
22357                        }
22358                    }
22359                    app.pendingUiClean = false;
22360                }
22361                app.trimMemoryLevel = 0;
22362            }
22363        }
22364
22365        if (mAlwaysFinishActivities) {
22366            // Need to do this on its own message because the stack may not
22367            // be in a consistent state at this point.
22368            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22369        }
22370
22371        if (allChanged) {
22372            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22373        }
22374
22375        // Update from any uid changes.
22376        if (mLocalPowerManager != null) {
22377            mLocalPowerManager.startUidChanges();
22378        }
22379        for (int i=mActiveUids.size()-1; i>=0; i--) {
22380            final UidRecord uidRec = mActiveUids.valueAt(i);
22381            int uidChange = UidRecord.CHANGE_PROCSTATE;
22382            if (uidRec.setProcState != uidRec.curProcState
22383                    || uidRec.setWhitelist != uidRec.curWhitelist) {
22384                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22385                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22386                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22387                        + " to " + uidRec.curWhitelist);
22388                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22389                        && !uidRec.curWhitelist) {
22390                    // UID is now in the background (and not on the temp whitelist).  Was it
22391                    // previously in the foreground (or on the temp whitelist)?
22392                    if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22393                            || uidRec.setWhitelist) {
22394                        uidRec.lastBackgroundTime = nowElapsed;
22395                        if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22396                            // Note: the background settle time is in elapsed realtime, while
22397                            // the handler time base is uptime.  All this means is that we may
22398                            // stop background uids later than we had intended, but that only
22399                            // happens because the device was sleeping so we are okay anyway.
22400                            mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
22401                        }
22402                    }
22403                } else {
22404                    if (uidRec.idle) {
22405                        uidChange = UidRecord.CHANGE_ACTIVE;
22406                        uidRec.idle = false;
22407                    }
22408                    uidRec.lastBackgroundTime = 0;
22409                }
22410                uidRec.setProcState = uidRec.curProcState;
22411                uidRec.setWhitelist = uidRec.curWhitelist;
22412                enqueueUidChangeLocked(uidRec, -1, uidChange);
22413                noteUidProcessState(uidRec.uid, uidRec.curProcState);
22414            }
22415        }
22416        if (mLocalPowerManager != null) {
22417            mLocalPowerManager.finishUidChanges();
22418        }
22419
22420        if (mProcessStats.shouldWriteNowLocked(now)) {
22421            mHandler.post(new Runnable() {
22422                @Override public void run() {
22423                    synchronized (ActivityManagerService.this) {
22424                        mProcessStats.writeStateAsyncLocked();
22425                    }
22426                }
22427            });
22428        }
22429
22430        if (DEBUG_OOM_ADJ) {
22431            final long duration = SystemClock.uptimeMillis() - now;
22432            if (false) {
22433                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22434                        new RuntimeException("here").fillInStackTrace());
22435            } else {
22436                Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
22437            }
22438        }
22439    }
22440
22441    @Override
22442    public void makePackageIdle(String packageName, int userId) {
22443        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
22444                != PackageManager.PERMISSION_GRANTED) {
22445            String msg = "Permission Denial: makePackageIdle() from pid="
22446                    + Binder.getCallingPid()
22447                    + ", uid=" + Binder.getCallingUid()
22448                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
22449            Slog.w(TAG, msg);
22450            throw new SecurityException(msg);
22451        }
22452        final int callingPid = Binder.getCallingPid();
22453        userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
22454                userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
22455        long callingId = Binder.clearCallingIdentity();
22456        synchronized(this) {
22457            try {
22458                IPackageManager pm = AppGlobals.getPackageManager();
22459                int pkgUid = -1;
22460                try {
22461                    pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
22462                            | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
22463                } catch (RemoteException e) {
22464                }
22465                if (pkgUid == -1) {
22466                    throw new IllegalArgumentException("Unknown package name " + packageName);
22467                }
22468
22469                if (mLocalPowerManager != null) {
22470                    mLocalPowerManager.startUidChanges();
22471                }
22472                final int appId = UserHandle.getAppId(pkgUid);
22473                final int N = mActiveUids.size();
22474                for (int i=N-1; i>=0; i--) {
22475                    final UidRecord uidRec = mActiveUids.valueAt(i);
22476                    final long bgTime = uidRec.lastBackgroundTime;
22477                    if (bgTime > 0 && !uidRec.idle) {
22478                        if (UserHandle.getAppId(uidRec.uid) == appId) {
22479                            if (userId == UserHandle.USER_ALL ||
22480                                    userId == UserHandle.getUserId(uidRec.uid)) {
22481                                uidRec.idle = true;
22482                                Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
22483                                        + " from package " + packageName + " user " + userId);
22484                                doStopUidLocked(uidRec.uid, uidRec);
22485                            }
22486                        }
22487                    }
22488                }
22489            } finally {
22490                if (mLocalPowerManager != null) {
22491                    mLocalPowerManager.finishUidChanges();
22492                }
22493                Binder.restoreCallingIdentity(callingId);
22494            }
22495        }
22496    }
22497
22498    final void idleUids() {
22499        synchronized (this) {
22500            final int N = mActiveUids.size();
22501            if (N <= 0) {
22502                return;
22503            }
22504            final long nowElapsed = SystemClock.elapsedRealtime();
22505            final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
22506            long nextTime = 0;
22507            if (mLocalPowerManager != null) {
22508                mLocalPowerManager.startUidChanges();
22509            }
22510            for (int i=N-1; i>=0; i--) {
22511                final UidRecord uidRec = mActiveUids.valueAt(i);
22512                final long bgTime = uidRec.lastBackgroundTime;
22513                if (bgTime > 0 && !uidRec.idle) {
22514                    if (bgTime <= maxBgTime) {
22515                        uidRec.idle = true;
22516                        doStopUidLocked(uidRec.uid, uidRec);
22517                    } else {
22518                        if (nextTime == 0 || nextTime > bgTime) {
22519                            nextTime = bgTime;
22520                        }
22521                    }
22522                }
22523            }
22524            if (mLocalPowerManager != null) {
22525                mLocalPowerManager.finishUidChanges();
22526            }
22527            if (nextTime > 0) {
22528                mHandler.removeMessages(IDLE_UIDS_MSG);
22529                mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22530                        nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
22531            }
22532        }
22533    }
22534
22535    /**
22536     * Checks if any uid is coming from background to foreground or vice versa and if so, increments
22537     * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
22538     * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
22539     */
22540    @VisibleForTesting
22541    @GuardedBy("this")
22542    void incrementProcStateSeqAndNotifyAppsLocked() {
22543        if (mWaitForNetworkTimeoutMs <= 0) {
22544            return;
22545        }
22546        // Used for identifying which uids need to block for network.
22547        ArrayList<Integer> blockingUids = null;
22548        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
22549            final UidRecord uidRec = mActiveUids.valueAt(i);
22550            // If the network is not restricted for uid, then nothing to do here.
22551            if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
22552                continue;
22553            }
22554            // If process state is not changed, then there's nothing to do.
22555            if (uidRec.setProcState == uidRec.curProcState) {
22556                continue;
22557            }
22558            final int blockState = getBlockStateForUid(uidRec);
22559            // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
22560            // there's nothing the app needs to do in this scenario.
22561            if (blockState == NETWORK_STATE_NO_CHANGE) {
22562                continue;
22563            }
22564            synchronized (uidRec.lock) {
22565                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
22566                if (blockState == NETWORK_STATE_BLOCK) {
22567                    if (blockingUids == null) {
22568                        blockingUids = new ArrayList<>();
22569                    }
22570                    blockingUids.add(uidRec.uid);
22571                } else {
22572                    if (DEBUG_NETWORK) {
22573                        Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
22574                                + " threads for uid: " + uidRec);
22575                    }
22576                    if (uidRec.waitingForNetwork) {
22577                        uidRec.lock.notifyAll();
22578                    }
22579                }
22580            }
22581        }
22582
22583        // There are no uids that need to block, so nothing more to do.
22584        if (blockingUids == null) {
22585            return;
22586        }
22587
22588        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
22589            final ProcessRecord app = mLruProcesses.get(i);
22590            if (!blockingUids.contains(app.uid)) {
22591                continue;
22592            }
22593            if (!app.killedByAm && app.thread != null) {
22594                final UidRecord uidRec = mActiveUids.get(app.uid);
22595                try {
22596                    if (DEBUG_NETWORK) {
22597                        Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
22598                                + uidRec);
22599                    }
22600                    app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
22601                } catch (RemoteException ignored) {
22602                }
22603            }
22604        }
22605    }
22606
22607    /**
22608     * Checks if the uid is coming from background to foreground or vice versa and returns
22609     * appropriate block state based on this.
22610     *
22611     * @return blockState based on whether the uid is coming from background to foreground or
22612     *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
22613     *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
22614     *         {@link #NETWORK_STATE_NO_CHANGE}.
22615     */
22616    @VisibleForTesting
22617    int getBlockStateForUid(UidRecord uidRec) {
22618        // Denotes whether uid's process state is currently allowed network access.
22619        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
22620                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
22621        // Denotes whether uid's process state was previously allowed network access.
22622        final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
22623                || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
22624
22625        // When the uid is coming to foreground, AMS should inform the app thread that it should
22626        // block for the network rules to get updated before launching an activity.
22627        if (!wasAllowed && isAllowed) {
22628            return NETWORK_STATE_BLOCK;
22629        }
22630        // When the uid is going to background, AMS should inform the app thread that if an
22631        // activity launch is blocked for the network rules to get updated, it should be unblocked.
22632        if (wasAllowed && !isAllowed) {
22633            return NETWORK_STATE_UNBLOCK;
22634        }
22635        return NETWORK_STATE_NO_CHANGE;
22636    }
22637
22638    final void runInBackgroundDisabled(int uid) {
22639        synchronized (this) {
22640            UidRecord uidRec = mActiveUids.get(uid);
22641            if (uidRec != null) {
22642                // This uid is actually running...  should it be considered background now?
22643                if (uidRec.idle) {
22644                    doStopUidLocked(uidRec.uid, uidRec);
22645                }
22646            } else {
22647                // This uid isn't actually running...  still send a report about it being "stopped".
22648                doStopUidLocked(uid, null);
22649            }
22650        }
22651    }
22652
22653    final void doStopUidLocked(int uid, final UidRecord uidRec) {
22654        mServices.stopInBackgroundLocked(uid);
22655        enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
22656    }
22657
22658    final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
22659        boolean changed = false;
22660        for (int i=mActiveUids.size()-1; i>=0; i--) {
22661            final UidRecord uidRec = mActiveUids.valueAt(i);
22662            if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
22663                uidRec.curWhitelist = onWhitelist;
22664                changed = true;
22665            }
22666        }
22667        if (changed) {
22668            updateOomAdjLocked();
22669        }
22670    }
22671
22672    final void trimApplications() {
22673        synchronized (this) {
22674            int i;
22675
22676            // First remove any unused application processes whose package
22677            // has been removed.
22678            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
22679                final ProcessRecord app = mRemovedProcesses.get(i);
22680                if (app.activities.size() == 0
22681                        && app.curReceivers.isEmpty() && app.services.size() == 0) {
22682                    Slog.i(
22683                        TAG, "Exiting empty application process "
22684                        + app.toShortString() + " ("
22685                        + (app.thread != null ? app.thread.asBinder() : null)
22686                        + ")\n");
22687                    if (app.pid > 0 && app.pid != MY_PID) {
22688                        app.kill("empty", false);
22689                    } else {
22690                        try {
22691                            app.thread.scheduleExit();
22692                        } catch (Exception e) {
22693                            // Ignore exceptions.
22694                        }
22695                    }
22696                    cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
22697                    mRemovedProcesses.remove(i);
22698
22699                    if (app.persistent) {
22700                        addAppLocked(app.info, null, false, null /* ABI override */);
22701                    }
22702                }
22703            }
22704
22705            // Now update the oom adj for all processes.
22706            updateOomAdjLocked();
22707        }
22708    }
22709
22710    /** This method sends the specified signal to each of the persistent apps */
22711    public void signalPersistentProcesses(int sig) throws RemoteException {
22712        if (sig != Process.SIGNAL_USR1) {
22713            throw new SecurityException("Only SIGNAL_USR1 is allowed");
22714        }
22715
22716        synchronized (this) {
22717            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
22718                    != PackageManager.PERMISSION_GRANTED) {
22719                throw new SecurityException("Requires permission "
22720                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
22721            }
22722
22723            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
22724                ProcessRecord r = mLruProcesses.get(i);
22725                if (r.thread != null && r.persistent) {
22726                    Process.sendSignal(r.pid, sig);
22727                }
22728            }
22729        }
22730    }
22731
22732    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
22733        if (proc == null || proc == mProfileProc) {
22734            proc = mProfileProc;
22735            profileType = mProfileType;
22736            clearProfilerLocked();
22737        }
22738        if (proc == null) {
22739            return;
22740        }
22741        try {
22742            proc.thread.profilerControl(false, null, profileType);
22743        } catch (RemoteException e) {
22744            throw new IllegalStateException("Process disappeared");
22745        }
22746    }
22747
22748    private void clearProfilerLocked() {
22749        if (mProfileFd != null) {
22750            try {
22751                mProfileFd.close();
22752            } catch (IOException e) {
22753            }
22754        }
22755        mProfileApp = null;
22756        mProfileProc = null;
22757        mProfileFile = null;
22758        mProfileType = 0;
22759        mAutoStopProfiler = false;
22760        mStreamingOutput = false;
22761        mSamplingInterval = 0;
22762    }
22763
22764    public boolean profileControl(String process, int userId, boolean start,
22765            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
22766
22767        try {
22768            synchronized (this) {
22769                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
22770                // its own permission.
22771                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22772                        != PackageManager.PERMISSION_GRANTED) {
22773                    throw new SecurityException("Requires permission "
22774                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22775                }
22776
22777                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
22778                    throw new IllegalArgumentException("null profile info or fd");
22779                }
22780
22781                ProcessRecord proc = null;
22782                if (process != null) {
22783                    proc = findProcessLocked(process, userId, "profileControl");
22784                }
22785
22786                if (start && (proc == null || proc.thread == null)) {
22787                    throw new IllegalArgumentException("Unknown process: " + process);
22788                }
22789
22790                if (start) {
22791                    stopProfilerLocked(null, 0);
22792                    setProfileApp(proc.info, proc.processName, profilerInfo);
22793                    mProfileProc = proc;
22794                    mProfileType = profileType;
22795                    ParcelFileDescriptor fd = profilerInfo.profileFd;
22796                    try {
22797                        fd = fd.dup();
22798                    } catch (IOException e) {
22799                        fd = null;
22800                    }
22801                    profilerInfo.profileFd = fd;
22802                    proc.thread.profilerControl(start, profilerInfo, profileType);
22803                    fd = null;
22804                    try {
22805                        mProfileFd.close();
22806                    } catch (IOException e) {
22807                    }
22808                    mProfileFd = null;
22809                } else {
22810                    stopProfilerLocked(proc, profileType);
22811                    if (profilerInfo != null && profilerInfo.profileFd != null) {
22812                        try {
22813                            profilerInfo.profileFd.close();
22814                        } catch (IOException e) {
22815                        }
22816                    }
22817                }
22818
22819                return true;
22820            }
22821        } catch (RemoteException e) {
22822            throw new IllegalStateException("Process disappeared");
22823        } finally {
22824            if (profilerInfo != null && profilerInfo.profileFd != null) {
22825                try {
22826                    profilerInfo.profileFd.close();
22827                } catch (IOException e) {
22828                }
22829            }
22830        }
22831    }
22832
22833    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
22834        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
22835                userId, true, ALLOW_FULL_ONLY, callName, null);
22836        ProcessRecord proc = null;
22837        try {
22838            int pid = Integer.parseInt(process);
22839            synchronized (mPidsSelfLocked) {
22840                proc = mPidsSelfLocked.get(pid);
22841            }
22842        } catch (NumberFormatException e) {
22843        }
22844
22845        if (proc == null) {
22846            ArrayMap<String, SparseArray<ProcessRecord>> all
22847                    = mProcessNames.getMap();
22848            SparseArray<ProcessRecord> procs = all.get(process);
22849            if (procs != null && procs.size() > 0) {
22850                proc = procs.valueAt(0);
22851                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
22852                    for (int i=1; i<procs.size(); i++) {
22853                        ProcessRecord thisProc = procs.valueAt(i);
22854                        if (thisProc.userId == userId) {
22855                            proc = thisProc;
22856                            break;
22857                        }
22858                    }
22859                }
22860            }
22861        }
22862
22863        return proc;
22864    }
22865
22866    public boolean dumpHeap(String process, int userId, boolean managed,
22867            String path, ParcelFileDescriptor fd) throws RemoteException {
22868
22869        try {
22870            synchronized (this) {
22871                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
22872                // its own permission (same as profileControl).
22873                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
22874                        != PackageManager.PERMISSION_GRANTED) {
22875                    throw new SecurityException("Requires permission "
22876                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
22877                }
22878
22879                if (fd == null) {
22880                    throw new IllegalArgumentException("null fd");
22881                }
22882
22883                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
22884                if (proc == null || proc.thread == null) {
22885                    throw new IllegalArgumentException("Unknown process: " + process);
22886                }
22887
22888                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
22889                if (!isDebuggable) {
22890                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22891                        throw new SecurityException("Process not debuggable: " + proc);
22892                    }
22893                }
22894
22895                proc.thread.dumpHeap(managed, path, fd);
22896                fd = null;
22897                return true;
22898            }
22899        } catch (RemoteException e) {
22900            throw new IllegalStateException("Process disappeared");
22901        } finally {
22902            if (fd != null) {
22903                try {
22904                    fd.close();
22905                } catch (IOException e) {
22906                }
22907            }
22908        }
22909    }
22910
22911    @Override
22912    public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
22913            String reportPackage) {
22914        if (processName != null) {
22915            enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
22916                    "setDumpHeapDebugLimit()");
22917        } else {
22918            synchronized (mPidsSelfLocked) {
22919                ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
22920                if (proc == null) {
22921                    throw new SecurityException("No process found for calling pid "
22922                            + Binder.getCallingPid());
22923                }
22924                if (!Build.IS_DEBUGGABLE
22925                        && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
22926                    throw new SecurityException("Not running a debuggable build");
22927                }
22928                processName = proc.processName;
22929                uid = proc.uid;
22930                if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
22931                    throw new SecurityException("Package " + reportPackage + " is not running in "
22932                            + proc);
22933                }
22934            }
22935        }
22936        synchronized (this) {
22937            if (maxMemSize > 0) {
22938                mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
22939            } else {
22940                if (uid != 0) {
22941                    mMemWatchProcesses.remove(processName, uid);
22942                } else {
22943                    mMemWatchProcesses.getMap().remove(processName);
22944                }
22945            }
22946        }
22947    }
22948
22949    @Override
22950    public void dumpHeapFinished(String path) {
22951        synchronized (this) {
22952            if (Binder.getCallingPid() != mMemWatchDumpPid) {
22953                Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
22954                        + " does not match last pid " + mMemWatchDumpPid);
22955                return;
22956            }
22957            if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
22958                Slog.w(TAG, "dumpHeapFinished: Calling path " + path
22959                        + " does not match last path " + mMemWatchDumpFile);
22960                return;
22961            }
22962            if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
22963            mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
22964        }
22965    }
22966
22967    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
22968    public void monitor() {
22969        synchronized (this) { }
22970    }
22971
22972    void onCoreSettingsChange(Bundle settings) {
22973        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
22974            ProcessRecord processRecord = mLruProcesses.get(i);
22975            try {
22976                if (processRecord.thread != null) {
22977                    processRecord.thread.setCoreSettings(settings);
22978                }
22979            } catch (RemoteException re) {
22980                /* ignore */
22981            }
22982        }
22983    }
22984
22985    // Multi-user methods
22986
22987    /**
22988     * Start user, if its not already running, but don't bring it to foreground.
22989     */
22990    @Override
22991    public boolean startUserInBackground(final int userId) {
22992        return mUserController.startUser(userId, /* foreground */ false);
22993    }
22994
22995    @Override
22996    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
22997        return mUserController.unlockUser(userId, token, secret, listener);
22998    }
22999
23000    @Override
23001    public boolean switchUser(final int targetUserId) {
23002        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23003        int currentUserId;
23004        UserInfo targetUserInfo;
23005        synchronized (this) {
23006            currentUserId = mUserController.getCurrentUserIdLocked();
23007            targetUserInfo = mUserController.getUserInfo(targetUserId);
23008            if (targetUserId == currentUserId) {
23009                Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23010                return true;
23011            }
23012            if (targetUserInfo == null) {
23013                Slog.w(TAG, "No user info for user #" + targetUserId);
23014                return false;
23015            }
23016            if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23017                Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23018                        + " when device is in demo mode");
23019                return false;
23020            }
23021            if (!targetUserInfo.supportsSwitchTo()) {
23022                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23023                return false;
23024            }
23025            if (targetUserInfo.isManagedProfile()) {
23026                Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23027                return false;
23028            }
23029            mUserController.setTargetUserIdLocked(targetUserId);
23030        }
23031        if (mUserController.mUserSwitchUiEnabled) {
23032            UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23033            Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23034            mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23035            mUiHandler.sendMessage(mHandler.obtainMessage(
23036                    START_USER_SWITCH_UI_MSG, userNames));
23037        } else {
23038            mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23039            mHandler.sendMessage(mHandler.obtainMessage(
23040                    START_USER_SWITCH_FG_MSG, targetUserId, 0));
23041        }
23042        return true;
23043    }
23044
23045    void scheduleStartProfilesLocked() {
23046        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23047            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23048                    DateUtils.SECOND_IN_MILLIS);
23049        }
23050    }
23051
23052    @Override
23053    public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23054        return mUserController.stopUser(userId, force, callback);
23055    }
23056
23057    @Override
23058    public UserInfo getCurrentUser() {
23059        return mUserController.getCurrentUser();
23060    }
23061
23062    String getStartedUserState(int userId) {
23063        synchronized (this) {
23064            final UserState userState = mUserController.getStartedUserStateLocked(userId);
23065            return UserState.stateToString(userState.state);
23066        }
23067    }
23068
23069    @Override
23070    public boolean isUserRunning(int userId, int flags) {
23071        if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23072                && checkCallingPermission(INTERACT_ACROSS_USERS)
23073                    != PackageManager.PERMISSION_GRANTED) {
23074            String msg = "Permission Denial: isUserRunning() from pid="
23075                    + Binder.getCallingPid()
23076                    + ", uid=" + Binder.getCallingUid()
23077                    + " requires " + INTERACT_ACROSS_USERS;
23078            Slog.w(TAG, msg);
23079            throw new SecurityException(msg);
23080        }
23081        synchronized (this) {
23082            return mUserController.isUserRunningLocked(userId, flags);
23083        }
23084    }
23085
23086    @Override
23087    public int[] getRunningUserIds() {
23088        if (checkCallingPermission(INTERACT_ACROSS_USERS)
23089                != PackageManager.PERMISSION_GRANTED) {
23090            String msg = "Permission Denial: isUserRunning() from pid="
23091                    + Binder.getCallingPid()
23092                    + ", uid=" + Binder.getCallingUid()
23093                    + " requires " + INTERACT_ACROSS_USERS;
23094            Slog.w(TAG, msg);
23095            throw new SecurityException(msg);
23096        }
23097        synchronized (this) {
23098            return mUserController.getStartedUserArrayLocked();
23099        }
23100    }
23101
23102    @Override
23103    public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23104        mUserController.registerUserSwitchObserver(observer, name);
23105    }
23106
23107    @Override
23108    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23109        mUserController.unregisterUserSwitchObserver(observer);
23110    }
23111
23112    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23113        if (info == null) return null;
23114        ApplicationInfo newInfo = new ApplicationInfo(info);
23115        newInfo.initForUser(userId);
23116        return newInfo;
23117    }
23118
23119    public boolean isUserStopped(int userId) {
23120        synchronized (this) {
23121            return mUserController.getStartedUserStateLocked(userId) == null;
23122        }
23123    }
23124
23125    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23126        if (aInfo == null
23127                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23128            return aInfo;
23129        }
23130
23131        ActivityInfo info = new ActivityInfo(aInfo);
23132        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23133        return info;
23134    }
23135
23136    private boolean processSanityChecksLocked(ProcessRecord process) {
23137        if (process == null || process.thread == null) {
23138            return false;
23139        }
23140
23141        boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23142        if (!isDebuggable) {
23143            if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23144                return false;
23145            }
23146        }
23147
23148        return true;
23149    }
23150
23151    public boolean startBinderTracking() throws RemoteException {
23152        synchronized (this) {
23153            mBinderTransactionTrackingEnabled = true;
23154            // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23155            // permission (same as profileControl).
23156            if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23157                    != PackageManager.PERMISSION_GRANTED) {
23158                throw new SecurityException("Requires permission "
23159                        + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23160            }
23161
23162            for (int i = 0; i < mLruProcesses.size(); i++) {
23163                ProcessRecord process = mLruProcesses.get(i);
23164                if (!processSanityChecksLocked(process)) {
23165                    continue;
23166                }
23167                try {
23168                    process.thread.startBinderTracking();
23169                } catch (RemoteException e) {
23170                    Log.v(TAG, "Process disappared");
23171                }
23172            }
23173            return true;
23174        }
23175    }
23176
23177    public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23178        try {
23179            synchronized (this) {
23180                mBinderTransactionTrackingEnabled = false;
23181                // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23182                // permission (same as profileControl).
23183                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23184                        != PackageManager.PERMISSION_GRANTED) {
23185                    throw new SecurityException("Requires permission "
23186                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23187                }
23188
23189                if (fd == null) {
23190                    throw new IllegalArgumentException("null fd");
23191                }
23192
23193                PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23194                pw.println("Binder transaction traces for all processes.\n");
23195                for (ProcessRecord process : mLruProcesses) {
23196                    if (!processSanityChecksLocked(process)) {
23197                        continue;
23198                    }
23199
23200                    pw.println("Traces for process: " + process.processName);
23201                    pw.flush();
23202                    try {
23203                        TransferPipe tp = new TransferPipe();
23204                        try {
23205                            process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23206                            tp.go(fd.getFileDescriptor());
23207                        } finally {
23208                            tp.kill();
23209                        }
23210                    } catch (IOException e) {
23211                        pw.println("Failure while dumping IPC traces from " + process +
23212                                ".  Exception: " + e);
23213                        pw.flush();
23214                    } catch (RemoteException e) {
23215                        pw.println("Got a RemoteException while dumping IPC traces from " +
23216                                process + ".  Exception: " + e);
23217                        pw.flush();
23218                    }
23219                }
23220                fd = null;
23221                return true;
23222            }
23223        } finally {
23224            if (fd != null) {
23225                try {
23226                    fd.close();
23227                } catch (IOException e) {
23228                }
23229            }
23230        }
23231    }
23232
23233    @VisibleForTesting
23234    final class LocalService extends ActivityManagerInternal {
23235        @Override
23236        public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23237                int targetUserId) {
23238            synchronized (ActivityManagerService.this) {
23239                ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23240                        targetPkg, intent, null, targetUserId);
23241            }
23242        }
23243
23244        @Override
23245        public String checkContentProviderAccess(String authority, int userId) {
23246            return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23247        }
23248
23249        @Override
23250        public void onWakefulnessChanged(int wakefulness) {
23251            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23252        }
23253
23254        @Override
23255        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23256                String processName, String abiOverride, int uid, Runnable crashHandler) {
23257            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23258                    processName, abiOverride, uid, crashHandler);
23259        }
23260
23261        @Override
23262        public SleepToken acquireSleepToken(String tag) {
23263            Preconditions.checkNotNull(tag);
23264
23265            synchronized (ActivityManagerService.this) {
23266                SleepTokenImpl token = new SleepTokenImpl(tag);
23267                mSleepTokens.add(token);
23268                updateSleepIfNeededLocked();
23269                return token;
23270            }
23271        }
23272
23273        @Override
23274        public ComponentName getHomeActivityForUser(int userId) {
23275            synchronized (ActivityManagerService.this) {
23276                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23277                return homeActivity == null ? null : homeActivity.realActivity;
23278            }
23279        }
23280
23281        @Override
23282        public void onUserRemoved(int userId) {
23283            synchronized (ActivityManagerService.this) {
23284                ActivityManagerService.this.onUserStoppedLocked(userId);
23285            }
23286        }
23287
23288        @Override
23289        public void onLocalVoiceInteractionStarted(IBinder activity,
23290                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23291            synchronized (ActivityManagerService.this) {
23292                ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23293                        voiceSession, voiceInteractor);
23294            }
23295        }
23296
23297        @Override
23298        public void notifyAppTransitionStarting(SparseIntArray reasons) {
23299            synchronized (ActivityManagerService.this) {
23300                mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reasons);
23301            }
23302        }
23303
23304        @Override
23305        public void notifyAppTransitionFinished() {
23306            synchronized (ActivityManagerService.this) {
23307                mStackSupervisor.notifyAppTransitionDone();
23308            }
23309        }
23310
23311        @Override
23312        public void notifyAppTransitionCancelled() {
23313            synchronized (ActivityManagerService.this) {
23314                mStackSupervisor.notifyAppTransitionDone();
23315            }
23316        }
23317
23318        @Override
23319        public List<IBinder> getTopVisibleActivities() {
23320            synchronized (ActivityManagerService.this) {
23321                return mStackSupervisor.getTopVisibleActivities();
23322            }
23323        }
23324
23325        @Override
23326        public void notifyDockedStackMinimizedChanged(boolean minimized) {
23327            synchronized (ActivityManagerService.this) {
23328                mStackSupervisor.setDockedStackMinimized(minimized);
23329            }
23330        }
23331
23332        @Override
23333        public void killForegroundAppsForUser(int userHandle) {
23334            synchronized (ActivityManagerService.this) {
23335                final ArrayList<ProcessRecord> procs = new ArrayList<>();
23336                final int NP = mProcessNames.getMap().size();
23337                for (int ip = 0; ip < NP; ip++) {
23338                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23339                    final int NA = apps.size();
23340                    for (int ia = 0; ia < NA; ia++) {
23341                        final ProcessRecord app = apps.valueAt(ia);
23342                        if (app.persistent) {
23343                            // We don't kill persistent processes.
23344                            continue;
23345                        }
23346                        if (app.removed) {
23347                            procs.add(app);
23348                        } else if (app.userId == userHandle && app.foregroundActivities) {
23349                            app.removed = true;
23350                            procs.add(app);
23351                        }
23352                    }
23353                }
23354
23355                final int N = procs.size();
23356                for (int i = 0; i < N; i++) {
23357                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
23358                }
23359            }
23360        }
23361
23362        @Override
23363        public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
23364            if (!(target instanceof PendingIntentRecord)) {
23365                Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
23366                return;
23367            }
23368            ((PendingIntentRecord) target).setWhitelistDuration(duration);
23369        }
23370
23371        @Override
23372        public void setDeviceIdleWhitelist(int[] appids) {
23373            synchronized (ActivityManagerService.this) {
23374                mDeviceIdleWhitelist = appids;
23375            }
23376        }
23377
23378        @Override
23379        public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
23380            synchronized (ActivityManagerService.this) {
23381                mDeviceIdleTempWhitelist = appids;
23382                setAppIdTempWhitelistStateLocked(changingAppId, adding);
23383            }
23384        }
23385
23386        @Override
23387        public void updatePersistentConfigurationForUser(@NonNull Configuration values,
23388                int userId) {
23389            Preconditions.checkNotNull(values, "Configuration must not be null");
23390            Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
23391            synchronized (ActivityManagerService.this) {
23392                updateConfigurationLocked(values, null, false, true, userId,
23393                        false /* deferResume */);
23394            }
23395        }
23396
23397        @Override
23398        public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
23399                Bundle bOptions) {
23400            Preconditions.checkNotNull(intents, "intents");
23401            final String[] resolvedTypes = new String[intents.length];
23402            for (int i = 0; i < intents.length; i++) {
23403                resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
23404            }
23405
23406            // UID of the package on user userId.
23407            // "= 0" is needed because otherwise catch(RemoteException) would make it look like
23408            // packageUid may not be initialized.
23409            int packageUid = 0;
23410            try {
23411                packageUid = AppGlobals.getPackageManager().getPackageUid(
23412                        packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
23413            } catch (RemoteException e) {
23414                // Shouldn't happen.
23415            }
23416
23417            synchronized (ActivityManagerService.this) {
23418                return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
23419                        /*resultTo*/ null, bOptions, userId);
23420            }
23421        }
23422
23423        @Override
23424        public int getUidProcessState(int uid) {
23425            return getUidState(uid);
23426        }
23427
23428        @Override
23429        public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
23430            synchronized (ActivityManagerService.this) {
23431
23432                // We might change the visibilities here, so prepare an empty app transition which
23433                // might be overridden later if we actually change visibilities.
23434                mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
23435                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23436                mWindowManager.executeAppTransition();
23437            }
23438            if (callback != null) {
23439                callback.run();
23440            }
23441        }
23442
23443        @Override
23444        public boolean isSystemReady() {
23445            // no need to synchronize(this) just to read & return the value
23446            return mSystemReady;
23447        }
23448
23449        @Override
23450        public void notifyKeyguardTrustedChanged() {
23451            synchronized (ActivityManagerService.this) {
23452                if (mKeyguardController.isKeyguardShowing()) {
23453                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
23454                }
23455            }
23456        }
23457
23458        /**
23459         * Sets if the given pid has an overlay UI or not.
23460         *
23461         * @param pid The pid we are setting overlay UI for.
23462         * @param hasOverlayUi True if the process has overlay UI.
23463         * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
23464         */
23465        @Override
23466        public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
23467            synchronized (ActivityManagerService.this) {
23468                final ProcessRecord pr;
23469                synchronized (mPidsSelfLocked) {
23470                    pr = mPidsSelfLocked.get(pid);
23471                    if (pr == null) {
23472                        Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
23473                        return;
23474                    }
23475                }
23476                if (pr.hasOverlayUi == hasOverlayUi) {
23477                    return;
23478                }
23479                pr.hasOverlayUi = hasOverlayUi;
23480                //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
23481                updateOomAdjLocked(pr);
23482            }
23483        }
23484
23485        /**
23486         * Called after the network policy rules are updated by
23487         * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
23488         * and {@param procStateSeq}.
23489         */
23490        @Override
23491        public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
23492            if (DEBUG_NETWORK) {
23493                Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
23494                        + uid + " seq: " + procStateSeq);
23495            }
23496            UidRecord record;
23497            synchronized (ActivityManagerService.this) {
23498                record = mActiveUids.get(uid);
23499                if (record == null) {
23500                    if (DEBUG_NETWORK) {
23501                        Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
23502                                + " procStateSeq: " + procStateSeq);
23503                    }
23504                    return;
23505                }
23506            }
23507            synchronized (record.lock) {
23508                if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23509                    if (DEBUG_NETWORK) {
23510                        Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
23511                                + " been handled for uid: " + uid);
23512                    }
23513                    return;
23514                }
23515                record.lastNetworkUpdatedProcStateSeq = procStateSeq;
23516                if (record.curProcStateSeq > procStateSeq) {
23517                    if (DEBUG_NETWORK) {
23518                        Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
23519                                + ", curProcstateSeq: " + record.curProcStateSeq
23520                                + ", procStateSeq: " + procStateSeq);
23521                    }
23522                    return;
23523                }
23524                if (record.waitingForNetwork) {
23525                    if (DEBUG_NETWORK) {
23526                        Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
23527                                + ", procStateSeq: " + procStateSeq);
23528                    }
23529                    record.lock.notifyAll();
23530                }
23531            }
23532        }
23533
23534        /**
23535         * Called after virtual display Id is updated by
23536         * {@link com.android.server.vr.CompatibilityDisplay} with a specific
23537         * {@param vrCompatibilityDisplayId}.
23538         */
23539        @Override
23540        public void setVrCompatibilityDisplayId(int vrCompatibilityDisplayId) {
23541            if (DEBUG_STACK) {
23542                Slog.d(TAG, "setVrCompatibilityDisplayId called for: " +
23543                        vrCompatibilityDisplayId);
23544            }
23545            synchronized (ActivityManagerService.this) {
23546                mVrCompatibilityDisplayId = vrCompatibilityDisplayId;
23547            }
23548        }
23549    }
23550
23551    /**
23552     * Called by app main thread to wait for the network policy rules to get udpated.
23553     *
23554     * @param procStateSeq The sequence number indicating the process state change that the main
23555     *                     thread is interested in.
23556     */
23557    @Override
23558    public void waitForNetworkStateUpdate(long procStateSeq) {
23559        final int callingUid = Binder.getCallingUid();
23560        if (DEBUG_NETWORK) {
23561            Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
23562        }
23563        UidRecord record;
23564        synchronized (this) {
23565            record = mActiveUids.get(callingUid);
23566            if (record == null) {
23567                return;
23568            }
23569        }
23570        synchronized (record.lock) {
23571            if (record.lastDispatchedProcStateSeq < procStateSeq) {
23572                if (DEBUG_NETWORK) {
23573                    Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
23574                            + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
23575                            + " lastProcStateSeqDispatchedToObservers: "
23576                            + record.lastDispatchedProcStateSeq);
23577                }
23578                return;
23579            }
23580            if (record.curProcStateSeq > procStateSeq) {
23581                if (DEBUG_NETWORK) {
23582                    Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
23583                            + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
23584                            + ", procStateSeq: " + procStateSeq);
23585                }
23586                return;
23587            }
23588            if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
23589                if (DEBUG_NETWORK) {
23590                    Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
23591                            + procStateSeq + ", so no need to wait. Uid: "
23592                            + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
23593                            + record.lastNetworkUpdatedProcStateSeq);
23594                }
23595                return;
23596            }
23597            try {
23598                if (DEBUG_NETWORK) {
23599                    Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
23600                        + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
23601                }
23602                final long startTime = SystemClock.uptimeMillis();
23603                record.waitingForNetwork = true;
23604                record.lock.wait(mWaitForNetworkTimeoutMs);
23605                record.waitingForNetwork = false;
23606                final long totalTime = SystemClock.uptimeMillis() - startTime;
23607                if (totalTime >= mWaitForNetworkTimeoutMs) {
23608                    Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
23609                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
23610                            + procStateSeq);
23611                } else if (DEBUG_NETWORK ||  totalTime >= mWaitForNetworkTimeoutMs / 2) {
23612                    Slog.d(TAG_NETWORK, "Total time waited for network rules to get updated: "
23613                            + totalTime + ". Uid: " + callingUid + " procStateSeq: "
23614                            + procStateSeq);
23615                }
23616            } catch (InterruptedException e) {
23617                Thread.currentThread().interrupt();
23618            }
23619        }
23620    }
23621
23622    private final class SleepTokenImpl extends SleepToken {
23623        private final String mTag;
23624        private final long mAcquireTime;
23625
23626        public SleepTokenImpl(String tag) {
23627            mTag = tag;
23628            mAcquireTime = SystemClock.uptimeMillis();
23629        }
23630
23631        @Override
23632        public void release() {
23633            synchronized (ActivityManagerService.this) {
23634                if (mSleepTokens.remove(this)) {
23635                    updateSleepIfNeededLocked();
23636                }
23637            }
23638        }
23639
23640        @Override
23641        public String toString() {
23642            return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
23643        }
23644    }
23645
23646    /**
23647     * An implementation of IAppTask, that allows an app to manage its own tasks via
23648     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
23649     * only the process that calls getAppTasks() can call the AppTask methods.
23650     */
23651    class AppTaskImpl extends IAppTask.Stub {
23652        private int mTaskId;
23653        private int mCallingUid;
23654
23655        public AppTaskImpl(int taskId, int callingUid) {
23656            mTaskId = taskId;
23657            mCallingUid = callingUid;
23658        }
23659
23660        private void checkCaller() {
23661            if (mCallingUid != Binder.getCallingUid()) {
23662                throw new SecurityException("Caller " + mCallingUid
23663                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
23664            }
23665        }
23666
23667        @Override
23668        public void finishAndRemoveTask() {
23669            checkCaller();
23670
23671            synchronized (ActivityManagerService.this) {
23672                long origId = Binder.clearCallingIdentity();
23673                try {
23674                    // We remove the task from recents to preserve backwards
23675                    if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
23676                            REMOVE_FROM_RECENTS)) {
23677                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23678                    }
23679                } finally {
23680                    Binder.restoreCallingIdentity(origId);
23681                }
23682            }
23683        }
23684
23685        @Override
23686        public ActivityManager.RecentTaskInfo getTaskInfo() {
23687            checkCaller();
23688
23689            synchronized (ActivityManagerService.this) {
23690                long origId = Binder.clearCallingIdentity();
23691                try {
23692                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23693                    if (tr == null) {
23694                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23695                    }
23696                    return createRecentTaskInfoFromTaskRecord(tr);
23697                } finally {
23698                    Binder.restoreCallingIdentity(origId);
23699                }
23700            }
23701        }
23702
23703        @Override
23704        public void moveToFront() {
23705            checkCaller();
23706            // Will bring task to front if it already has a root activity.
23707            final long origId = Binder.clearCallingIdentity();
23708            try {
23709                synchronized (this) {
23710                    mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
23711                }
23712            } finally {
23713                Binder.restoreCallingIdentity(origId);
23714            }
23715        }
23716
23717        @Override
23718        public int startActivity(IBinder whoThread, String callingPackage,
23719                Intent intent, String resolvedType, Bundle bOptions) {
23720            checkCaller();
23721
23722            int callingUser = UserHandle.getCallingUserId();
23723            TaskRecord tr;
23724            IApplicationThread appThread;
23725            synchronized (ActivityManagerService.this) {
23726                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23727                if (tr == null) {
23728                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23729                }
23730                appThread = IApplicationThread.Stub.asInterface(whoThread);
23731                if (appThread == null) {
23732                    throw new IllegalArgumentException("Bad app thread " + appThread);
23733                }
23734            }
23735            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
23736                    resolvedType, null, null, null, null, 0, 0, null, null,
23737                    null, bOptions, false, callingUser, null, tr);
23738        }
23739
23740        @Override
23741        public void setExcludeFromRecents(boolean exclude) {
23742            checkCaller();
23743
23744            synchronized (ActivityManagerService.this) {
23745                long origId = Binder.clearCallingIdentity();
23746                try {
23747                    TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
23748                    if (tr == null) {
23749                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
23750                    }
23751                    Intent intent = tr.getBaseIntent();
23752                    if (exclude) {
23753                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23754                    } else {
23755                        intent.setFlags(intent.getFlags()
23756                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
23757                    }
23758                } finally {
23759                    Binder.restoreCallingIdentity(origId);
23760                }
23761            }
23762        }
23763    }
23764
23765    /**
23766     * Kill processes for the user with id userId and that depend on the package named packageName
23767     */
23768    @Override
23769    public void killPackageDependents(String packageName, int userId) {
23770        enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
23771        if (packageName == null) {
23772            throw new NullPointerException(
23773                    "Cannot kill the dependents of a package without its name.");
23774        }
23775
23776        long callingId = Binder.clearCallingIdentity();
23777        IPackageManager pm = AppGlobals.getPackageManager();
23778        int pkgUid = -1;
23779        try {
23780            pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
23781        } catch (RemoteException e) {
23782        }
23783        if (userId != UserHandle.USER_ALL && pkgUid == -1) {
23784            throw new IllegalArgumentException(
23785                    "Cannot kill dependents of non-existing package " + packageName);
23786        }
23787        try {
23788            synchronized(this) {
23789                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
23790                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
23791                        "dep: " + packageName);
23792            }
23793        } finally {
23794            Binder.restoreCallingIdentity(callingId);
23795        }
23796    }
23797
23798    @Override
23799    public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
23800        final int userId = intent.getCreatorUserHandle().getIdentifier();
23801        if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
23802            return false;
23803        }
23804        IIntentSender target = intent.getTarget();
23805        if (!(target instanceof PendingIntentRecord)) {
23806            return false;
23807        }
23808        final PendingIntentRecord record = (PendingIntentRecord) target;
23809        final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
23810                record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
23811        // For direct boot aware activities, they can be shown without triggering a work challenge
23812        // before the profile user is unlocked.
23813        return rInfo != null && rInfo.activityInfo != null;
23814    }
23815
23816    @Override
23817    public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
23818            throws RemoteException {
23819        final long callingId = Binder.clearCallingIdentity();
23820        try {
23821            mKeyguardController.dismissKeyguard(token, callback);
23822        } finally {
23823            Binder.restoreCallingIdentity(callingId);
23824        }
23825    }
23826
23827    @Override
23828    public int restartUserInBackground(final int userId) {
23829        return mUserController.restartUser(userId, /* foreground */ false);
23830    }
23831
23832    @Override
23833    public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
23834        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
23835                "scheduleApplicationInfoChanged()");
23836
23837        synchronized (this) {
23838            final long origId = Binder.clearCallingIdentity();
23839            try {
23840                updateApplicationInfoLocked(packageNames, userId);
23841            } finally {
23842                Binder.restoreCallingIdentity(origId);
23843            }
23844        }
23845    }
23846
23847    void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
23848        final PackageManagerInternal packageManager = getPackageManagerInternalLocked();
23849        final boolean updateFrameworkRes = packagesToUpdate.contains("android");
23850        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23851            final ProcessRecord app = mLruProcesses.get(i);
23852            if (app.thread == null || app.pid == Process.myPid()) {
23853                continue;
23854            }
23855
23856            if (userId != UserHandle.USER_ALL && app.userId != userId) {
23857                continue;
23858            }
23859
23860            final int packageCount = app.pkgList.size();
23861            for (int j = 0; j < packageCount; j++) {
23862                final String packageName = app.pkgList.keyAt(j);
23863                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
23864                    try {
23865                        final ApplicationInfo ai = packageManager.getApplicationInfo(
23866                                packageName, app.userId);
23867                        if (ai != null) {
23868                            app.thread.scheduleApplicationInfoChanged(ai);
23869                        }
23870                    } catch (RemoteException e) {
23871                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
23872                                    packageName, app));
23873                    }
23874                }
23875            }
23876        }
23877    }
23878
23879    /**
23880     * Attach an agent to the specified process (proces name or PID)
23881     */
23882    public void attachAgent(String process, String path) {
23883        try {
23884            synchronized (this) {
23885                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
23886                if (proc == null || proc.thread == null) {
23887                    throw new IllegalArgumentException("Unknown process: " + process);
23888                }
23889
23890                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23891                if (!isDebuggable) {
23892                    if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23893                        throw new SecurityException("Process not debuggable: " + proc);
23894                    }
23895                }
23896
23897                proc.thread.attachAgent(path);
23898            }
23899        } catch (RemoteException e) {
23900            throw new IllegalStateException("Process disappeared");
23901        }
23902    }
23903
23904    @VisibleForTesting
23905    public static class Injector {
23906        private NetworkManagementInternal mNmi;
23907
23908        public Context getContext() {
23909            return null;
23910        }
23911
23912        public AppOpsService getAppOpsService(File file, Handler handler) {
23913            return new AppOpsService(file, handler);
23914        }
23915
23916        public Handler getUiHandler(ActivityManagerService service) {
23917            return service.new UiHandler();
23918        }
23919
23920        public boolean isNetworkRestrictedForUid(int uid) {
23921            if (ensureHasNetworkManagementInternal()) {
23922                return mNmi.isNetworkRestrictedForUid(uid);
23923            }
23924            return false;
23925        }
23926
23927        private boolean ensureHasNetworkManagementInternal() {
23928            if (mNmi == null) {
23929                mNmi = LocalServices.getService(NetworkManagementInternal.class);
23930            }
23931            return mNmi != null;
23932        }
23933    }
23934}
23935